¿Cómo crear un nuevo archivo java.io.File en la memoria?

98

¿Cómo puedo crear nuevos File(desde java.io) en la memoria, no en el disco duro?

Estoy usando el lenguaje Java. No quiero guardar el archivo en el disco duro.

Me enfrento a una API incorrecta ( java.util.jar.JarFile). Se espera File filede String filename. No tengo ningún archivo (solo byte[]contenido) y puedo crear un archivo temporal, pero no es una solución hermosa. Necesito validar el resumen de un frasco firmado.

byte[] content = getContent();
File tempFile = File.createTempFile("tmp", ".tmp");
FileOutputStream fos = new FileOutputStream(tempFile);
fos.write(archiveContent);
JarFile jarFile = new JarFile(tempFile);
Manifest manifest = jarFile.getManifest();

Se agradecería cualquier ejemplo de cómo lograr obtener un manifiesto sin crear un archivo temporal.

ggorlen
fuente
8
¿Entonces solo quieres bytes en la memoria?
Sotirios Delimanolis
6
¿Qué intentas hacer con esto File?
Jon Skeet
5
A Filepor definición está en el disco duro.
Uwe Plonus
3
¿Cuál es el punto de crear un archivo si no lo quiere en la memoria persistente?
Bhavik Shah
7
Vaya, la falta de imaginación en StackOverflow es asombrosa. Alguien puede necesitar un archivo en memoria simple porque está usando una interfaz que requiere un archivo. La interfaz debería haberse escrito para un InputStream, pero no fue así. Un archivo temporal parece exagerado, por lo que sería preferible un archivo java.io.File en memoria.
Novaterata

Respuestas:

30

Para escribir en una secuencia, en la memoria, use:

new ByteArrayOutputStream();
haraldK
fuente
5
Esto no responde a la pregunta, ya que ByteArrayOutputStream no se puede utilizar con una interfaz que requiera un objeto de archivo.
FableBlaze
1
@FableBlaze Bueno, entonces la respuesta a la pregunta es "no es posible". Esta respuesta intenta ser pragmática y decir qué podría hacer el usuario en su lugar. La respuesta de Andreas es claramente más completa y una mejor (intento de) respuesta.
haraldK
"No es posible" sería una respuesta válida en mi opinión. Sin embargo, creo que un sistema de archivos en memoria (mencionado en los comentarios de la respuesta de Andreas) también podría mencionarse, porque si por alguna razón no puede escribir en el disco duro, entonces esa podría ser una forma de evitarlo.
FableBlaze
80

¿Cómo puedo crear un nuevo archivo (desde java.io) en la memoria, no en el disco duro?

Tal vez estés confundido Filey Stream:

  • A Filees una representación abstracta de nombres de rutas de archivos y directorios . Con un Fileobjeto, puede acceder a los metadatos del archivo en un sistema de archivos y realizar algunas operaciones en los archivos de este sistema de archivos, como eliminar o crear el archivo. Pero la Fileclase no proporciona métodos para leer y escribir el contenido del archivo.
  • Para leer y escribir desde un archivo, está utilizando un Streamobjeto, como FileInputStreamo FileOutputStream. Estos flujos se pueden crear a partir de un Fileobjeto y luego se pueden usar para leer y escribir en el archivo.

Puede crear una secuencia basada en un búfer de bytes que reside en la memoria , utilizando ay ByteArrayInputStreama ByteArrayOutputStreampara leer y escribir en un búfer de bytes de la misma manera que lee y escribe desde un archivo. La bytematriz contiene el contenido del "Archivo". FileEntonces no necesitas un objeto.

Tanto el File...y las ByteArray...corrientes heredan de java.io.OutputStreamy java.io.InputStream, respectivamente, por lo que puede utilizar la superclase común para ocultar si se está leyendo desde un archivo o de una matriz de bytes.

Andreas Fester
fuente
95
No estoy seguro de si esto es lo que quería el póster original, pero un ejemplo cuando un "Archivo en memoria" sería útil es cuando desea reutilizar una biblioteca existente que necesita un java.io.File como parámetro de entrada, pero usted realmente desea utilizar "archivos" almacenados en la memoria. En ese caso, creo que una solución sería usar Apache Commons VFS para crear una instancia de DefaultFileSystemManager y usarlo para crear un RamFileProvider. Hubiera agregado esto como una respuesta adecuada (más completa), pero parece que esta pregunta se cerró hace algún tiempo ...
Sorin Postelnicu
2
+1 Estaba buscando este tipo de solución, para probar la unidad del componente sin tener que usar un archivo real
GClaramunt
3
Si no desea crear "un archivo real", puede intentar crear un archivo temporal. Ver createTempFilepara java.io.file. Este archivo se puede configurar para que se borre automáticamente cuando finalice la prueba unitaria.
Andrew-Dufresne
2
Esto no responde a la pregunta. Como bien dijo @SorinPostelnicu, un "archivo" en la memoria es algo así como un sistema de archivos en la memoria.
Felipe
1
Probablemente resume el caso de uso del OP y un método valioso para reducir la latencia con una costosa E / S del disco del sistema.
Eddie B
3

Podría usar un sistema de archivos en memoria, como Jimfs

Aquí hay un ejemplo de uso de su archivo Léame:

FileSystem fs = Jimfs.newFileSystem(Configuration.unix());
Path foo = fs.getPath("/foo");
Files.createDirectory(foo);

Path hello = foo.resolve("hello.txt"); // /foo/hello.txt
Files.write(hello, ImmutableList.of("hello world"), StandardCharsets.UTF_8);
Tedward
fuente