excepción durante la copia de archivos en Java

Tengo una función que copia el archivo binario

    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();
}

y la segunda función

    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;
    }
}

La segunda función se ejecuta para cada controlador encontrado en el sistema. El archivo del controlador se copia y estoy tratando de inicializar PKCS11 con ese controlador. Si la inicialización falla, voy al siguiente controlador, lo copio a la ubicación tmp y así sucesivamente.

La inicialización está en el bloque try / catch Después del primer fallo, ya no puedo copiar el siguiente controlador a la ubicación estándar.

Me sale la excepcion

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)

¿Cómo puedo evitar la excepción y copiar de manera segura el archivo del controlador?

Para aquellos curiosos por qué estoy tratando de copiar el controlador ... PKCS11 tiene un ERROR desagradable, lo que evita el uso de controladores almacenados en la ubicación que tiene "(" en la ruta ... y este es un caso que estoy enfrentando.

Apreciaré su ayuda.

Respuesta 1

Si otro archivo usa el archivo y está bloqueado, no hay soluciones genéricas para poder acceder a él. Su mejor oportunidad es usar FileLock, pero depende de la plataforma, lea la documentación, está escrito que los resultados son "informativos", así que tenga cuidado. También puede echar un vistazo a la clase ReentrantReadWriteLock .

Respuesta: 2

Me gustaría mover el bloque try-catch al copyFilemétodo. De esa forma, puede manejar correctamente el cierre de la InputStreams (lo que probablemente esté causando que la JVM se aferre al controlador de archivo). Algo como esto:

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();
    }
}

Luego puede eliminar el try-catch del copyDriverToSafeLocationmétodo.

Respuesta: 3

O está el Java 7 Way:

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);
      }
    }
  }
}

Editar: Y la forma 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);
}
Respuesta: 4

Elegiría ir con Apache Commons IO y sus rutinas FileUtils.copyFile ().

¿Forma concisa estándar para copiar un archivo en Java?

Respuesta: 5

Tengo una Vista en mi ConstraintLayout que está posicionada en XML. Luego quiero cambiar esta vista a otra vista al hacer clic en el botón. Tengo el script para hacerlo y funciona bien, pero aparece la nueva Vista ...

Esto me estaba causando un gran dolor de cabeza, así que pensé en publicar la solución fácil. Mi problema era que cuando usaba la API de Java para S3 de Amazon, solo podía descargar 50 objetos antes de que misteriosamente ...

En mi aplicación obtengo contenido JSON como InputStream. Dependiendo de si se trata de un solo JSONObject o un JSONArray de los que quiero realizar diferentes acciones. ¿Cómo puedo diferenciar, usando Jackson, si es un ...

Necesito programar algunos trabajos periódicos y he encontrado un obstáculo con Quartz. Por ejemplo: no creo que esto sea posible con Quartz (con una sola expresión / trabajo): ejecute un trabajo todos los días entre ...