黑马程序员技术交流社区

标题: 求解释一句IO代码 [打印本页]

作者: 回音    时间: 2013-12-14 13:39
标题: 求解释一句IO代码
本帖最后由 回音 于 2013-12-14 17:43 编辑

复制文件的代码中有这么一段:
InputStream in =.......
OutputStream out = ..........
int temp = 0;
while( (temp = in.read()) != (-1) )
{
    out.write(temp);
}
temp里储存的是什么?是字符?字节?如果这样的话为什么temp是int类型?

作者: liyi2013    时间: 2013-12-14 13:41
抢沙发、求给点技术分!好方便进入下一环节
作者: liyi2013    时间: 2013-12-14 13:45
int temp = 0;  所以temp是int类型!
作者: 张利星    时间: 2013-12-14 13:50
InputStream的read()方法作用是:从输入流中读取数据的下一个字节。它返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。而temp是用来记录这个int字节值的,所以是int类型,可以用temp=-1来判断是否读取到末尾作为循环条件
作者: 谢文斌    时间: 2013-12-14 13:58
本帖最后由 谢文斌 于 2013-12-15 08:46 编辑

计算机中存储的都是二进制位,而一个字节byte代表了8个二进制位(bit)。
我们再来看看read()方法:
read

public int read()
         throws IOException

    从此输入流中读取一个数据字节。如果没有输入可用,则此方法将阻塞。

    指定者:
        类 InputStream 中的 read

    返回:
        下一个数据字节;如果已到达文件末尾,则返回 -1。
    抛出:
        IOException - 如果发生 I/O 错误。
昨天回答的时候因为知识面不全,错误地回答了byte理论上可以替换int去接收read()的返回值,但是我错了。版主还给分,真是惭愧啊,真实原因楼下的帖子说得很好,也是他们给我纠正的,感谢你们。正解:昨天看是FileInputStream的read()方法API,今天查了一下它是从父类InputStream里继承过来的read()方法,在那里显示的是:从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。在输入数据可用、检测到流末尾或者抛出异常前,此方法一直阻塞。
所以,不能用byte接收。

作者: 小斥候    时间: 2013-12-14 14:04
本帖最后由 小斥候 于 2013-12-14 14:09 编辑

你最好是读取到缓冲里面:byte[] buffer = new byte[1024]; if( (temp =in.read(buffer) ) != -1){out.write( buffer, 0 , temp) ;}
作者: 小斥候    时间: 2013-12-14 14:06
不对啊,我刚刚回答的一个呢?怎么给我删除了?
作者: 郭涛    时间: 2013-12-14 14:21
张利星 发表于 2013-12-14 13:50
InputStream的read()方法作用是:从输入流中读取数据的下一个字节。它返回 0 到 255 范围内的 int 字节值。 ...

老冯也没讲为什么要用int,理论上byte也是可以的
作者: 潘金锋    时间: 2013-12-14 14:25
从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。查API文档就知道啦
作者: believe    时间: 2013-12-14 14:41
这是Java中的输入输出流,应该是将图片或者视频类的文件以二进制的形式存储,读到缓冲区。
作者: Diaraelo    时间: 2013-12-14 14:51
无论存什么都会被转变成2进制再读取的,用byte型也可以吧,只是int存储量比较大吧。
作者: 张利星    时间: 2013-12-14 23:06
郭涛 发表于 2013-12-14 14:21
老冯也没讲为什么要用int,理论上byte也是可以的

byte的范围是-128~127,而InputStream的read()方法读取的是0~255范围内的int字节值,所以byte是不可以的
作者: Kyle    时间: 2013-12-14 23:12
郭涛 发表于 2013-12-14 14:21
老冯也没讲为什么要用int,理论上byte也是可以的

坑爹啊,你敢污蔑++
当时他可说了为什么byte不行而必须用int
作者: 还记得梦想吗    时间: 2013-12-15 02:35
字节流的两个基类 * InputStream OutputStream*  * 字符流两个基类 基类又叫父类 * Reader Writer
所以in.read()读取到的是字节流。。 byte 类型的取值范围是-128~127   

