1

我有一个复制二进制文件的功能

    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,它阻止使用存储在路径中具有“(”的位置的驱动程序...这是我面临的情况。

我会感谢你的帮助。

4

5 回答 5

1

或者有 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);
}
于 2012-06-14T15:28:18.947 回答
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();
    }
}

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

于 2012-06-14T15:20:19.620 回答
0

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

于 2012-06-14T15:39:07.957 回答
0

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

于 2012-06-14T15:29:39.410 回答
0

我会选择使用 Apache Commons IO 和他们的 FileUtils.copyFile() 例程。

用Java复制文件的标准简洁方法?

于 2012-06-14T15:23:30.663 回答