文件操作---IO

文章目录

  • 什么是文件?
  • 文件的路径
  • 文件的系统操作
  • 文件的内容操作
    • 面向字节流
      • 面向字节流的读操作(InputStream)
      • 面向字节流的写操作(OutputStream)
    • 面向字符流
      • 面向字符流的读操作(Reader)
      • 面向字符流的写操作(Writer)
    • 将字节流操作改造成字符流操作
      • 让InputStream可以读字符流(Scanner)
      • 让OutputStream可以写字符流(PrintWrite)

什么是文件?

  • 狭义的文件:存储在硬盘上的数据,以“文件”为单位,进行组织。比如:
    文件操作---IO_第1张图片

  • 广义的文件:操作系统是用来管理软硬件资源的,操作系统往往把这些资源都统一的抽象成“文件”来进行管理。即“一切皆文件”。

    比如:有一个键盘,从键盘读取数据就是读文件;将信息显示在屏幕上就是写文件

文件的路径

文件在电脑中是以“目录结构”的形式存储的,这个“目录结构”其实是一个N叉树。那么我们怎样找到一个具体的文件地址呢?就通过“路径”的概念,来描述一个文件在你电脑上的具体位置。路径又分为两类:绝对路径和相对路径。

  • 绝对路径:

    在这里插入图片描述
    像这样的、完整的路径就是绝对路径。它从盘符开始一直指向你要找的文件。
    通过’\'来分割每一级目录

  • 相对路径:

    首先得先有一个“基准路径”,也叫“工作路径”。
    相对路径就是以基准路径为起点,一直指向你要找的文件。

    如果基准路径是D,则相对路径是 .\program\qq\Bin\qq.exe 通过 '.‘表示当前目录
    如果基准路径是D:\program\qq\Bin,则相对路径是 .\qq.exe
    如果基准路径是D:\program\WeChat,则相对路径是 …\qq\Bin\qq.exe 通过’…'表示返回上级目录

文件的系统操作

文件操作是属于操作系统层面提供的一些API,不同的操作系统提供的API不同。但是Java作为一个跨平台的语言,就在JVM中把这些不同的API进行了封装。我们就可以直接使用库中的类来进行操作了。

我们使用File类来进行文件操作,它里面有一些方法需要我们学习:

  1. 获取文件的基本属性
        //写法一:后三个看起来一样
        File file = new File("D:/test.txt");
        
        //获取父目录文件路径
        System.out.println(file.getParent());            //D:/
        //获取文件名
        System.out.println(file.getName());				//test.txt
        //获取文件路径
        System.out.println(file.getPath());				//D:/test.txt
        //获取文件的绝对路径
        System.out.println(file.getAbsolutePath());		//D:/test.txt
        //获取修饰过的绝对路径
        System.out.println(file.getCanonicalPath());	//D:/test.txt
		//写法二:后三个不一样
        File file = new File("./test.txt");
        
        //获取父目录文件路径
        System.out.println(file.getParent());            //.
        //获取文件名
        System.out.println(file.getName());				//test.txt
        //获取文件路径
        System.out.println(file.getPath());				//./test.txt
        //获取文件的绝对路径
        System.out.println(file.getAbsolutePath());		//D:\Code\Java-Code\java-code\2023-10-31\.\test.txt
        //获取修饰过的绝对路径
        System.out.println(file.getCanonicalPath());	//D:\Code\Java-Code\java-code\2023-10-31\test.txt
  1. 判断文件的状态
		File file = new File("./test.txt");
        //判断文件是否存在
        System.out.println(file.exists());			//false
        //判断文件是否是目录
        System.out.println(file.isDirectory());		//false
        //判断文件是否是普通文件
        System.out.println(file.isFile());			//false
        
        file.createNewFile();
        System.out.println(file.exists());			//true
        System.out.println(file.isDirectory());		//false
        System.out.println(file.isFile());			//true
  1. 文件重命名
        //重命名
        //前提:srcFile必须存在  destFile必须不存在
        File srcFile = new File("./aaa.txt");
        File destFile = new File("./bbb.txt");
        
        System.out.println(srcFile.getName());			//aaa.txt

        srcFile.renameTo(destFile);
        System.out.println(srcFile.getName());			//bbb.txt
  1. 创建目录
        //创建目录
        File file = new File("./testDir");
        file.mkdir();
        

        //创建多级目录
        File file = new File("./testDir/aaa/bbb");
        file.mkdirs();

  1. 文件/目录删除
		//文件删除
		file.delete();

		//在删除目录时,1.创建完多层目录后默认停留在最后一层
					  2.要指定每一级目录然后逐级删除
  1. 得到文件夹下的所有目录名
        //得到文件夹下的所有目录名
        File file = new File("./dir/aaa/bbb");
        file.mkdirs();  // 创建完目录之后  file会自动指向到最低级的目录

        File file1 = new File("./dir");

		//返回值是一个字符串数组
        String[] results = file1.list();
        System.out.println(Arrays.toString(results));
  1. 得到文件夹下的所有文件
        //得到文件夹下的所有文件
        File file = new File("./dir/ccc.txt");
        File file1 = new File("./dir/ddd.txt");
        file.createNewFile();
        file1.createNewFile();

        File file2 = new File("./dir");

		//返回值是一个文件数组
        File[] results = file2.listFiles();
        for (File file3 : results){
            System.out.println(file3.getName());
        }

