Java 如何使用二进制流写出文件复制的百分比?

Java 如何使用二进制流写出文件复制的百分比?,java,Java,我想在使用二进制流复制文件时显示百分比,但我不知道怎么做 下面是我的代码 public static void binaryStream() throws IOException { try { FileInputStream inputStream = new FileInputStream(new File("Untitled.png")); FileOutputStream outputStream = new FileOutputStream(

我想在使用二进制流复制文件时显示百分比,但我不知道怎么做

下面是我的代码

public static void binaryStream() throws IOException {

    try {

        FileInputStream inputStream = new FileInputStream(new File("Untitled.png"));
        FileOutputStream outputStream = new FileOutputStream(new File("Untitled-copied.png"));

        int data;
        while ((data = inputStream.read()) >= 0) {
            outputStream.write(data);
        }

        outputStream.write(data);

        inputStream.close();
        outputStream.close();

    } catch (FileNotFoundException e) {
        System.out.println("Error");
    } catch (IOException e) {
        System.out.println("Error");
    }

}

如何像评论中提到的其他人那样做的示例

import java.io.*;

public class BinaryStream {
    public static void binaryStream(String file1, String file2) throws Exception
    {
      File sourceFile = new File(file1);
      try(
        FileInputStream inputStream = new FileInputStream(sourceFile); 
        FileOutputStream outputStream = new FileOutputStream(new File(file2))
      ) {
        long lenOfFile = sourceFile.length();

        long currentBytesWritten = 0;
        int data;
        while ((data = inputStream.read()) != -1) {
          outputStream.write(data);
          currentBytesWritten += 1;
          System.out.printf("%2.2f%%%n",
              100*((double)currentBytesWritten)/((double)lenOfFile));
        }
      }
   }

   public static void main(String args[]) throws Exception {
      binaryStream("Untitled.png", "Untitled-copied.png");
   }
}
请注意,我做了一些更改:

  • 删除了错误写入额外内容的额外outputStream.write()调用
  • 使用try-with-resources习惯用法关闭您打开的流,即使在出现异常时也是如此
  • 抛出异常而不是捕获异常,因为如果无法处理它们,就不应该捕获异常
  • -1
    比较,因为这是文件结束(流结束)的记录值
  • 在我的计算机上,输出如下:

    0,06%
    // removed data
    99,89%
    99,94%
    100,00%
    
    14,69%
    29,37%
    44,06%
    58,75%
    73,44%
    88,12%
    100,00%
    
    还要注意,这段代码在写入每个字节后都会打印一些内容,因此效率非常低。你可能不想经常这样做。在这一点上,您一次读写一个字节,这也是非常低效的-您可能希望使用分块读。例如,使用256字节数组:

    import java.io.*;
    
    public class BinaryStream {
      public static void binaryStream(String file1, String file2) throws Exception {
        File sourceFile = new File(file1);
        try(
          FileInputStream inputStream = new FileInputStream(sourceFile);
          FileOutputStream outputStream = new FileOutputStream(new File(file2))
        ) {
          long lenOfFile = sourceFile.length();
          long bytesWritten = 0;
          int amountOfBytesRead;
          byte[] bytes = new byte[256];
    
          while ((amountOfBytesRead = inputStream.read(bytes)) != -1) {
            outputStream.write(bytes, 0, amountOfBytesRead);
            bytesWritten += amountOfBytesRead;
            System.out.printf("%2.2f%%%n",
                100*((double)bytesWritten)/((double)lenOfFile));
          }
        }
      }
    
      public static void main(String args[]) throws Exception {
        binaryStream("Untitled.png", "Untitled-copied.png");
      }
    }
    
    我的计算机上的输出:

    0,06%
    // removed data
    99,89%
    99,94%
    100,00%
    
    14,69%
    29,37%
    44,06%
    58,75%
    73,44%
    88,12%
    100,00%
    

    请注意,在第一个示例中,.read()的返回值实际上是读取的字节,而在第二个示例中,.read()的返回值是读取的字节数和进入字节数组的实际字节数。

    您需要计算/获取要复制的文件的大小,然后通过计算已读取和写入的字节数来跟踪复制进度,并将该字节数除以大小。首先获取文件大小,稍后,使用缓冲区大小进行写入,由此可以得到百分比的除法值。您应该看看您可以与AtomicInteger组合并轮询AtomicInteger这是一个很好的解决方案,除了一件事:复制文件和进度条值计算应该在不同的线程中。对于这种双重强制转换表达式,您有什么特殊的教育目的吗?我相信一个简单的
    100.0*bytesWrite/Lenofile
    (然后它显然是一个十进制-更准确地说,
    double
    -计算,并且没有神秘的100d或100f符号)@tevemadar我想这是一个偏好问题,我喜欢这样显式地进行必要的转换。对于奇怪的事件顺序,我感到抱歉。最初,当我添加注释时,我修改了try with resource结构(它们在一个
    try
    中正确地处理多个资源,请参见第三个代码段:),同时修复了缩进和某个“不规则”的左括号。然后我把它提交审查。然后我注意到第一个块中的水平滚动条,并考虑添加换行符,但我取消了,显然取消了整个编辑,而不仅仅是换行符。