java I/O流学习
1、对I/O流的理解
-
要想“流”,要保证有三个东西:
-
源头
-
管道
-
目标
-
-
对于源头来说,他是主动的,是流出
-
对于目标来说,他是被动的,是被流入
-
将这个思想放到程序中:
因为程序员操作的是程序,所以读和写都是相对于程序来说的!-
程序要想获取数据源(另一个程序、数据库、文件、云空间)的数据,是被动的接受,被流入,也叫读,如同下图所示:
![]()
-
程序向数据源传输数据,则程序变成主动的,主动输出,也叫写,如图所示:
-

2、FileInputStream
1 FileInputStream ins = new FileInputStream("file/1.txt"); 2 int out = 0; 3 while ((out = ins.read())!=-1){ 4 System.out.println("out = " + out); 5 } 6 // 带通道的流一定记得close掉,不然进程一直存在,占用非常大的内存!!! 7 ins.close();
结果:
out = 97 out = 32 out = 97 out = 32 out = 97 out = 13 out = 10 out = 98 out = 13 out = 10 out = 99
1.txt长这样:

说明
-
read()方法读出的是byte类型的ASSCII码,并且是一个一个子节读的字节流,所以使用while循环输出。
-
如果想输出字符,可以强制类型转换为char(因为是同级的),即
(char)out,输出就和文件一样了。 -
自动类型转换:byte,short,char—> int —> long—> float —> double
-
-
enter键其实是两个控制符,回车(光标回到本行行首 13)->换行(光标回到对应的下一行 10)。
1 FileInputStream ins = new FileInputStream("file/1.txt"); 2 byte[] bytes = new byte[1024]; 3 int len = ins.read(bytes); 4 ins.close(); 5 System.out.println(new String(bytes,0,len));
结果:
a a a b c
注:
-
使用read(byte[])方法把文件信息读到byte[]数组里,返回值就变成了读入的子节长度
-
(byte[] bytes, int offset, int length)
bytes-要解码为字符的字节 offset-要解码的第一个字节的索引 length-要解码的字节数
-
一个逻辑的火花:读和写确实是相对于程序来说的,但是程序也很好的安排了读和写的位置,比如,FileInputStream(程序从哪个文件读数据),.read(程序把读入的数据放到哪),FileOutputStream(程序向哪个文件写数据),.wirte(程序从哪个地方把要写出的数据拿出来),这么看来,我所说的“程序”就像是中间的管道。
3、FileOutputStream
1 FileOutputStream outs = new FileOutputStream("file/2.txt"); 2 byte[] bytes = "zhangYaoYuan,你好啊!".getBytes(); 3 for (byte aByte : bytes) { 4 outs.write(aByte); 5 } 6 // outs.write(bytes);不用for循环,这一步就可以了 7 outs.close();
结果:

如果是操作大的文件,难道是new一个非常大的byte数组吗?
实际上并不是这么处理的,而是使用循环分N次搬运
即buffer缓冲的思想
复制一张图片:
1 public void copyFile() throws IOException { 2 FileInputStream ins = new FileInputStream("file/minions.jpg"); 3 FileOutputStream outs = new FileOutputStream("file/target.jpg"); 4 5 byte[] bytes = new byte[1024]; 6 int lens;// 当一次读入的数据大小少于1024b时,这个就有用了,少操作了很多空格 7 while ((lens = ins.read(bytes))!=-1){ 8 outs.write(bytes,0,lens); 9 } 10 ins.close(); 11 outs.close(); 12 }
4、BufferedInputStream/BufferedOutputStream
有了buffer缓冲的思想,Java写好了一个类,就不需要再自定义byte数组了
1 public void bufferedStream() throws IOException{ 2 BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("file/minions.jpg")); 3 BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("file/target.jpg")); 4 int lens; 5 while ((lens = bufferedInputStream.read())!=-1){ 6 bufferedOutputStream.write(lens); 7 } 8 bufferedInputStream.close(); 9 bufferedOutputStream.close(); 10 }
注意:
使用方法和自定义byte数组一样,但是注意这个类的构造参数是FileInputStream即另外一个类,这就如同是在花钱买了一个VIP服务,套在之前的套餐上!这也是一种设计模式,叫装饰设计模式!
5、FileReader/FileWriter
注:
xxInputStream、xxOutputStream都代表字节流,一次读取一个字节,所以使用byte[]数组接收或者缓冲;
xxReader、xxWriter都代表字符流,一次读取两个字节(Unicode编码),所以使用char[]数组进行接收或者缓冲,注意在Java中char类型占用两个字节。
二者的用途:
字节流通常用于处理二进制数据,实际上它可以处理任意类型的数据,但它不支持直接写入或读取Unicode码元;字符流通常处理文本数据,它支持写入及读取Unicode码元。
所以说,xxReader、xxWriter专门用来处理文本的(其实就是Unicode编码的中文文本)。
类的使用基本和字节流一致
1 public void fileReader() throws IOException { 2 FileReader fileReader = new FileReader("file/1.txt"); 3 int lens; 4 char[] chars = new char[1024]; 5 while ((lens = fileReader.read(chars)) != -1) { 6 System.out.println(new String(chars, 0, lens)); 7 } 8 fileReader.close(); 9 }
想要输出读入的内容,就要new一个char数组进行接收。
1 public void fileWriter() throws IOException { 2 FileWriter fileWriter = new FileWriter("file/3.txt"); 3 String str = "张耀元哈哈哈哈哈哈哈!"; 4 fileWriter.write(str); 5 fileWriter.close(); 6 }
既然是专门处理文本的,写文本可以直接用String做参数。
6、BufferedReader/BufferedWriter
BufferedReader/BufferedWriter同字节流的设计一样,使用了装饰的设计模式,并且增加了readLine()和nextLine()方法,处理文本更加方便。
1 public void bufferedReader() throws IOException { 2 BufferedReader bufferedReader = new BufferedReader(new FileReader("file/3.txt")); 3 String str = null; 4 // 直接返回读到的内容,比较牛,如果使用read方法,还要申请一个char数组接住内容 5 while ((str = bufferedReader.readLine())!= null){ 6 System.out.println(str); 7 } 8 bufferedReader.close(); 9 }
1 public void bufferedWriter() throws IOException { 2 // append 追加 3 BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("file/4.txt",true)); 4 //“\n”换行的方式换个系统可能就不行了,所以专门有一个方法nextLine()实现换行 5 // String string = "你\n" + "你\n" + "你好厉害啊!"; 6 String str1 = "你好棒啊!"; 7 String str2 = "你好帅啊!"; 8 bufferedWriter.newLine(); 9 bufferedWriter.write(str1); 10 bufferedWriter.newLine(); 11 bufferedWriter.write(str2); 12 bufferedWriter.close(); 13 }
7、apache commons io


浙公网安备 33010602011771号