使用BufferInputStream下载无法正常工作

时间:2011-10-11 03:43:55

标签: java io downloading bufferedinputstream

以下代码无法下载文件(btw clen是文件的长度):

    int pos = 0, total_pos = 0;
    byte[] buffer = new byte[BUFFER_SIZE];
            while (pos != -1) {
                pos = in.read(buffer, 0, BUFFER_SIZE);
                total_pos += pos;
                out.write(buffer);
                setProgress((int) (total_pos * 100 / clen));
            }

...但这很好用:

    int buf;
    while ((buf = in.read()) != -1)
        out.write(buf);

我想知道为什么,即使第二个代码段工作得很快。在那个注意事项中,是否有任何特殊的理由使用byte []缓冲区(因为它似乎没有更快,而BufferedInputStream已经使用了它自己的缓冲区......?)

2 个答案:

答案 0 :(得分:2)

以下是应该如何做的。

public static void copyStream(InputStream is, OutputStream os)
    {
        byte[] buff = new byte[4096];
        int count;
        try {
            while((count = is.read(buff)) > 0)
                os.write(buff, 0, count);

        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if(is != null)
                    is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(os != null)
                    os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

答案 1 :(得分:0)

我尝试对代码进行必要的最小更改以使其正常工作。 st0le很好地提供了一个更简洁的流复制版本。

public class Test {
    private static final String FORMAT = "UTF-8";
    private static final int BUFFER_SIZE = 10; // for demonstration purposes.
    public static void main(String[] args) throws Exception {
        String string = "This is a test of the public broadcast system";
        int clen = string.length();
        ByteArrayInputStream in = new ByteArrayInputStream(string.getBytes(FORMAT));
        OutputStream out = System.out;
        int pos = 0, total_pos = 0;
        byte[] buffer = new byte[BUFFER_SIZE];
        while (pos != -1) {
            pos = in.read(buffer, 0, BUFFER_SIZE);
            if (pos > 0) {
                total_pos += pos;
                out.write(buffer, 0, pos);
                setProgress((int) (total_pos * 100 / clen));
            }
        }
    }
    private static void setProgress(int i) {
    }
}
  • 当您将缓冲区写入输出流时,您忽略了 pos 的值。
  • 您还需要重新检查 pos 的值,因为它可能刚刚读取了文件的末尾。在这种情况下,您不会增加 total_pos (尽管您可能会报告您已完成100%)
  • 请务必使用close()s在适当的位置正确处理资源。

CNC中 使用数组作为缓冲区的一般原因是输出流可以使用更大的数据集执行尽可能多的工作。

写入控制台可能没有太大的延迟,但它可能是写入的网络套接字或其他一些慢速设备。正如JavaDoc所述

  

OutputStream的write方法在每个要写出的字节上调用一个参数的write方法。鼓励子类重写此方法并提供更有效的实现。

使用缓冲输入/输出流时使用它的好处可能很小。