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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 陈振兴 中级黑马   /  2012-9-10 09:05  /  1551 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 陈振兴 于 2012-9-10 11:32 编辑

问题描述:今天一敲代码,怎么感觉字节流中的字节数组为什么不能读取到,反而比原图片的字节大好多倍??
代码如下:
public static void copyPic1()throws IOException{
                //我就不try了
                FileInputStream in = new FileInputStream("c:\\clone.bmp");
                FileOutputStream out = new FileOutputStream("c:\\bp.bmp");
                byte[] by = new byte[1024];
                int len = 0;
                while((len=in.read())!=-1){
                        out.write(by,0,len);
//                        out.write(len);  注释掉byte数组,图片就写入成功
                }
                out.close();
                in.close();
        }

public static void copyPic2()throws IOException{
                //我就不try了
                BufferedInputStream bufin = new BufferedInputStream(new FileInputStream("c:\\clone.bmp"));
                BufferedOutputStream bufout = new BufferedOutputStream(new FileOutputStream("c:\\pp.bmp"));
//                byte[] by = new byte[1024];
                int len = 0;
                while((len=bufin.read())!=-1){
//                        bufout.write(by,0,len);  字节缓冲字节流也是如此,
                        bufout.write(len);
                }
                bufout.close();
                bufin.close();
        }
问题:1)把读取到字节缓存到byte[]里,和直接读取后,为什么缓存的数据就比原来的数据量大,导致的直接原因是什么?
2)若果不加缓冲流的话,输入(in)输出(out)关闭的顺序,我从IO这块的理解是,不加缓冲技术,应该就是即读即写的这种,首先关闭的是写,再关闭读取流,但感觉效率的影响又不是很大!即他们的关闭顺序的区别有吗?

评分

参与人数 1技术分 +1 收起 理由
王德升 + 1 赞一个!

查看全部评分

2 个回复

倒序浏览
本帖最后由 张飞年 于 2012-9-10 11:05 编辑

     (1)楼主你的关键错误在于你的read()方法的使用,int len = in.read() 是读取流从源文件一次读取一个字节并把字节给len,然后我们操作len(的输出或者写入别的流)。int len = in.read(by);是表示一次从源文件一次读取一个字节长度的字节并存储在里面,返回当前存储的字节数(有时存满,如果到文件结尾有可能存不满),然后我们利用这个数组长度,取出相应长度的字节数。
具体到楼主代码错误在:
while((len=in.read())!=-1){//这里应为read(by),read(by)返回的是已写入数组的字节长度,如果到结尾就返回-1,返回-1的原因你可以看一下自定义myRead()那节视频,
                         out.write(by,0,len);//取出对应长度字节数
【楼主的代码的意思是将一个1024的空数组写了n倍(具体就是字节数*1024,如果不出意外就是1024倍)到输出流】
      (2)关于关闭输入流与输出流的顺序,当文件读写完成后,输入流和输出流都没有数据,因为都在finally中所以先关闭谁都可以,顺序没有要求,不过别忘了健壮性的判断。  fw.close()与fr.close()的顺序可以颠倒。
=============================================================
下面的字符流操作也要注意这一点,同理的。提醒一下,当用缓冲时的readLine()方法时也得请注意:
    String line = null;//定义一个字符串以便存储取出行
   while ((line = myBuf.myReadLine()) != null) {//如果在myReadLine中取到了结尾则会返回-1,进而方法返回null,如果这里接收到null,也就表示到了行尾
    System.out.println(line);
这里附上我写的注释比较多的一段代码吧,供参考:
  1. public static void main(String[] args) throws IOException {
  2.                 BufferedInputStream bufin = new BufferedInputStream(//定义字节缓冲
  3.                                 new FileInputStream("d:\\222.jpg"));
  4.                 BufferedOutputStream bufout = new BufferedOutputStream(
  5.                                 new FileOutputStream("d:\\446.jpg"));
  6.                 byte[] by = new byte[bufin.available()];//定义长度为对象字节长度的数组
  7.                 int len = 0;
  8.                 if((len = bufin.read(by)) != -1) {//一次全读进数组,这里用if条件,因为一次就可以全读取完,不然就用while
  9.                         bufout.write(by,0,len);//这里一次性输出相应长度的数组内容,如果数组内容是1024的大小,那么就用while来多次取多次输出
  10.                         bufout.flush();
  11.                 }
  12.                 bufout.close();
  13.         }
复制代码
回复 使用道具 举报
张飞年 发表于 2012-9-10 10:39
(1)楼主你的关键错误在于你的read()方法的使用,int len = in.read() 是读取流从源文件一次读取一个 ...

ok!谢谢,学习了!真正理解了啊!呵呵
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马