ignoring example ejemplos appending and java process runtime.exec io-redirection

java - example - La redirección con Runtime.getRuntime(). Exec() no funciona



nohup ignoring input and appending output to nohup out (2)

Necesito ejecutar un comando desde un programa. La línea de comandos está bien, lo intenté en la terminal, pero no funciona en el programa.

Agrego una copia de mi código:

File dir = new File("videos"); String[] children = dir.list(); if (children == null) { // Either dir does not exist or is not a directory System.out.print("No existe el directorio/n"); } else { for (int i=0; i<children.length; i++) { // Get filename of file or directory String filename = children[i]; //Recojo el momento exacto System.out.print("/n" +filename); Process p = Runtime.getRuntime().exec("exiftool -a -u -g1 -j videos/"+filename+">metadata/"+filename+".json"); }

El programa debe obtener el nombre de todos los archivos en una carpeta (nombre de archivo) y extraer los metadatos de estos videos, escribiéndolos en un archivo .json en la carpeta ''metadatos''.
¿Dónde está el problema?


El problema es que el carácter de redirección ( > ) es una construcción basada en shell, no un ejecutable. Entonces, a menos que ejecutes este comando a través de algo como bash (que no eres), se interpretará como un argumento de carácter literal para tu invocación exiftool .

Si desea que esto funcione, tiene dos opciones:

  1. Consigue bash para hacerlo: pasa toda la línea de comando como argumento a bash -c . Esto podría necesitar un escape heroico, aunque en tu caso se ve bien.
  2. Haz la redirección tú mismo dentro de Java. Invoque el comando sin la salida redirigida (es decir, todo hasta el signo > ), luego lea desde el tren de salida del proceso y escriba todos los contenidos en el archivo apropiado.

El último enfoque parece ser más trabajoso inicialmente, pero cuando se considera que siempre se debe leer la salida de un proceso (ver los javadocs , segundo párrafo), en realidad es muy poco más que eso. Simplemente está enviando esta salida a un archivo en lugar de tirarlo.


Si tienes Java 7, es más fácil:

Process p = new ProcessBuilder() .command("exiftool", "-a", "-u", "-g1", "-j", new File("videos", filename).toString()) .redirectOutput(new File("metadata", filename + ".json")) .start();

Esto cae bajo la "solución 2", pero la biblioteca de tiempo de ejecución se ocupa de la repetición.