黑马程序员技术交流社区

标题: 课后练习求优化:将一个图片文件中数据存储到另一个文件.. [打印本页]

作者: 萧萧北    时间: 2013-6-15 08:55
标题: 课后练习求优化:将一个图片文件中数据存储到另一个文件..
本帖最后由 孙百鑫 于 2013-6-19 09:05 编辑

IO部门的一个课后练习:将一个图片文件中数据存储到另一个文件...
根据毕老师视频思路,我是这么分析的
  /* 分析:
源:因为是源,所以使用读取流。InputStream Reader
操作的是图片,不是操作文本文件。这时就可以选择InputStream
这样体系就明确了。
接下来明确要使用该体系中的哪个对象。
明确设备:硬盘。上一个文件。
Reader体系中可以操作文件的对象是 FileInputStream
是否需要提高效率:是!。加入InputStream体系中缓冲区 BufferedInputStream
  */
  1. public static void test_1()throws IOException
  2. {
  3. /* 分析:
  4. 源:因为是源,所以使用读取流。InputStream Reader
  5. 操作的是图片,不是操作文本文件。这时就可以选择InputStream
  6. 这样体系就明确了。
  7. 接下来明确要使用该体系中的哪个对象。
  8. 明确设备:硬盘。上一个文件。
  9. Reader体系中可以操作文件的对象是 FileInputStream
  10. 是否需要提高效率:是!。加入InputStream体系中缓冲区 BufferedInputStream
  11. */
  12. BufferedInputStream bufis=new BufferedInputStream(new FileInputStream("IMG5051A.jpg"));

  13. BufferedOutputStream bufos=new BufferedOutputStream(new FileOutputStream("test1.jpg"));

  14. int len=0;
  15. while((len=bufis.read())!=-1) //通过read()逐个读取,效率不高
  16. {
  17. bufos.write(len);
  18. }
  19. bufos.close();
  20. bufis.close();
  21. }
复制代码
上面给代码能实现赋值图片功能,但while((len=bufis.read())!=-1) //通过read()逐个读取,感觉效率不高,我想通过逐行读取,又做了如下改变:
  1. //练习:将一个图片文件中数据存储到另一个文件中。复制文件。
  2. //test_1()方法的改进 有问题
  3. public static void test_1_1() throws IOException
  4. {
  5. BufferedReader bufr=new BufferedReader(new InputStreamReader(new FileInputStream("IMG5051A.jpg")));

  6. BufferedWriter bufo=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("test1_1.jpg")));

  7. String line=null;
  8. while((line=bufr.readLine())!=null)
  9. {
  10. bufo.write(line);
  11. bufo.newLine();
  12. }
  13. bufr.close();
  14. }
复制代码
这段代码能够运行,可是复制后的图片格式错误,无法打开,一直找不到问题,总觉得两段代码都有毛病,麻烦各位大神帮我优化下,请帮我指出我的错误,谢谢啦。



作者: msileandroid    时间: 2013-6-15 09:20
InputStreamReader 是字节流通向字符流的桥梁,用于操作字符用的,当然不行了;操作图片只能用字节读...
作者: 蚂蚁搬家    时间: 2013-6-15 10:40
第一段代码其实有一个read方法和write方法比这个效率高的:
byte[] buf = new byte[1024];
while((int len = bufis.read(buf)) != -1)
{
        bufos.write(buf, 0, len);
}

第二段代码里BufferedReader和BufferedWriter读取的时候是按字符编码的,是用来操作文本文件的,
readLine方法遇到换行符才返回读取的数据,否则一直阻塞,图片文件里怎么会有换行符,可能有两个字节数据编码后刚好是换行符,该方法就返回了数据,
然后你用write方法将其写出,然后又用newLine方法加了一个换行符,哥们儿,你操作的可是图片啊,怎么能加上换行符呢?
总之,BufferedReader和BufferedWriter是用来操作文本文件的,操作图片文件肯定出错!
作者: 萧萧北    时间: 2013-6-15 16:56
蚂蚁搬家 发表于 2013-6-15 10:40
第一段代码其实有一个read方法和write方法比这个效率高的:
byte[] buf = new byte[1024];
while((int len  ...

恩 ,这个换行符去掉也是错误的,所以我就加了试试,我只是觉得第一个方法效率太低。
请问一下,你用byte[] buf = new byte[1024];
是类似于缓存的功能,那此处用BufferedReader的意义何在呢?
一直不明白哎...
作者: 蚂蚁搬家    时间: 2013-6-15 17:34
萧萧北 发表于 2013-6-15 16:56
恩 ,这个换行符去掉也是错误的,所以我就加了试试,我只是觉得第一个方法效率太低。
请问一下,你用byt ...

这个应该是读取的时候先放进我们自己定义的缓冲区buf中,buf放满了,系统再把它放进缓冲流自己的缓冲区,它的具体大小就不知道了,可能是图片文件全读取完毕了,才开始写出,也可能是读取一部分之后,系统自己的缓冲区就满了,就开始写出了!
作者: 林森~Linson    时间: 2013-6-15 17:58
图片是二进制数据,必须用字节读取。而readLine()是用于读取一行文本数据的。是不可以用于读取二进制数据的。




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