• 【IO】文件操作基础知识


    目录

    1.文件的操作:

    2.文件内容的读写—数据流:

    3.文件操作练习:


    1.文件的操作:

    1. 文件分为狭义上的文件和广义的文件。
    2. 狭义上的文件:存储在硬盘上的数据,以“文件”为单位进行组织。文件夹也叫做目录。
    3. 通过“路径”的概念来描述一个文件在电脑上的具体位置。路径分为绝对路径(每个 / 间隔的部分都是目录)和相对路径(需要有基准)。
    4. 相对路径中 ./表示当前目录(./qq/Bin/QQ.exe);使用 ../ 表示返回到上级目录
    5. I(input)O(output),输入和输出的方向是以CPU/内存为中心。输入就是将外部设备(键盘)的数据放到内存里。
    6. File类;注意:有File对象不代表有真实存在该对象。File类的构造方法常用File(路径),这里的路径可以是绝对路径还可以是相对路径。一个file对象就是一个文件或目录。
      File file = new File("..//helloworld.txt");//并不要求该文件真实存在
      返回值类型方法签名说明
      StringgetName()返回File对象纯文件名称
      booleanisDirectory()判断是不是目录
      booleanisFile()判断是不是普通文件
      booleancreateNewFile()创建文件,成功后返回true
      booleandelete()删除该文件,成功后返回true
      voiddeleteOnExit()进程退出时才会删除文件
      booleanmkdir()创建目录
      booleanmkdirs()创建多级目录
      booleanrenameTo()重命名

    2.文件内容的读写—数据流:

    1. 读操作:InputStream;从外部设备读取到内存上。
      //InputStream是一个抽象类,不具体,不能实例化,所以需要用到FileInputStream
      //下面这个过程就相当于打开文件!想要读写文件就需要打开文件~
      InputStream inputStream = new FileInputStream("hello.txt");
      返回值类型方法签名说明
      intread()读取一个字节的数据,返回-1代表读完了
      intread(byte[ ] b)读取b.length字节数据放到b中,返回读到的数量,-1代表已经读完了
      intread(byte[ ] b, int m, int n)读取n-m个字节到b中
      voidclose()关闭字节流
      1. //1.读操作:无
      2. public static void main(String[] args) throws IOException {
      3. InputStream inputStream = new FileInputStream("hello.txt");
      4. while(true){
      5. int ret = inputStream.read();
      6. if(ret == -1){
      7. break;
      8. }
      9. System.out.println(ret);
      10. }
      11. inputStream.close();
      12. }
      13. //2.读操作:使用Scanner来读数据
      14. public static void main(String[] args) throws IOException {
      15. InputStream inputStream = new FileInputStream("./hello.txt");
      16. //scanner搭配inputStream使用,读操作
      17. Scanner scanner = new Scanner(inputStream);
      18. while(scanner.hasNext()){
      19. System.out.println(scanner.next());
      20. }
      21. inputStream.close();
      22. }
      23. //3.读操作:使用byte数组
      24. public static void main(String[] args) throws IOException {
      25. try(InputStream inputStream = new FileInputStream("hello.txt")){
      26. byte[] ret = new byte[1024];
      27. int len = 0;
      28. while(true){
      29. len = inputStream.read(ret);
      30. if(len == -1){
      31. break;
      32. }
      33. for (int i = 0; i < len; i++) {
      34. System.out.println(ret[i]);
      35. }
      36. }
      37. }
      38. }
      39. //4.读操作:使用try和scanner
      40. public static void main(String[] args) throws IOException {
      41. try(InputStream inputStream = new FileInputStream("./hello.txt");
      42. Scanner scanner = new Scanner(inputStream)){
      43. while(scanner.hasNext()){
      44. String ret = scanner.next();
      45. System.out.println(ret);
      46. }
      47. }
      48. }
    2. 写:OutputStream;
      //OutputStream是一个抽象类,不具体,不能实例化,所以需要用到FileOutputStream
      //使用OutputStream写文件的时候,只要文件打开成功,就会把文件原来的内容清空
      OutputStream outputStream = new FileOutrputStream("./hello.txt");
      返回值类型方法签名说明
      voidwrite(int b)写入一个字符将b这个字符数组中的数据全部写入
      voidwrite(byte[ ] b)将b这个字符数组中的数据全部写入
      intwrite(byte[ ] b, int m, int n)将b这个字符数组中的数据从m开始写入
      voidclose()关闭字节流
      voidflush()刷新缓冲区
      1. //1.写操作
      2. public static void main(String[] args) throws IOException {
      3. OutputStream outputStream = new FileOutputStream("./hello.txt");
      4. //打开文件后,会先把文件内容清空
      5. outputStream.write(97);
      6. outputStream.write(98);
      7. outputStream.write(99);
      8. outputStream.close();
      9. }
      10. //2.写操作:使用PrintWriter来写操作
      11. public static void main(String[] args) throws IOException {
      12. OutputStream outputStream = new FileOutputStream("./hello.txt");
      13. PrintWriter writer = new PrintWriter(outputStream);
      14. writer.print(45);
      15. writer.print('c');
      16. writer.println();
      17. //一定要刷新缓冲区
      18. outputStream.flush();
      19. //一定要关闭文件,writer.close()!!!
      20. writer.close();
      21. }
      22. //3.写操作:使用try和PrintWriter来写操作
      23. public static void main(String[] args) throws IOException {
      24. try(OutputStream outputStream = new FileOutputStream("./hello.txt");
      25. PrintWriter writer = new PrintWriter(outputStream)){
      26. writer.println();
      27. writer.print('s');
      28. writer.flush();
      29. }
      30. }
      31. //4.写操作:使用OutputStreamWriter和PrintWriter来写
      32. public static void main(String[] args) throws IOException {
      33. try(OutputStream outputStream = new FileOutputStream("./hello.txt");
      34. OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
      35. PrintWriter printWriter = new PrintWriter(outputStreamWriter)){
      36. printWriter.println();
      37. printWriter.print(1);
      38. printWriter.print(12);
      39. printWriter.print(13);
      40. printWriter.flush();
      41. }
      42. }
    3. 刷新缓冲区:OutputStream为了减少设备操作的次数,写数据时会将数据暂时写入缓冲区中,直到满足条件才写到内存上。因此为了保证数据不会遗留在缓冲区上,我们需要用到刷新缓存区flash()的操作来将数据刷到设备上。 

    4. 文件内容操作后一定要将文件close,否则会造成文件资源泄露,类比于图书馆借书(一伙人直只借不还,图书馆的书不就越来越少了嘛~)。

      为什么需要close文件???
      1.每个进程都对应着PCB,PCB里面有一个字段,文件描述符表
      2.同一个进程里面多个PCB可能同时使用一份文件描述符表
      3.文件描述符表相当于一个数组,每次打开一个文件,都会在表里创建一个项
      4.如果关闭则会把对应的项给释放掉
      5.如果不关闭,意味着这个项一直占着位置,
      6.如果持续打开文件且从来不关就会导致表项(数组里的元素)被耗尽
      7.导致后续文件在打开文件就会打开失败
      8.所以需要保证代码执行完关闭文件

    3.文件操作练习:

    1.扫描指定目录,并找到名称中包含指定字符的所有普通文件(不包含目录),并且后续询问用户是否要删除该文件 

    思路:

    1.先让用户输入要扫描的路径和要查找的字
    2.遍历目录,找到名字包含的的文件
    3.询问用户是否删除

    代码:

    1. //扫描目录,找到包含指定字符的所有普通文件,找到后询问是否要删除
    2. public class Demo {
    3. public static void main(String[] args) throws IOException {
    4. //1.让用户输入必要的信息
    5. Scanner scanner = new Scanner(System.in);
    6. System.out.println("请输入要扫描的路径:");
    7. File rootDir = new File(scanner.next());
    8. if(!rootDir.isFile()){
    9. System.out.println("输入的目录有错误!!!");
    10. return;
    11. }
    12. System.out.println("请输入要查找的关键字:");
    13. String toDelete = scanner.next();
    14. //2.遍历目录
    15. scanDir(rootDir,toDelete);
    16. }
    17. private static void scanDir(File rootDir, String toDelete) throws IOException {
    18. System.out.println("当前访问: "+rootDir.getCanonicalPath());
    19. File[] files = rootDir.listFiles();
    20. if(files == null){
    21. //说明目录是个空的目录
    22. return;
    23. }
    24. for (File f : files) {
    25. if(f.isDirectory()){
    26. scanDir(f,toDelete);
    27. }else{
    28. checkDelete(f,toDelete);
    29. }
    30. }
    31. }
    32. private static void checkDelete(File f, String toDelete) throws IOException {
    33. if(f.getName().contains(toDelete)){
    34. System.out.println("该单词"+toDelete+" 被 "+f.getCanonicalPath()+"包含了,是否要删除?(Y/N)" );
    35. Scanner scanner = new Scanner(System.in);
    36. String choice = scanner.next();
    37. if(choice.equals("Y") || choice.equals("y")){
    38. f.delete();
    39. }
    40. }
    41. }
    42. }

    2.将普通的文件复制一份

    思路:

    把第一个文件打开,将里面的内容逐个字节的读取出来,写入到第二个文件中

    代码:

    1. //普通文件的复制
    2. public class Demo {
    3. public static void main(String[] args) throws IOException {
    4. //1.输入
    5. Scanner scanner = new Scanner(System.in);
    6. System.out.println("请输入要复制的源文件:");
    7. File srcFile = new File(scanner.next());
    8. System.out.println("请输入目标文件:");
    9. File destFile = new File(scanner.next());
    10. if(!srcFile.isFile()){
    11. System.out.println("输入的源文件有错误!!!");
    12. return;
    13. }
    14. if(!destFile.getParentFile().isDirectory()){
    15. System.out.println("输入的目标文件有误!!!");
    16. return;
    17. }
    18. //2.打开目标文件,按照字节读取写入到目标文件中
    19. try(InputStream inputStream = new FileInputStream(srcFile);
    20. OutputStream outputStream = new FileOutputStream(destFile)){
    21. while(true){
    22. int ret = inputStream.read();
    23. if(ret == -1){
    24. break;
    25. }
    26. outputStream.write(ret);
    27. }
    28. }
    29. }
    30. }

    3.扫描指定目录,并找到名称或者内容中包含指定字符的所有普通文件(不包含目录)

    思路:

    1.先让用户输入要扫描的路径和要查找的字
    2.遍历目录,找到名字和内容都包含的文件
    3.询问用户是否删除

    代码:

    1. //扫描文件,判断其中是否包含关键字
    2. public class Demo {
    3. public static void main(String[] args) throws IOException {
    4. Scanner scanner = new Scanner(System.in);
    5. System.out.println("请输入要扫描的路径:");
    6. File rootDir = new File(scanner.next());
    7. if(!rootDir.isFile()){
    8. System.out.println("输入的路径有问题!");
    9. return;
    10. }
    11. System.out.println("请输入要搜索的关键字:");
    12. String toFind = scanner.next();
    13. //2.遍历
    14. scanDir(rootDir,toFind);
    15. }
    16. private static void scanDir(File rootDir, String toFind) throws IOException {
    17. System.out.println("当前路径:"+rootDir.getCanonicalPath());
    18. File[] files = rootDir.listFiles();
    19. if(files == null){
    20. return;
    21. }
    22. for(File f : files){
    23. if(f.isDirectory()){
    24. scanDir(f,toFind);
    25. }else{
    26. checkDelete(f,toFind);
    27. }
    28. }
    29. }
    30. private static void checkDelete(File f, String toFind) throws IOException {
    31. //先检查文件名
    32. if(f.getName().contains(toFind)){
    33. System.out.println(f.getCanonicalPath() + "文件名中包含 " + toFind+" 是否删除(Y/N)");
    34. }
    35. try(InputStream inputStream = new FileInputStream(f)){
    36. StringBuilder sb = new StringBuilder();
    37. Scanner scanner = new Scanner(inputStream);
    38. while(scanner.hasNextLine()){
    39. sb.append(scanner.nextLine() + "\n");
    40. }
    41. if(sb.indexOf(toFind) > -1){
    42. System.out.println(f.getCanonicalPath() + "文件内容中包含 " + toFind+" 是否删除(Y/N)");
    43. }
    44. }
    45. }
    46. }

    如果对您有帮助的话,

    不要忘记点赞+关注哦,蟹蟹

    如果对您有帮助的话,

    不要忘记点赞+关注哦,蟹蟹

    如果对您有帮助的话,

    不要忘记点赞+关注哦,蟹蟹

  • 相关阅读:
    Matlab实现异构交通流
    渲染如何做到超强渲染?MAX插件CG MAGIC中的渲染功能!
    u盘刻录系统安装盘
    本科毕业论文研究结果与预期不符怎么办?
    pycharm连接MySql数据库,新建表creat table、删除表drop table、查询表select、插入数据insert
    Selenium实现批量将CSDN文章改为【粉丝可见】
    K8s持久化存储
    Seata AT模式源码解析一(Seata Server端启动流程)
    ruby ftp封装实例详解
    【C++ Primer Plus】第11章 使用类
  • 原文地址:https://blog.csdn.net/qq_68993495/article/details/127544584