文件的内容操作

我们通过“流”来进行文件的读写操作。就像“水流“一样,需要使用时打开”流入“,使用中一直在”流“,使用完成后关闭。Java标准库就在”流“的概念上,提供了一组类用来完成读写文件的操作!

我们首先要明白的就是:输入和输出是对于CPU而言的。
将数据送到CPU中执行,就是输入;把运算好的结果从CPU拿走,就是输出。
文件操作---IO_第2张图片

面向字节流

面向字节流的读操作(InputStream)

文件操作---IO_第3张图片

        //读文件操作
        File file = new File("./aaa.txt");
        file.createNewFile();

        InputStream inputStream = new FileInputStream("./aaa.txt");

        while (true){
            int a = inputStream.read();
            //读到文件末尾时  返回-1
            if (a == -1){
                break;
            }
            System.out.println(a);
        }
        inputStream.close();

面向字节流的写操作(OutputStream)

文件操作---IO_第4张图片

        //写文件操作
        //使用OutputStream进行写文件操作的时候   只要文件打开了,文件原有内容就会清空
        //操作的是字节  可以直接传数字或者字符   不能传字符串----》 传字节数组
        OutputStream outputStream = new FileOutputStream("./aaa.txt");

        outputStream.write(97);
        outputStream.write(98);
        outputStream.write(99);

        outputStream.close();

面向字符流

面向字符流的读操作(Reader)

使用的方法和InputStream一样。

        //按字符进行读
        Reader reader = new FileReader("./aaa.txt");
        while (true){
            int ret = reader.read();
            if (ret == -1){
                break;
            }
            char ch = (char)ret;
            System.out.println(ch);
        }
        reader.close();

面向字符流的写操作(Writer)

使用的方法和OutputStream一样。

        //按字符进行写
        Writer writer = new FileWriter("./aaa.txt");
        writer.write("hello world");
        writer.close();

将字节流操作改造成字符流操作

让InputStream可以读字符流(Scanner)

        //使用InputStream读取字符流   借助Scanner
        InputStream inputStream = new FileInputStream("./aaa.txt");
        Scanner scanner = new Scanner(inputStream,"UTF-8");
        while (scanner.hasNext()){
            String s = scanner.next();
            System.out.println(s);
        }
        inputStream.close();

让OutputStream可以写字符流(PrintWrite)

        //使用OutputStream写入字符流   借助PrintWrite
        OutputStream outputStream = new FileOutputStream("./aaa.txt");
        PrintWriter printWriter = new PrintWriter(outputStream);
        printWriter.print("hello");
        printWriter.print("你好");
        printWriter.flush();
        outputStream.close();

注:

  1. 进行文件读写的时候一定要记得调用close()方法,释放资源。因为:
    每个进程都对应着PCB(可能有多个),PCB里有文件描述符表,这些PCB都共用一个文件描述符表。文件描述符表是一个顺序表,是有长度上限的。每次打开一个文件,就会在表里创建一项;关闭一个文件,就销毁对应的那一项。当不关闭文件时,文件描述符表的资源就会被占满,下次就无法打开新的文件,是个大问题。
  2. 如果close()方法前出现了异常,那么可能就无法释放资源。我们可以使用try让close()一定被执行到。
        //把需要释放资源的东西放到try()的括号里  在try执行完之后  会自动调用close
        try (InputStream inputStream = new FileInputStream("./aaa.txt");
             OutputStream outputStream = new FileOutputStream("./aaa.txt")){
            .......
        }

你可能感兴趣的:(JavaEE初阶,java)