147 votes

Comment créer un nouveau fichier java.io.File en mémoire ?

Comment puis-je créer de nouvelles File (de java.io ) en mémoire, et non sur le disque dur ?

J'utilise le langage Java. Je ne veux pas enregistrer le fichier sur le disque dur.

Je suis confronté à une mauvaise API ( java.util.jar.JarFile ). Il s'attend à ce que File file de String filename . Je n'ai pas de fichier (seulement byte[] ) et peut créer un fichier temporaire, mais ce n'est pas la meilleure solution. J'ai besoin de valider le digest d'un jar signé.

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

Tout exemple permettant d'obtenir le manifeste sans créer de fichier temporaire serait apprécié.

99voto

Andreas Points 16923

Comment puis-je créer un nouveau fichier (de java.io) en mémoire, et non sur le disque dur ?

Peut-être que vous confondez File y Stream :

  • A File est une représentation abstraite des fichiers et des répertoires chemins d'accès . L'utilisation d'un File vous pouvez accéder aux métadonnées d'un fichier dans un système de fichiers, et effectuer certaines opérations sur les fichiers de ce système de fichiers, comme la suppression ou la création du fichier. Mais l'objet File ne fournit pas de méthodes pour lire et écrire le contenu du fichier.
  • Pour lire et écrire à partir d'un fichier, vous utilisez un fichier de type Stream comme FileInputStream o FileOutputStream . Ces flux peuvent être créés à partir d'un File et sera ensuite utilisé pour lire et écrire dans le fichier.

Vous pouvez créer un flux basé sur un tampon d'octets qui réside en mémoire en utilisant un ByteArrayInputStream et un ByteArrayOutputStream pour lire et écrire dans un tampon d'octets de la même manière que vous lisez et écrivez dans un fichier. Le site byte contient le contenu du "File". Vous n'avez pas besoin d'un File objet alors.

Les deux File... et le ByteArray... Les flux héritent de java.io.OutputStream y java.io.InputStream de sorte que vous pouvez utiliser la superclasse commune pour masquer le fait que vous lisez à partir d'un fichier ou d'un tableau d'octets.

43voto

haraldK Points 5751

Il n'est pas possible de créer un java.io.File qui conserve son contenu dans la mémoire (Java heap) *.

Au lieu de cela, vous utilisez normalement un flux. Pour écrire dans un flux, en mémoire, utilisez :

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

Mais malheureusement, un flux ne peut pas être utilisé comme entrée de java.util.jar.JarFile qui, comme vous le mentionnez, ne peut utiliser qu'un File ou un String contenant le chemin d'accès à un JAR valide fichier . Je pense que l'utilisation d'un fichier temporaire comme vous le faites actuellement est la seule option, à moins que vous ne souhaitiez utiliser une API différente.

Si vous êtes d'accord pour utiliser une API différente, il existe commodément une classe dans le même paquet, nommée JarInputStream que vous pouvez utiliser. Il suffit d'envelopper votre archiveContent dans un tableau ByteArrayInputStream pour lire le contenu du JAR et extraire le manifeste :

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

*) Il est évidemment possible de créer un système de fichiers complet qui réside en mémoire, comme un disque RAM, mais il serait toujours "sur le disque" (et non dans la mémoire du tas de Java) en ce qui concerne le processus Java.

14voto

Tedward Points 21

Vous pouvez utiliser un système de fichiers en mémoire, tel que Jimfs

Voici un exemple d'utilisation tiré de leur 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);

6voto

mipasov Points 255

Je pense que le fichier temporaire peut être une autre solution pour cela.

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

Il y a une réponse à cette question aquí .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X