从InputStream读取并写入OutputStream

时间:2012-02-14 20:13:54

标签: java

这应该很简单,我搜索了谷歌,但没有看到有人提到我注意到的问题。我见过的所有东西都是基本相同的东西。像这样:

byte [] buffer = new byte[256];
int bytesRead = 0;
while((bytesRead = input.read(buffer)) != -1)
{
    output.write(buffer, 0, bytesRead);
}

我知道当达到EOF时,read()会返回-1,但是如果文件小于缓冲区或者大小相同怎么办?例如,正在读入一个200字节的文件。我假设它读取了200个字节,但返回-1。这与javadocs匹配,但它也意味着永远不会调用write()。我本来希望实际告诉我它读取200个字节,并在下一次迭代时返回-1。

我如何解决这个“问题”?

5 个答案:

答案 0 :(得分:12)

仅供参考,GuavaByteStreams.copy(InputStream, OutputStream),您可以直接使用,也可以查看它是如何解决此问题的。

答案 1 :(得分:7)

您的代码

byte [] buffer = new byte[256];
int bytesRead = 0;
while((bytesRead = input.read(buffer)) != -1) {
    output.write(buffer, 0, bytesRead);
}

工作正常。

例如,假设您有一个包含300个字符(600字节)的文件:

步骤1.缓冲区将读取256个字节并将其重写为输出; 344离开EOF

步骤2.缓冲区将读取256个字节并将其重写为输出; 88离开EOF

步骤3.缓冲区将读取88个字节(byteRead == 88)并将其重写为输出; EOF离开了

步骤4. EOF(input.read(buffer)返回-1

...编辑

以上步骤不是理论。我通过使用以下代码重写实际文件内容来获得此信息:

static void rewrite() throws IOException {
    InputStream input = new FileInputStream("file1.txt");
    OutputStream output = new FileOutputStream("file2.txt");
    byte[] buffer = new byte[256];
    int bytesRead = 0;
    while ((bytesRead = input.read(buffer)) != -1) {
        System.out.println(bytesRead);
        output.write(buffer, 0, bytesRead);
    }
}

您的配置可能还有其他问题。

答案 2 :(得分:1)

至少需要调用read()才能检测到非空流的结束。一个读取内容,然后另一个返回EOF。

例如,如果缓冲区为256字节,文件只有200字节,则对read(byte[])的调用将返回200(或一系列调用结果将总和为200),然后后续调用将返回-1表示EOF。

你是如何解释InputStream的Javadoc并不完全清楚的,但它清楚地表明它返回读取的字节数,并且当没有时返回-1 更多数据需要阅读。

  

如果b的长度为零,则不读取任何字节,返回0;   否则,尝试读取至少一个字节。如果没有字节   是可用的,因为流位于文件的末尾,即值   返回-1;否则,至少读取一个字节并存储到b。

此外:

  

返回:读入缓冲区的总字节数,或-1 [if]   因为已经到达了流的末尾,所以没有更多的数据。

答案 3 :(得分:0)

read()返回读取完整文件之前读取的字节数。一旦不再能读取字节,它只返回-1。

来自the java documentation (1.4)

  

如果没有字节可用,因为流位于文件末尾,则返回值-1;   否则,至少读取一个字节并存储到b中。

它实际上做了你想要它做的事情。它读取200个字节(或文件中剩余的任何内容,并且小于您提供的缓冲区),并在下一次迭代时返回-1。

答案 4 :(得分:0)

  

我假设它读取了200个字节,但返回-1

没有。它读取200个字节并返回200.这在Javadoc中非常清楚,您也可以轻松地尝试它。