Java---IO流

IO流

  • 字节流
    • 输出流:FileOutputStream
    • 输入流 FileInputStream
  • 字符流
    • 字符输入流 FileReader
    • 字符输出流 FileWriter
  • 缓冲流
    • 字节缓冲流
    • 字符缓冲流

File:表示系统中的文件或者文件夹的路径。可以用来获取文件信息,判断文件类型,创建删除文件等。File类只能对文件本身进行操作。
IO流:用来读写文件中的数据(可读写文件或者网络中的数据)
IO流分类
依据 字节流可分为:InputStream和OutputStream
依据 字符流可分为:Reader和Writer

字节流

输出流:FileOutputStream

操作本地文件的字节输出流,可以把程序中的数据写到本地文件中。

		// 1.创建对象
		// 写出 -> 输出流 OutputStream
		FileOutputStream fos = new FileOutputStream("a.txt");
		// 2.写出数据
		fos.write(98);
		// 3.释放资源
		fos.close();

创建字节输出流对象
参数是字符串表示的路径或者File对象都是可以的。如果文件不存在会创建一个新的文件,但是要保证父级路径是存在的。如果文件已经存在,则会清空文件。
写数据
write方法的参数是整数,但是实际上写到本地文件中的是整数ASCII上对应的字符。
一次写多个字节

		// 1.创建对象
		FileOutputStream fos = new FileOutputStream("a.txt");
		// 2.写出数据
		// 一次写一个字符数据
		fos.write(97); // a
		fos.write(98); // b
		// ②、一次写入一个字符数组
		byte[] bytes = { 97, 98, 99, 100, 101 };
		fos.write(bytes);
		//一次写一个字符数组的部分数据
		// 参数一:数组 ;参数二:起始索引 ; 参数三:个数
		fos.write(bytes, 1, 2); // b c
		// 3.释放资源
		fos.close();

续写和换行

		如果想要续写,打开续写开关即可
		打开位置,创建对象的第二个参数
		默认false:表示关闭,此时创建对象会清空文件
		手动true:表示打开续写,此时创建对象不会清空文件
		new FileOutputStream("a.txt",true);
		如果想要换行
		String str3 = "\r\n";
		byte[] bytes3 = str3.getBytes();
		fos.write(bytes3);

输入流 FileInputStream

// 1.创建对象
		FileInputStream fis = new FileInputStream("a.txt");
		// a.txt : abcde
		// 2.读取数据
		int b1 = fis.read();
		System.out.println(b1); // 97
		System.out.println((char) b1); // 强转: a
		// 读取不到就会返回 -1
		// 3.释放资源
		fis.close();

一次读一个字节,读出来的是数据在ASCII上对应的数字。读取到文件末尾时,read方法返回 -1。
循环读取

// 1.创建对象
		FileInputStream fis = new FileInputStream("a.txt");
		// a.txt : abcde
		// 2.循环读取
		//定义第三方变量
		int b;
		while ((b = fis.read()) != -1) {
			System.out.println((char) b);
		}
		// 释放资源
		fis.close();

一次可以读取一个字节数组,每次读取会尽可能把数组填满。

// 1.创建对象
		FileInputStream fis = new FileInputStream("a.txt");
		// 2.读取数据
		byte[] bytes = new byte[2];
		//一次读取多个字节数据:具体读多少,跟数组的长度有关
		//返回值:本次读取到了多少个字节数据
		int len = fis.read(bytes);
		System.out.println(len);
		String str= new String(bytes);
		System.out.println(str);
		//3.释放资源
		fis.close();

案例:文件拷贝

// 1.创建对象
		FileInputStream fis = new FileInputStream("movie.mp4");
		FileOutputStream fos = new FileOutputStream("a\\copy.mp4");
		// 2.拷贝
		// 需要边读边写
		int b;
		while ((b = fis.read()) != -1) {
			fos.write(b);
		}
		// 3.释放资源
		// 规则: 先开的最后关闭
		fos.close();
		fis.close();

缺点:FileInputStream 一次读写一个字节,速度慢。可以利用FileInputStream使用 byte[] 数组一次遍历多个数据。

