java读/写结构

java读/写结构,java,io,fileinputstream,fileoutputstream,Java,Io,Fileinputstream,Fileoutputstream,有人能解释一下为什么这个建筑不起作用吗 while (fileInputStream.available()>0) { fileOutputStream.write(fileInputStream.read()); } 这个很好用: while (fileInputStream.available()>0) { int data = fileInputStream.read(); fileOutputStream.write(data); } 对我

有人能解释一下为什么这个建筑不起作用吗

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();
}
复制了整个文件。(注意-我不建议一次复制一个字节的文件,使用缓冲I/O类复制整个块)


您是否碰巧忘记了使用
flush()
close()
来输出流?

似乎您的while循环正在做估计的事情,并在这里和那里跳过

public int available() throws IOException {
        return 0;
    }
返回可读取的剩余字节数的估计值 (或跳过)此输入流,而不被下一个 为此输入流调用方法。下一次调用 可能是同一个线程或另一个线程。一次读取或跳过 这许多字节不会阻塞,但可以读取或跳过更少的字节。在里面 在某些情况下,非阻塞读取(或跳过)可能会被阻塞 当它只是很慢时,例如,当以过慢的速度读取大文件时 网络


您错误地使用了
available()
方法。该方法用于确定在不阻塞线程的情况下可以读取多少字节


检查是否达到EOF的正确方法是查看该方法是否返回
-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);
}

你有没有一个循环没有给我们看?因为read()只读取一段数据。一般来说,该段由容器确定,int为32位,其中as fileoutputstream接受不同数量的bytest,它们是相同的。请注意,这不会将输入流的全部内容复制到输出流。它将只读取和写入一个字节。如果要使其工作,应输入字节缓冲区,不要使用
fileInputStream.available()
进行循环读取。它不会做你认为它会做的事。它只是告诉您有多少字节是可用的,而不需要阻塞,这不一定是文件的长度。这可能会影响你的结果,因为没有变量的问题。我更新了第一个帖子,认为在这个问题上循环不会有什么影响。有循环,也有区别我检查了它:是的,它复制了文件,一些数据可以从中读取,但内容确实损坏了。我关闭了它,但没有刷新。它与flush()一起工作。你能解释为什么吗?根据javadoc,“OutputStream的flush方法什么都不做。”“你能解释一下为什么吗?”:诚实的回答:不,谢谢,在我看来,这就是这里发生的事情。