关于BufferedInputStream以及缓冲区的一些疑问

xuhao3622603 2015-05-01 10:56:44
首先所有的输入流类中都有read(byte[] b) 这个方法。我想,只要用了这个方法,其实就是在用缓冲技术,
事实上看视频上老师演示BufferedInputStream的原理,也是用了read(byte[] b) 的方法,然后一个个从数组里面取出来,然后return出去。
那么BufferedInputStream有什么用?只是封装好一个数组?然后封装了一些方法?
不用它一样可以使用缓冲来读跟写。
例如下面的代码
当然我这个是有问题的,其实问题出在哪里我也不知道,求大神指导。


import java.io.*;
class abc
{
public static void main(String[] args) throws IOException
{
FileInputStream fis = new FileInputStream("d:\\02.jpg");
FileOutputStream fos = new FileOutputStream("d:\\00000000.jpg");

byte[] a = new byte[1024*4];
int ch;

while((ch=fis.read())!=-1)
{
fis.read(a);

fos.write(a);

}
}
}


那么问题就来了,我写的这个demo可以运行,也创建了文件并且传了数据,但是数据大小跟源文件差了1k,很显然哪里出错了。
但是的思路哪里错了,我实在想不出来,希望高手解答。
...全文
307 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
xuhao3622603 2015-05-02
  • 打赏
  • 举报
回复
引用 4 楼 rumlee 的回复:
另外你对缓冲的理解是错误的。
说一下我的理解,直接用read(),其实可以理解为,在内存中定义了一个byte文件,然后读一次只能存一个byte,接着写一次,写一个byte,这样必须读一次就写一次。 而定义缓冲区就是连着读n次,从硬盘中取出数据存到存入内存中的数组,然后从内存中的数组中取数据,连着写n次到硬盘上。虽然读写的总次数不变,但同一时间集中做一件事,从而提高效率。 如果我对缓存的想法不对,望指正。 谢谢。
xuhao3622603 2015-05-02
  • 打赏
  • 举报
回复
[
引用 2 楼 u011004037 的回复:
while那读了一个ch却并没有写进生成文件中,会让你的生成文件大概小千分之一。而那个读数组的又没有获取他读的长度,会让你复制出来的文件最后多出来那么一点点 而那个BufferedInputStream.得缓冲并不是说你可以一次读多个字节,而是说,他会有一个数组存储数据,你读数据时,他先读到数组里,然后再返回给你。当你读一个字节的时候,BufferedInputStream会直接从缓冲区拿一个字节给你,而InputStream会读一个字节给你。结果就是,一般而言,BufferedInputStream会比其他的类进行更少次数的IO操作,算是用空间换时间吧
你说的对,我早上想了一下修改了代码,然后复制文件没出错。 class abc { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("d:\\02.jpg"); FileOutputStream fos = new FileOutputStream("d:\\00000000.jpg"); byte[] a = new byte[1024*4]; int ch; while((ch=fis.read(a))!=-1) { fos.write(a,0,ch); } } } 但是我自己定义了数组,这不就是缓冲区? 说一下我的理解,直接用read(),其实可以理解为,在内存中定义了一个byte文件,然后读一次只能存一个byte,接着写一次,写一个byte,这样必须读一次就写一次。 而定义缓冲区就是连着读n次,从硬盘中取出数据存到存入内存中的数组,然后从内存中的数组中取数据,连着写n次到硬盘上。虽然读写的总次数不变,但同一时间集中做一件事,从而提高效率。 如果我对缓存的想法不对,望指正。 谢谢。
rumlee 2015-05-02
  • 打赏
  • 举报
回复
另外你对缓冲的理解是错误的。
rumlee 2015-05-02
  • 打赏
  • 举报
回复
你的问题是因为没有close导致的。比较标准的写法应该是


import java.io.*;
class abc
{
        public static void main(String[] args) throws IOException
        {
                FileInputStream fis = null;
                FileOutputStream fos = null;
try{
fis = new FileInputStream("d:\\02.jpg");
fos = new FileOutputStream("d:\\00000000.jpg");
                byte[] a = new byte[1024*4];
                int ch;

                while((ch=fis.read(a))!=-1)
                {
                        fos.write(a,0,ch);
                }
}catch(Exception e){
}finally{
  try{fis.close();}catch(Exception e){}
  try{fos.close();}catch(Exception e){}
}
        }
}

youzi05 2015-05-02
  • 打赏
  • 举报
回复
while那读了一个ch却并没有写进生成文件中,会让你的生成文件大概小千分之一。而那个读数组的又没有获取他读的长度,会让你复制出来的文件最后多出来那么一点点 而那个BufferedInputStream.得缓冲并不是说你可以一次读多个字节,而是说,他会有一个数组存储数据,你读数据时,他先读到数组里,然后再返回给你。当你读一个字节的时候,BufferedInputStream会直接从缓冲区拿一个字节给你,而InputStream会读一个字节给你。结果就是,一般而言,BufferedInputStream会比其他的类进行更少次数的IO操作,算是用空间换时间吧
JPF1024 2015-05-02
  • 打赏
  • 举报
回复
看下这个吧.. 更多可以看:http://www.07q.net/read/2268.html

import java.io.*;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;

/**
 * Created by puruidong on 2015/5/1.
 */


public class Entity {
    public static void main(String[] args) throws IOException {
         if (!Files.exists(Paths.get(".\\test.txt"))) Files.write(Paths.get(".\\test.txt"), new byte[0]);
        if (!Files.exists(Paths.get(".\\newtest.txt"))) Files.write(Paths.get(".\\newtest.txt"), new byte[0]);
        try (
                FileInputStream fis = new FileInputStream(".\\test.txt");
                FileOutputStream fos = new FileOutputStream(".\\newtest.txt");
        ) {
            if (Files.readAllLines(Paths.get(".\\test.txt")).size() == 0) {
                Files.write(Paths.get(".\\test.txt"), ("first write------" + System.currentTimeMillis()).getBytes());
            }else{
                //一行代码写入文件.
                Files.write(Paths.get(".\\test.txt"), ("more write------" + System.currentTimeMillis()).getBytes());
            }
            int result = 0;
            byte[] by = new byte[1024];
            while ((result = fis.read(by)) != -1) {
                fos.write((new String(by) + "---" + System.currentTimeMillis()).getBytes());
            }
            /*
             * java 8 一行代码读取文件内容
               *
               1)文件可能很大,可能会超出内存空间,使用前要做评估。
               2)要输出日志,记录为什么无法读取文件或者在阅读文件时遇到的任何错误。
               3)在把字节转换成字符时,应该指定字符编码。
               4)要处理文件不存在的情况。
               还要注意,如果读入的文件的编码是ANSI编码,那么上面的例子在读取文件内容时会报java.nio.charset.MalformedInputException: Input length = 1错误。
             *
             */
            Files.readAllLines(Paths.get(".\\newtest.txt"), Charset.defaultCharset()).forEach(t -> System.out.println("newtest.txt:" + t));
        }
    }
}


62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