java i o教程_java I/O流学习

I/O Stream

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 = 97out = 32out = 97out = 32out = 97out = 13out = 10out = 98out = 13out = 10out = 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 abc

注:

使用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 (byteaByte : bytes) {4 outs.write(aByte);5 }6 //outs.write(bytes);不用for循环,这一步就可以了

7 outs.close();

结果:

如果是操作大的文件,难道是new一个非常大的byte数组吗?

实际上并不是这么处理的,而是使用循环分N次搬运

即buffer缓冲的思想

复制一张图片:

1 public void copyFile() throwsIOException {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() throwsIOException{2 BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("file/minions.jpg"));3 BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("file/target.jpg"));4 intlens;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() throwsIOException {2 FileReader fileReader = new FileReader("file/1.txt");3 intlens;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() throwsIOException {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() throwsIOException {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() throwsIOException {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

一些基础的东西学习了之后,实际开发中,不需要这么麻烦的操作流(苦笑.jpg,感觉都白学了),apache就写了一个非常方便、非常牛逼、非常好用的工具类FileUtils,操作文件就变得非常easy!(但不是说基础的就不用学了,知道原理更重要!)

官方文档先放这,关于练习和例子之后补充。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值