java 读/写构造

java read / write construction

谁能解释一下为什么这个结构不起作用:

while (fileInputStream.available()>0) {    
    fileOutputStream.write(fileInputStream.read());
}

这个效果很好:

while (fileInputStream.available()>0) {
    int data = fileInputStream.read();
    fileOutputStream.write(data);
}

对我来说它们是相同的,但是第一个不能正确写入数据(将写入文件长度/数据的一半)。

我的兴趣被激起了,我写了这个小测试:

public static void main(String[] args) throws IOException {

    FileInputStream fileInputStream = new FileInputStream("/home/nick/foo");
    FileOutputStream fileOutputStream = new FileOutputStream("/home/nick/bar");
    fileOutputStream.write(fileInputStream.read());

    fileOutputStream.flush();
    fileOutputStream.close();
    fileInputStream.close();
}

它按预期工作 - 从 /home/nick/foo 读取一个字节并将其写入 /home/nick/bar

编辑:

更新程序:

public static void main(String[] args) throws IOException {

    FileInputStream fileInputStream = new FileInputStream("/home/nick/foo");
    FileOutputStream fileOutputStream = new FileOutputStream("/home/nick/bar");
    while (fileInputStream.available()>0) {    
        fileOutputStream.write(fileInputStream.read());
    }

    fileOutputStream.flush();
    fileOutputStream.close();
    fileInputStream.close();
}

复制了整个文件。 (注意 - 我不建议一次复制一个字节的文件,使用 Buffered I/O 类 来复制整个块)

你有没有忘记 flush()close() 到 OutputStream?

看起来你的 while 循环正在做 估计 的事情并在这里和那里跳过。

public int available() throws IOException {
        return 0;
    }

Returns an estimate of the number of remaining bytes that can be read (or skipped over) from this input stream without blocking by the next invocation of a method for this input stream. The next invocation might be the same thread or another thread. A single read or skip of this many bytes will not block, but may read or skip fewer bytes. In some cases, a non-blocking read (or skip) may appear to be blocked when it is merely slow, for example when reading large files over slow networks.

See here

您使用的 available() 方法不正确。该方法用于确定在不阻塞线程的情况下有多少字节可供读取。

Good Stack Overflow Question about available()

JavaDoc on available()


检查是否到达EOF的正确方法是查看read()方法是否返回-1:

int data = fileInputStream.read();
while (data != -1) {
    fileOutputStream.write(data);
    data = fileInputStream.read();
}

如果您尝试读取大量数据,此方法可能会非常慢。您可以使用 read(byte[] b, int off, int len) 方法读取更多字节来加快速度。该循环看起来与另一个循环非常相似。

byte [] buffer = new byte[1024]; // 1kb buffer
int numBytesRead = fileInputStream.read(buffer);
while (numBytesRead != -1) {
    fileOutputStream.write(buffer, 0, numBytesRead);
    numBytesRead = fileInputStream.read(buffer);
}