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

Lesezeit: 6 Minuten

Wie kann ich neu anlegen File (aus java.io) im Speicher, nicht auf der Festplatte?

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

Ich bin mit einer schlechten API konfrontiert (java.util.jar.JarFile). Es erwartet File file von String filename. Ich habe keine Datei (nur byte[] Inhalt) und kann eine temporäre Datei 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 dafür, wie Sie ein Manifest erhalten können, ohne eine temporäre Datei zu erstellen, wären willkommen.

  • Sie wollen also nur Bytes im Speicher?

    – Sotirios Delimanolis

    11. Juli 2013 um 13:46 Uhr


  • Was versuchst du tun mit diesem File?

    – Jon Skeet

    11. Juli 2013 um 13:46 Uhr

  • EIN File ist per Definition auf der Festplatte.

    – Uwe Plonus

    11. Juli 2013 um 13:47 Uhr

  • @UwePlonus nein… new File("/dev/null")

    – fg

    11. Juli 2013 um 13:48 Uhr

  • Wow, der Mangel an Vorstellungskraft bei StackOverflow ist erstaunlich. Jemand benötigt möglicherweise eine In-Memory-Datei, weil er eine Schnittstelle verwendet, die eine Datei erfordert. Die Schnittstelle hätte für einen InputStream geschrieben werden sollen, war es aber nicht. Eine temporäre Datei scheint einfach übertrieben zu sein, daher wäre eine In-Memory-java.io.File vorzuziehen.

    – Novaterata

    17. April 2019 um 21:00 Uhr


Benutzer-Avatar
Andreas Fester

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

Vielleicht verwirrst du dich File und Stream:

  • EIN File ist eine abstrakte Darstellung von Datei und Verzeichnis Pfadnamen. Verwendung einer File -Objekt können Sie auf die Dateimetadaten in einem Dateisystem zugreifen und einige Operationen an Dateien in diesem Dateisystem ausführen, wie z. B. die Datei löschen oder erstellen. Aber die File Die Klasse stellt keine Methoden zum Lesen und Schreiben des Dateiinhalts bereit.
  • Um aus einer Datei zu lesen und zu schreiben, verwenden Sie a Stream Objekt, wie FileInputStream oder FileOutputStream. Diese Streams können erstellt werden aus a File -Objekt und kann dann zum Lesen und Schreiben in die Datei verwendet werden.

Sie können eine erstellen Stream basierend auf einem Byte-Puffer, der sich im Speicher befindetdurch Verwendung von a ByteArrayInputStream und ein ByteArrayOutputStream zum Lesen und Schreiben in a Byte-Puffer auf ähnliche Weise lesen und schreiben Sie aus einer Datei. Das byte Das Array enthält den Inhalt der “Datei”. Sie brauchen keine File Objekt dann.

Beide File... und die ByteArray... Streams erben von java.io.OutputStream und java.io.InputStreamsodass Sie die gemeinsame Superklasse verwenden können, um zu verbergen, ob Sie aus einer Datei oder aus einem Byte-Array lesen.

  • Ich bin mir nicht sicher, ob dies das ist, was das ursprüngliche Poster wollte, aber ein Beispiel, in dem 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 tatsächlich im Speicher gespeicherte “Dateien” verwenden möchten. In diesem Fall wäre eine Lösung meiner Meinung nach, 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

    18. Dezember 2013 um 16:54 Uhr

  • +1 Ich habe nach dieser Art von Lösung gesucht, um Komponenten zu testen, ohne eine tatsächliche Datei verwenden zu müssen

    – GClaramunt

    20. Dezember 2013 um 14:10 Uhr

  • Wenn Sie keine “tatsächliche Datei” erstellen möchten, können Sie versuchen, eine temporäre Datei zu erstellen. Sehen createTempFile zum java.io.file. Diese Datei kann so eingestellt werden, dass sie beim Beenden des Komponententests automatisch gelöscht wird.

    – Andrew-Dufresne

    16. August 2014 um 0:37 Uhr

  • Dies beantwortet die Frage nicht. Wie @SorinPostelnicu gut sagte, ist eine “Datei” im Speicher so etwas wie ein Dateisystem im Speicher oder so.

    – Felipe

    3. September 2014 um 3:09 Uhr

  • OP verwechselt Dateien und Streams definitiv NICHT. Er glaubt, er möchte jarFile verwenden, um eine Datei zu lesen, und alles, was er hat, sind die Bytes aus irgendeiner Quelle (getContent()).

    – Zweibären

    25. Oktober 2018 um 21:20 Uhr

Benutzer-Avatar
Harald K

Es ist nicht möglich, eine zu erstellen java.io.File das seinen Inhalt im (Java-Heap-) Speicher hält *.

Stattdessen würden Sie normalerweise einen Stream verwenden. Verwenden Sie zum Schreiben in einen Stream im Speicher:

OutputStream out = new ByteArrayOutputStream();
out.write(...);

Aber leider kann ein Stream nicht als Input für verwendet werden java.util.jar.JarFiledie, wie Sie erwähnen, nur a verwenden kann File oder ein String enthält den Pfad zu einem gültigen JAR Datei. Ich glaube, dass die Verwendung einer temporären Datei, wie Sie es derzeit tun, die einzige Option ist, es sei denn, Sie möchten eine andere API verwenden.

Wenn Sie mit der Verwendung einer anderen API einverstanden sind, gibt es praktischerweise eine Klasse im selben Paket mit dem Namen JarInputStream Sie können verwenden. Wickeln Sie einfach Ihre ein archiveContent Reihe in a ByteArrayInputStreamum den Inhalt des JAR zu lesen und das Manifest zu extrahieren:

try (JarInputStream stream = new JarInputStream(new ByteArrayInputStream(archiveContent))) {
     Manifest manifest = stream.getManifest();
}

*) Es ist offensichtlich möglich, ein vollständiges Dateisystem zu erstellen, das sich wie eine RAM-Disk im Speicher befindet, aber das wäre immer noch “auf der Festplatte” (und nicht im Java-Heap-Speicher), soweit es den Java-Prozess betrifft.

  • Dies beantwortet die Frage nicht, da ByteArrayOutputStream nicht mit einer Schnittstelle verwendet werden kann, die ein Dateiobjekt erfordert.

    – FableBlaze

    17. Januar 2020 um 12:04 Uhr

  • @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. Die Antwort von Andreas ist eindeutig gründlicher und ein besserer (Versuch einer) Antwort.

    – Harald K

    17. Januar 2020 um 12:11 Uhr

  • “Es ist nicht möglich” wäre meiner Meinung nach eine gültige Antwort. Ich denke jedoch, dass auch ein In-Memory-Dateisystem (in den Kommentaren von Andreas ‘Antwort erwähnt) erwähnt werden könnte, denn wenn Sie aus irgendeinem Grund nicht auf die Festplatte schreiben können, könnte dies ein Ausweg sein.

    – FableBlaze

    17. Januar 2020 um 12:19 Uhr


Sie könnten ein In-Memory-Dateisystem verwenden, z Jimfs

Hier ist ein Anwendungsbeispiel aus ihrer 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);

  • Jimfs wird nicht unterstützt File Objekt

    – Pixel

    2. Juni 2021 um 12:25 Uhr

Ich denke, temporäre Dateien können eine andere Lösung dafür sein.

File tempFile = File.createTempFile(prefix, suffix, null);
FileOutputStream fos = new FileOutputStream(tempFile);
fos.write(byteArray);

Eine Antwort darauf gibt es hier.

1018650cookie-checkWie erstelle ich eine neue java.io.File im Speicher? [duplicate]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy