IO 图像读取和写入:写入字节数组与使用 write(int b) 方法一次写入字节不同吗?

0 java io

我是 java IO 的新手,我尝试简单地复制并粘贴照片。我使用了两种方法来实现这一目标,第一种方法效果很好,但第二种方法则不然。

这段代码运行良好。

try (BufferedInputStream input = new BufferedInputStream(new FileInputStream("photoOriginal.jpg"));
             BufferedOutputStream output =new BufferedOutputStream(new FileOutputStream("photoCopy.jpg"))) {
            try {
                int n =0;
                byte[] buf = new byte[4092];
                while((n = input.read(buf))!=-1){
                    output. Write(buf,0,n);
                    output.flush();
                }
} 
  } catch (IOException e) {
            System.out.println("Error: " + e.getMessage());
            e.printStackTrace();
   }
Run Code Online (Sandbox Code Playgroud)

但第二个不起作用,程序完成后,我发现副本文件的大小与原始文件的大小相同,但在尝试打开它时,它显示格式不支持的错误。

try (BufferedInputStream input = new BufferedInputStream(new FileInputStream("photoOriginal.jpg"));
             BufferedOutputStream output =new BufferedOutputStream(new FileOutputStream("photoCopy.jpg"))) {
            try {
                int byteRead = input.read();
                while (byteRead != -1) {
                    byteRead = input.read();
                    output.write(byteRead);
                    output.flush();
                }

                }
} 
  } catch (IOException e) {
            System.out.println("Error: " + e.getMessage());
            e.printStackTrace();
   }
Run Code Online (Sandbox Code Playgroud)

我不明白问题出在哪里,似乎两个样本都在做同样的事情。读取和写入字节数组与一次读取和写入单个字节是否不同?使用write(int b)方法将 int 写入 Stream 不是只会写入最低 8 位,反之亦然,如文档中所述?

write
public Abstract void write(int b)
throws IOException
将指定字节写入此输出流。写入的一般约定是将一个字节写入输出流。要写入的字节是参数 b 的低 8 位。b 的 24 个高位被忽略。

希望有人能帮忙。

Jon*_*eet 6

您没有写出第一个字节 - 您调用input.read(),检查它是否不是 -1,然后input.read()再次调用:

// Broken code
int byteRead = input.read();
while (byteRead != -1) {
    byteRead = input.read();
    output.write(byteRead);
    output.flush();
}
Run Code Online (Sandbox Code Playgroud)

如果您将下一个input.read()调用移至循环末尾,它将起作用:

// Working code with duplication
int byteRead = input.read();
while (byteRead != -1) {
    output.write(byteRead);
    output.flush();
    byteRead = input.read();
}
Run Code Online (Sandbox Code Playgroud)

或者您可以结合“读取和测试”以避免重复:

// Working code without duplication
int byteRead;
while ((byteRead = input.read()) != -1) {
    output.write(byteRead);
    output.flush();
}
Run Code Online (Sandbox Code Playgroud)

然而,这仍然是一种非常低效的复制流的方法。按照您的第一个代码一次复制一个块会更有效(或者transferTo如果您使用的是 Java 9 或更高版本,则使用内置方法,如 rostamn79 指出的那样)。