Byte是一个字节 也就是 8个位 。int 的取值范围是 0-255 是4个字节 4个八位 。。
while( (temp = in.read()) != (-1) )  -1的意思是流读取结束 。没有可以读取的了 。。   把读取到的值和-1 作比较 如果等于-1 就结束退出while循环!!!   

此方法 最好使用缓冲技术 , 就像接水一样 存满一小桶 读取一次 写入一次 提高效率

FileReader fr = new FileReader("FileReaderDemo.java");
  
  char[] buf = new char[1024];  

  int num = 0;  

  while((num=fr.read(buf))!=-1){
   System.out.print(new String(buf,0,num));
   //print  打印到1024字节不换行
   //println   打印到1024字节换行
  }
  
  fr.close();

作者: 还记得梦想吗    时间: 2013-12-15 02:41
郭涛 发表于 2013-12-14 14:21
老冯也没讲为什么要用int,理论上byte也是可以的

byte 类型貌似不可以
byte num  ;  
//在这一句 读取到的字符需要转化为byte类型 测试结果读不出来!!!!
while((num=(byte) fr.read(buf))!=-1){
   System.out.print(new String(buf,0,num));
   //print  打印到1024字节不换行
   //println   打印到1024字节换行
  }

//输出结果
reak;


作者: 还记得梦想吗    时间: 2013-12-15 02:42
郭涛 发表于 2013-12-14 14:21
老冯也没讲为什么要用int,理论上byte也是可以的

byte 类型貌似不可以
byte num  ;  
//在这一句 读取到的字符需要转化为byte类型 测试结果读不出来!!!!
while((num=(byte) fr.read(buf))!=-1){
   System.out.print(new String(buf,0,num));
   //print  打印到1024字节不换行
   //println   打印到1024字节换行
  }

//输出结果
reak;


作者: 还记得梦想吗    时间: 2013-12-15 02:44
谢文斌 发表于 2013-12-14 13:58
计算机中存储的都是二进制位,而一个字节byte代表了8个二进制位(bit)。
我们再来看看read()方法:
read

byte 类型貌似不可以
byte num  ;  
//在这一句 读取到的字符需要转化为byte类型 测试结果读不出来!!!!
while((num=(byte) fr.read(buf))!=-1){
   System.out.print(new String(buf,0,num));
   //print  打印到1024字节不换行
   //println   打印到1024字节换行
  }

//输出结果
reak;


作者: 还记得梦想吗    时间: 2013-12-15 02:53
查了一下 API 文档
java.io.Reader  类下  public abstract class Readerextends Objectimplements Readable, Closeable用于读取字符流的抽象类。子类必须实现的方法只有 read(char[], int, int) 和 close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。

int  read()       读取单个字符。  返回类型是int类型 所以定义temp是 int类型
int read(char[] cbuf, int off, int len)         将字符读入数组的某一部分。
int  read(char[] cbuf, int off, int len)          将字符读入数组的某一部分。

都是返回类型是 int 类型 byte类型测试下 的确通不过  大家来评

byte num  ;  
//在这一句 读取到的字符需要转化为byte类型 测试结果读不出来!!!!
while((num=(byte) fr.read(buf))!=-1){
   System.out.print(new String(buf,0,num));
   //print  打印到1024字节不换行
   //println   打印到1024字节换行
  }

//输出结果
reak;

作者: 谢文斌    时间: 2013-12-15 08:33
张利星 发表于 2013-12-14 23:06
byte的范围是-128~127,而InputStream的read()方法读取的是0~255范围内的int字节值,所以byte是不可以的 ...

原来是这样啊,受教了。
作者: 谢文斌    时间: 2013-12-15 08:34
还记得梦想吗 发表于 2013-12-15 02:44
byte 类型貌似不可以
byte num  ;  
//在这一句 读取到的字符需要转化为byte类型 测试结果读不出来!! ...

嗯嗯,谢谢,已经知道了。我改下答案吧




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2