// 1.创建对象
		FileInputStream fis = new FileInputStream("D:\\aaa\\movie.mp4");
		FileOutputStream fos = new FileOutputStream("aaa\\copy.mp4");
		// 2.拷贝
		int len;
		byte[] bytes = new byte[1024 * 1024 * 5]; // 5兆大小
		while ((len = fis.read(bytes)) != -1) {
			fos.write(bytes,0,len);
		}
		// 3.释放资源
		fos.close();
		fis.close();

字符流

输入流:一次读取一个字节,遇到中文时,一次读多个字节再写到文件中。
输出流:底层会把数据按照指定的编码方式,变成字节再写到文件中。
适用场景:文件中有中文。

字符输入流 FileReader

		// 1.创建对象并关联本地文件
		FileReader fr = new FileReader("a.txt");
		// 2.读取数据 
		// 细节1:字符流的底层就是字节流
		// 默认一个字节一个字节的读取的
		// 如果遇到中文,就会一次读取多个字节,GBK一次两个字节 UTF-8一次三个字节
		// 细节2:读取之后,方法底层会进行解码并转换成十进制
		// 十进制作为返回值 并作为字符集上的数字
		// 细节3:想要看中文 可以对十进制进行强转
		//空参read
		int ch;
		while ((ch = fr.read()) != -1) {
			System.out.println((char) ch);
		}	
		//带参read:读取数据、解码、强转三者合并,把强转之后字符放进数组
		//空参的read + 强转类型转换
		char[] chars = new char[2];
		int len;
		while((len = fr.read(chars)) != -1) {
			//把数组中的数据变成字符串再进行打印
			System.out.println(new String(chars,0,len));
		}
		// 3.释放资源
		fr.close();

字符输出流 FileWriter

		// 1.创建对象 续写开关打开
		FileWriter fw = new FileWriter("a.txt", true);
		// 2.写数据
		fw.write(25105); // 写一个字符
		fw.write("你好?"); // 写一个字符串 9个字节
		char[] chars = { 'a', 'b', 'c', '我' };
		fw.write(chars); // 写一个字符数组
		// 3.释放资源
		fw.close();

如果write方法的参数是整数,但是实际上写到本地文件中的是整数在字符集上对应的字符。
字符流原理分析
创建字符输入流对象底层:关联文件,并创建缓冲区(长度为8192的字节数组)
读取数据底层:判断缓冲区中是否有数据可以读取。缓冲区没有数据:就从文件中获取数据,装到缓冲区中,每次尽可能装满缓冲区;如果文件中也没用数据时,返回 -1。缓冲区有数据:就从缓冲区中读取。 空参的read方法:一次读取一个字节,遇到中文一次读多个字节,把字节解码并转成十进制返回。 有参的read方法:把读取字节、解码、强转三步合并,强转之后的字符放到数组当中。

缓冲流

缓冲流也称为高效流或者高级流。缓冲流自带缓冲区、可以提高基本字节流、字符流读写数据的性能。

字节缓冲流

原理:底层自带了长度为8192的缓冲区提高性能
首先基本流会读取数据,把读到的数据放到缓冲输入流的缓冲区,一次性会读8192个字节数据。下面代码中创建的中间变量b就是不断倒手两边的数据,将左边缓冲区的数据一个一个的放到右边缓冲区,当右边缓冲区填满了就会自动利用基本流向目的地写出数据。循环上述步骤,直到读到文件末尾返回-1。

BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
       BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("aaa\\a.txt"));
       int b;
       while ((b = bis.read()) != -1){
           bos.write(b);
       }
       bos.close();
       bis.close();
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("aaa\\a.txt"));
        byte[] bytes = new byte[8192];
        int len;
        while ((len = bis.read(bytes)) != -1){
            bos.write(bytes,0,len);
        }
        bos.close();
        bis.close();

字符缓冲流

原理:底层自带了长度为8192的缓冲区提高性能。字符流同样也带有8192字节大小的缓冲区,所有性能提高不大,主要学习字符缓冲流两个特有的方法:输入流的readLine()和输出流的newLine()。

		BufferedReader br = new BufferedReader(new FileReader("a.txt"));
        String line;
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }
        br.close();
        BufferedWriter bw = new BufferedWriter(new FileWriter("aaa\\a.txt"));
        bw.write("你好");
        bw.newLine();
        bw.close();

来源:B站黑马学习视频

你可能感兴趣的:(java,开发语言)