Wie erstelle ich eine neue java.io.File im Speicher?

97

Wie kann ich neue erstellen File(ausjava.io ) im Speicher , nicht auf der Festplatte?

Ich benutze die Java-Sprache. Ich möchte die Datei nicht auf der Festplatte speichern.

Ich bin mit einer schlechten API ( java.util.jar.JarFile) konfrontiert . Es erwartet File filevon String filename. Ich habe keine Datei (nur byte[]Inhalt) und kann temporäre Dateien erstellen, aber es ist keine schöne Lösung. Ich muss den Digest eines signierten Glases validieren.

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

Alle Beispiele, wie Sie erreichen können, ohne eine temporäre Datei zu erstellen, sind willkommen.

ggorlen
quelle
8
Sie möchten also nur Bytes im Speicher?
Sotirios Delimanolis
6
Was versuchen Sie zu tun mit diesem File?
Jon Skeet
5
A befindet sich Fileper Definition auf der Festplatte.
Uwe Plonus
3
Was bringt es, eine Datei zu erstellen, wenn Sie sie nicht im dauerhaften Speicher haben möchten?
Bhavik Shah
6
Wow, der Mangel an Vorstellungskraft bei StackOverflow ist erstaunlich. Jemand benötigt möglicherweise eine einfache In-Memory-Datei, da er eine Schnittstelle verwendet, für die eine Datei erforderlich ist. Die Schnittstelle sollte für einen InputStream geschrieben worden sein, war es aber nicht. Eine temporäre Datei scheint einfach übertrieben zu sein, daher wäre eine speicherinterne java.io.File vorzuziehen.
Novaterata

Antworten:

29

Verwenden Sie zum Schreiben in einen Stream im Speicher:

new ByteArrayOutputStream();
haraldK
quelle
3
Dies beantwortet die Frage nicht, da ByteArrayOutputStream nicht mit einer Schnittstelle verwendet werden kann, für die ein Dateiobjekt erforderlich ist.
FableBlaze
1
@FableBlaze Nun, die Antwort auf die Frage lautet dann "es ist nicht möglich". Diese Antwort versucht pragmatisch zu sein und zu sagen, was der Benutzer stattdessen tun könnte. Andreas 'Antwort ist eindeutig gründlicher und eine bessere (Versuch einer) Antwort.
HaraldK
"Es ist nicht möglich" wäre meiner Meinung nach eine gültige Antwort. Ich denke jedoch, dass ein In-Memory-Dateisystem (in den Kommentaren von Andreas 'Antwort erwähnt) ebenfalls erwähnt werden könnte, denn wenn Sie aus irgendeinem Grund nicht auf die Festplatte schreiben können, könnte dies ein Weg sein, dies zu umgehen.
FableBlaze
80

Wie kann ich eine neue Datei (aus java.io) im Speicher erstellen, nicht auf der Festplatte?

Vielleicht sind Sie verwirrend Fileund Stream:

  • A Fileist eine abstrakte Darstellung von Datei- und Verzeichnispfadnamen . Mithilfe eines FileObjekts können Sie auf die Dateimetadaten in einem Dateisystem zugreifen und einige Vorgänge für Dateien in diesem Dateisystem ausführen, z. B. Löschen oder Erstellen der Datei. Aber dieFile Klasse bietet jedoch keine Methoden zum Lesen und Schreiben des Dateiinhalts.
  • Zum Lesen und Schreiben aus einer Datei verwenden Sie ein StreamObjekt wie FileInputStreamoder FileOutputStream. Diese Streams können aus einem FileObjekt erstellt und dann zum Lesen und Schreiben in die Datei verwendet werden.

Sie können einen Stream basierend auf einem Bytepuffer erstellen, der sich im Speicher befindet , indem Sie a ByteArrayInputStreamund a verwenden ByteArrayOutputStream, um aus einem Bytepuffer zu lesen und in einen Bytepuffer zu schreiben, ähnlich wie Sie aus einer Datei lesen und schreiben. Das byteArray enthält den Inhalt der "Datei". Sie brauchen dann kein FileObjekt.

Sowohl die File...und die ByteArray...Ströme erben von java.io.OutputStreamund java.io.InputStreamjeweils so , dass Sie die gemeinsamen übergeordneten Klasse zu verstecken können , ob Sie aus einer Datei oder von einer Byte - Array lesen.

Andreas Fester
quelle
93
Ich bin nicht sicher, ob dies das ist, was das Originalposter wollte, aber ein Beispiel, wenn eine "Datei im Speicher" nützlich wäre, ist, wenn Sie eine vorhandene Bibliothek wiederverwenden möchten, die eine java.io.File als Eingabeparameter benötigt, aber Sie möchte eigentlich "Dateien" verwenden, die im Speicher gespeichert sind. In diesem Fall denke ich, dass eine Lösung darin besteht, Apache Commons VFS zu verwenden, um einen DefaultFileSystemManager zu instanziieren und damit einen RamFileProvider zu erstellen. Ich hätte dies als (vollständigere) richtige Antwort hinzugefügt, aber es scheint, dass diese Frage vor einiger Zeit geschlossen wurde ...
Sorin Postelnicu
2
+1 Ich war auf der Suche nach einer
solchen
3
Wenn Sie keine "tatsächliche Datei" erstellen möchten, können Sie versuchen, eine temporäre Datei zu erstellen. Siehe createTempFilefür java.io.file. Diese Datei kann so eingestellt werden, dass sie beim Beenden des Komponententests automatisch gelöscht wird.
Andrew-Dufresne
2
Dies beantwortet die Frage nicht. Wie @SorinPostelnicu gut sagte, ist eine "Datei" im Speicher so etwas wie ein Dateisystem im Speicher oder so.
Felipe
1
Fasst wahrscheinlich den Anwendungsfall des OP und eine wertvolle Methode zur Reduzierung der Latenz mit teuren System-Festplatten-E / A zusammen.
Eddie B
1

Sie können ein In-Memory-Dateisystem wie Jimfs verwenden

Hier ist ein Anwendungsbeispiel aus ihrer Readme-Datei:

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
quelle