Come creare un nuovo java.io.File in memoria?


98

Come posso creare nuovo File(da java.io) in memoria, non sul disco rigido?

Sto usando il linguaggio Java. Non voglio salvare il file sul disco rigido.

Mi trovo di fronte a una cattiva API ( java.util.jar.JarFile). Si aspetta File filedi String filename. Non ho file (solo byte[]contenuto) e posso creare file temporanei, ma non è una bella soluzione. Devo convalidare il digest di un barattolo firmato.

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

Sarebbe apprezzato qualsiasi esempio di come ottenere manifest senza creare un file temporaneo.


8
Quindi vuoi solo byte in memoria?
Sotirios Delimanolis

6
Cosa stai cercando di fare con questo File?
Jon Skeet

5
A Fileper definizione si trova sul disco rigido.
Uwe Plonus

3
che senso ha creare un file se non lo vuoi nella memoria persistente?
Bhavik Shah

7
Wow, la mancanza di immaginazione su StackOverflow è sbalorditiva. Qualcuno potrebbe aver bisogno di un file in memoria semplice perché utilizza un'interfaccia che richiede un file. L'interfaccia avrebbe dovuto essere scritta per un InputStream, ma non lo era. Un file temporaneo sembra eccessivo, quindi un java.io.File in memoria sarebbe preferibile.
Novaterata

Risposte:


30

Per scrivere in un flusso, in memoria, utilizzare:

new ByteArrayOutputStream();

5
Questo non risponde alla domanda poiché ByteArrayOutputStream non è utilizzabile con un'interfaccia che richiede un oggetto file.
FableBlaze

1
@FableBlaze Bene, la risposta alla domanda quindi, è "non è possibile". Questa risposta cerca di essere pragmatica e di dire cosa potrebbe fare l'utente. La risposta di Andreas è chiaramente più completa e una risposta migliore (tentativo di una).
haraldK

"Non è possibile" sarebbe una risposta valida secondo me. Tuttavia penso che si possa menzionare anche un filesystem in memoria (menzionato nei commenti della risposta di Andreas), perché se per qualche motivo non puoi scrivere sul disco rigido, allora potrebbe essere un modo per aggirarlo.
FableBlaze

80

Come posso creare un nuovo file (da java.io) in memoria, non nel disco rigido?

Forse stai confondendo Filee Stream:

  • A Fileè una rappresentazione astratta di nomi di percorso di file e directory . Utilizzando un Fileoggetto, è possibile accedere ai metadati del file in un file system ed eseguire alcune operazioni sui file su questo file system, come eliminare o creare il file. Ma la Fileclasse non fornisce metodi per leggere e scrivere il contenuto del file.
  • Per leggere e scrivere da un file, stai usando un Streamoggetto, come FileInputStreamo FileOutputStream. Questi flussi possono essere creati da un Fileoggetto e quindi essere utilizzati per leggere e scrivere nel file.

È possibile creare un flusso basato su un buffer di byte che risiede in memoria , utilizzando a ByteArrayInputStreame a ByteArrayOutputStreamper leggere e scrivere su un buffer di byte in un modo simile a quello in cui si legge e si scrive da un file. L' bytearray contiene il contenuto del "File". FileAllora non hai bisogno di un oggetto.

Sia il flusso che File...il ByteArray...flusso ereditano rispettivamente da java.io.OutputStreame java.io.InputStream, in modo da poter utilizzare la superclasse comune per nascondere se si sta leggendo da un file o da un array di byte.


95
Non sono sicuro che questo sia ciò che voleva il poster originale, ma un esempio in cui un "File in memoria" sarebbe utile è quando si desidera riutilizzare una libreria esistente che ha bisogno di un java.io.File come parametro di input, ma tu desidera effettivamente utilizzare "file" archiviati in memoria. In tal caso, penso che una soluzione sarebbe quella di utilizzare Apache Commons VFS per istanziare un DefaultFileSystemManager e usarlo per creare un RamFileProvider. Avrei aggiunto questa come risposta corretta (più completa), ma sembra che questa domanda sia stata chiusa qualche tempo fa ...
Sorin Postelnicu

2
+1 Stavo cercando questo tipo di soluzione, per unit test come componente senza dover utilizzare un file effettivo
GClaramunt

3
Se non vuoi creare "un file effettivo", puoi provare a creare un file temporaneo. Vedi createTempFileper java.io.file. Questo file può essere impostato per l'eliminazione automatica all'uscita dallo unit test.
Andrew-Dufresne

2
Questo non risponde alla domanda. Come ha ben detto @SorinPostelnicu un "File" in memoria è qualcosa di simile a un Filesystem in memoria o giù di lì.
Felipe

1
Probabilmente riassume il caso d'uso dell'OP e un metodo prezioso per ridurre la latenza con costosi i / o del disco di sistema.
Eddie B

3

Potresti usare un filesystem in memoria, come Jimfs

Ecco un esempio di utilizzo dal loro file readme:

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);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.