7.22 Java基础 | I/O流【下】
【前情回顾】
字节流
- OutputStream常用方法 write() \flush()\close()\【都是void类型的函数】
- FileOutputStream使用文件输出流将“幼稚鬼同学快学习”写入磁盘文件 FileOutputStream(String name) / FileOutputStream(String name,boolean append)/FileOutputStream(File file) / FileOutputStream(File file,boolean append)
- InputStream常用方法 read()、available()【除了close都是int类型函数】
- FileOutputStream将文件信息从磁盘中读取到内存中,并在控制台输出
- 使用字节流实现磁盘文件拷贝
感觉上一篇写了一tan 粑粑,可能当时人不太清醒而且不够理解
重新理解了一遍概念:
I/O流是磁盘和内存之间的实现数据交互的通道,I代表input,o代表Output,而FileOutputStream文件输出流 就是一个具有 “把内存中的数据 传给 文件” 的功能的通道,而“内存中的数据”可以代表如“数组”中的数据,所以前边说:把数组中的数据传给文件。
所以后来编写程序的时候说:把数组(内存)中的数据传入通道,通道实现数组和文件之间的数据交互。通道.write(数组)
可能图片能更清楚一点:
(自己的理解,欢迎指正)
FileOutputStream使用文件输出流将“幼稚鬼同学快学习”写入磁盘文件
将数组内容写入"通道":法一:使用for循环一个一个输入法二:一次性全部发送过去法三:使用偏移量(注意考虑数组越界的问题)三个方法:
主要代码部分: 创建文件、创建通道、创建数组、数据交换
File dir=new File("D:\\JFM code\\Java_test\\d722");if(!dir.exists()){dir.mkdirs();}File f=new File(dir,"io_3.txt");//构建通道 文件与(“到”)内存之间的通道,文件输出流FIleOutputStream是从内存到文件的数据传输通道OutputStream os=new FileOutputStream(f,true);//创建字符串,并将字符串变成数组String text="幼稚鬼同学快学习";byte[] bytes=text.getBytes();法一 for(byte a:bytes){os.write(a);}法二 os.write(bytes);法三 os.write(bytes,3,bytes.length-3);os.flush();os.close();
结果一:
结果二:
结果三:
FileOutputStream将文件信息从磁盘中读取到内存中,并在控制台输出
创建文件对象、创建通道、创建数组
此时读取的是一串数字:
new String(buf) 把字节数组转化成字符串
结果转化成字符串:
![]()
小 贴士(加new String的原因):
数据类型不同:
buf
是字节数组(byte[]
),存储的是原始二进制数据(0-255 的数值)- 字符串(
String
)是字符序列,存储的是 Unicode 字符为什么需要转换:
System.out.println()
可以直接打印字节数组,但会输出其内存地址(如[B@1b6d3586
)- 通过
new String(buf)
可以将字节数组按照默认字符集(通常是 UTF-8)解码为有意义的字符串- 如果直接打印字节数组,得到的是无意义的内存标识,而不是实际内容
当通道中的数据太大了,而内存不够,只能一次读取部分,多读几次
方法一:
![]()
方法二:
小贴士 read(byte[] buf)
方法的补充:
当读取到数据时:返回实际读取的字节数(范围是 1~ 缓冲区长度)。
当流结束时:返回
-1
(表示已经到达流的末尾,没有更多数据可读取)。特殊情况:
只有在使用带有缓冲区的
read(byte[] buf)
方法时,才可能返回 0,但这并不表示 "没有数据",而是表示:
缓冲区长度为 0(
buf.length == 0
)或者在非阻塞模式下,当前确实没有数据可读取(但流并未结束)