【问题标题】:exception during file copy in JavaJava中文件复制期间的异常
【发布时间】:2012-06-17 15:58:16
【问题描述】:

我有一个复制二进制文件的函数

    public static void copyFile(String Src, String Dst) throws FileNotFoundException, IOException {
    File f1 = new File(Src);
    File f2 = new File(Dst);
    FileInputStream in = new FileInputStream(f1);

    FileOutputStream out = new FileOutputStream(f2);

    byte[] buf = new byte[1024];
    int len;
    while ((len = in.read(buf)) > 0) {
        out.write(buf, 0, len);
    }
    in.close();
    out.close();
}

还有第二个功能

    private String copyDriverToSafeLocation(String driverPath) {
    String safeDir = System.getProperty("user.home");
    String safeLocation = safeDir + "\\my_pkcs11tmp.dll";
    try {
        Utils.copyFile(driverPath, safeLocation);
        return safeLocation;
    } catch (Exception ex) {
        System.out.println("Exception occured while copying driver: " + ex);
        return null;
    }
}

为系统中找到的每个驱动程序运行第二个函数。 驱动程序文件被复制,我正在尝试使用该驱动程序初始化 PKCS11。 如果初始化失败,我会转到下一个驱动程序,我将其复制到 tmp 位置等等。

初始化在 try/catch 块中 第一次失败后,我无法再将下一个驱动程序复制到标准位置。

我得到了异常

Exception occured while copying driver: java.io.FileNotFoundException: C:\Users\Norbert\my_pkcs11tmp.dll (The process cannot access the file because it is being used by another process)

如何避免异常并安全复制驱动文件?

对于那些好奇我为什么要复制驱动程序的人... PKCS11 有令人讨厌的 BUG,这会阻止使用存储在路径中具有“(”的位置的驱动程序...这是我面临的情况。

感谢您的帮助。

【问题讨论】:

  • 感谢大家的cmets。我不想使用像 apache 这样的额外库,因为最后这段代码将由 applet 运行。我尝试了所有其余的,但似乎 dest 文件正在使用中。我什至尝试了讨厌的解决方案并枚举了驱动程序(并将数字添加到 dst 文件名),但是当我通过 applet 运行它时,dst 文件正在使用中,当 applet 运行不止一次时。

标签: java file-copying


【解决方案1】:

我会将 try-catch 块移到 copyFile 方法中。这样您就可以正确处理关闭InputStreams(这可能导致JVM 保留文件句柄)。像这样的:

public static void copyFile(String Src, String Dst) {
    try {
        File f1 = new File(Src);
        File f2 = new File(Dst);
        FileInputStream in = new FileInputStream(f1);

        FileOutputStream out = new FileOutputStream(f2);

        byte[] buf = new byte[1024];
        int len;
        while ((len = in.read(buf)) > 0) {
            out.write(buf, 0, len);
        }
    }
    catch(Exception e) {
        System.out.println("Exception occured while copying driver: " + ex);
    }
    finally {
        in.close();
        out.close();
    }
}

然后您可以从copyDriverToSafeLocation 方法中删除try-catch。

【讨论】:

    【解决方案2】:

    我会选择使用 Apache Commons IO 及其 FileUtils.copyFile() 例程。

    Standard concise way to copy a file in Java?

    【讨论】:

      【解决方案3】:

      或者还有 Java 7 方式:

      public static void copyFile(String src, String dst) throws FileNotFoundException, IOException {
        try (FileInputStream in = new FileInputStream(new File(src))) {
          try (FileOutputStream out = new FileOutputStream(new File(dst))) {
            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) > 0) {
              out.write(buf, 0, len);
            }
          }
        }
      }
      

      编辑:还有 Java 7 NIO 方式。

      public static void copyFile(String src, String dst) throws FileNotFoundException, IOException {
        copyFile(new File(src), new File(dst));
      }
      
      public static void copyFile(File src, File dst) throws FileNotFoundException, IOException {
        try (FileInputStream in = new FileInputStream(src)) {
          try (FileOutputStream out = new FileOutputStream(dst)) {
            copyFile(in, out);
          }
        }
      }
      
      public static void copyFile(FileInputStream in, FileOutputStream out) throws IOException {
        FileChannel cin = in.getChannel();
        FileChannel cout = out.getChannel();
        cin.transferTo(0, cin.size(), cout);
      }
      

      【讨论】:

      • 您不会关闭()您的输入或输出流。
      • 它们不需要在 java 7 中显式关闭。当 try 块结束时它们会自动关闭。
      【解决方案4】:

      我不确定为什么一个文件的问题会阻止复制一个不同的文件。但是,发生异常时不关闭文件肯定会导致问题。使用 try...finally 确保在打开的每个文件上都调用 close。

      【讨论】:

        【解决方案5】:

        如果文件被其他进程使用并被锁定,则没有通用的解决方案可以访问它。你最好的机会是使用FileLock,但它依赖于平台,阅读文档,它写的结果是“建议的”,所以要小心。你也可以看看ReentrantReadWriteLock class

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-12-13
          • 1970-01-01
          • 2019-08-29
          • 1970-01-01
          • 1970-01-01
          • 2013-12-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多