A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 张振纲 中级黑马   /  2012-8-11 19:06  /  2311 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 张振纲 于 2012-8-11 20:36 编辑

我们都知道IO流分为字节流和字符流
假设我们需要拷贝一个文本文件
在不利用缓冲技术下,字节流是读取一个字节,然后写入一个字节,直接输出并不需要刷新流
那么字节流的缓冲区的具体过程是将数据从硬盘读出,放入内存,然后存储到另一片内存然后再输出吗?

那字符流具体又是什么流程呢?

还有,Reader 类中read方法会返回一个整数
我们通过这个整数就可以将数据写入流中,这个整数代表的是什么?

带着疑问我写了这样一段代码,来研究到底返回的INT是什么
  1. import java.io.*;
  2. class Fuzhi
  3. {
  4. public static void main(String[] args) throws IOException
  5. {
  6. FileInputStream fis = new FileInputStream("MapTest.java");
  7. FileOutputStream fos = new FileOutputStream("333.java");

  8. int num = 0;

  9. while ((num=fis.read())!=-1)
  10. {
  11. System.out.print((char)num);
  12. fos.write(num);
  13. }
  14. }
  15. }
复制代码


通过这段代码就很明显的说明read返回的int值就是数据
是被提升类INT类型的二进制数据
然后再WRITE时转换回去

哈哈,问题解决了

6 个回复

倒序浏览
Stream字节流流接受输出字节并将这些字节发送到某个接收器
InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,否则可能接受平台默认的字符集。

每次调用 InputStreamReader 中的一个 read() 方法都会导致从基础输入流读取一个或多个字节。要启用从字节到字符的有效转换,可以提前从基础流读取更多的字节,使其超过满足当前读取操作所需的字节。

public abstract int read()
                  throws IOException

    从输入流读取下一个数据字节。返回 0 到 255 范围内的 int 字节值。如果因已到达流末尾而没有可用的字节,则返回值 -1。在输入数据可用、检测到流的末尾或者抛出异常前,此方法一直阻塞。
READ()方法 返回的INT 数值,是代表流中的的位置,,当返回,-1是,则代码,这个流中的,数据都传输完。在进行下次的读取,在传输。

字节流,传送数据用的是,字节,而,字符流,是包字节包装成字符。传输的内容更多。   而再包装BUffer 就更多了,

具体数据的传送过程是读取内容,暂时存放在内存,然后写入硬盘。】
关键在与硬盘,每次的写入,频繁的写入,  会降低,硬盘的寿命,造成更多的,硬盘中的碎片。
所有,我们用buffer,或者,reader 包装,字节流,就是为了,增大每次传送的数据容量,而减少写入硬盘的次数。


回复 使用道具 举报
缓冲的作用我的理解是:减少读取硬盘的次数,比如说读的时候,不是说你读一个字节,系统就只在硬盘中取一个字节,它会取一大块字节,放入内存中,这样你再读的时候,系统就首先在你已经缓冲读入在内存中的数据里读,而不需要再读硬盘了,加快速度

同样写也是的,写一个文件的时候,不会写一字次访问一次硬盘,而是将整个文件读出来放在内存中,一下都写入硬盘。

所以对于write("a"),其实没有将a写入硬盘文件中,而是放在了write()方法自己内部的数组中,等数组满了,数据多了,一起写入硬盘。

总之,缓冲是为了减少访问硬盘,加快速度。

以上是个人理解,不一定对。
回复 使用道具 举报
刘圣伟 发表于 2012-8-11 20:03
Stream字节流流接受输出字节并将这些字节发送到某个接收器
InputStreamReader 是字节流通向字符流的桥梁: ...

也就是说缓冲区是多一次内存中的操作,使单个字符在缓冲区内累积,然后统一输出,对吗?

另外关于那个INT代表在流中的位置,能细说说吗?
回复 使用道具 举报
楼上说的关于read()方法的内容不太全面,我补充一下
在InputStream这个类中,经常用到的read方法有两种,
第一种
int x=0;
InputStream is=new InputStream();
while((x=is.read())!=-1)
{....}
这种情况下,read()方法从输入流读取下一个数据字节。返回 0 到 255 范围内的 int 字节值。如果因已到达流末尾而没有可用的字节,则返回值 -1。在输入数据可用、检测到流的末尾或者抛出异常前,此方法一直阻塞。
第二种
InputStream is=new InputStream();
byte[] b=new byte[1024];
int x=0;
while((x=is.read(b))!=-1)
{.....}
public int read(byte[] b)throws IOException
从输入流中读取一定数量的字节并将其存储在缓冲区数组 b 中。以整数形式返回实际读取的字节数。在输入数据可用、检测到文件末尾或者抛出异常前,此方法一直阻塞。

所以第一种方法x表示得到的字节的int值,即ASC||码值,第二种方法得到的x表示获取到的字节数量,意义是不同的

点评

十分感谢,终于彻底明白了  发表于 2012-8-11 20:45
回复 使用道具 举报
王程 发表于 2012-8-11 20:42
楼上说的关于read()方法的内容不太全面,我补充一下
在InputStream这个类中,经常用到的read方法有两种,
...

这样一来后面的方法要比前面的方法每次从内存中多读1KB的数据?
回复 使用道具 举报
王程 中级黑马 2012-8-11 21:03:42
7#
黎健东 发表于 2012-8-11 20:51
这样一来后面的方法要比前面的方法每次从内存中多读1KB的数据?

没有啊,那个byte数组的大小我随便定的,你可以随意
第一种是一次读一个字节,第二种是一次读一堆
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马