简体   繁体   English

如何在内存中创建一个新的 java.io.File?

[英]How to create a new java.io.File in memory?

How can I create new File (from java.io ) in memory, not on the hard disk?如何在内存中而不是在硬盘上创建新File (来自java.io )?

I am using the Java language.我正在使用 Java 语言。 I don't want to save the file on the hard drive.我不想将文件保存在硬盘上。

I'm faced with a bad API ( java.util.jar.JarFile ).我遇到了一个糟糕的 API ( java.util.jar.JarFile )。 It's expecting File file of String filename .它期待String filename File file I have no file (only byte[] content) and can create temporary file, but it's not beautiful solution.我没有文件(只有byte[]内容)并且可以创建临时文件,但这不是很好的解决方案。 I need to validate the digest of a signed jar.我需要验证签名 jar 的摘要。

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

Any examples of how to achieve getting manifest without creating a temporary file would be appreciated.任何有关如何在不创建临时文件的情况下获取清单的示例将不胜感激。

How can I create new File (from java.io) in memory , not in the hard disk?如何在内存中而不是在硬盘中创建新文件(来自 java.io)?

Maybe you are confusing File and Stream :也许你混淆了FileStream

  • A File is an abstract representation of file and directory pathnames . File是文件和目录路径名的抽象表示。 Using a File object, you can access the file metadata in a file system, and perform some operations on files on this filesystem, like delete or create the file.使用File对象,您可以访问文件系统中的文件元数据,并对该文件系统上的文件执行一些操作,例如删除或创建文件。 But the File class does not provide methods to read and write the file contents.但是File类不提供读写文件内容的方法。
  • To read and write from a file, you are using a Stream object, like FileInputStream or FileOutputStream .要读取和写入文件,您需要使用Stream对象,例如FileInputStreamFileOutputStream These streams can be created from a File object and then be used to read from and write to the file.这些流可以从File对象创建,然后用于读取和写入文件。

You can create a stream based on a byte buffer which resides in memory , by using a ByteArrayInputStream and a ByteArrayOutputStream to read from and write to a byte buffer in a similar way you read and write from a file.您可以基于驻留在内存中的字节缓冲区创建,方法是使用ByteArrayInputStreamByteArrayOutputStream以类似于从文件中读写的方式读取和写入字节缓冲区 The byte array contains the "File's" content. byte数组包含“文件”的内容。 You do not need a File object then.那时您不需要File对象。

Both the File... and the ByteArray... streams inherit from java.io.OutputStream and java.io.InputStream , respectively, so that you can use the common superclass to hide whether you are reading from a file or from a byte array. File...ByteArray...流分别继承自java.io.OutputStreamjava.io.InputStream ,因此您可以使用通用超类来隐藏您是从文件读取还是从字节读取阵列。

It is not possible to create a java.io.File that holds its content in (Java heap) memory *.无法创建将其内容保存在(Java 堆)内存中的java.io.File *。

Instead, normally you would use a stream.相反,通常您会使用流。 To write to a stream, in memory, use:要在内存中写入流,请使用:

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

But unfortunately, a stream can't be used as input for java.util.jar.JarFile , which as you mention can only use a File or a String containing the path to a valid JAR file .但不幸的是,流不能用作java.util.jar.JarFile输入,正如您提到的,它只能使用包含有效 JAR文件路径的FileString I believe using a temporary file like you currently do is the only option, unless you want to use a different API.我相信像您目前所做的那样使用临时文件是唯一的选择,除非您想使用不同的 API。

If you are okay using a different API, there is conveniently a class in the same package, named JarInputStream you can use.如果您可以使用不同的 API,那么在同一个包中可以方便地使用一个名为JarInputStream的类。 Simply wrap your archiveContent array in a ByteArrayInputStream , to read the contents of the JAR and extract the manifest:只需将您的archiveContent数组包装在ByteArrayInputStream ,即可读取 JAR 的内容并提取清单:

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

*) It's obviously possible to create a full file-system that resides in memory, like a RAM-disk, but that would still be "on disk" (and not in Java heap memory) as far as the Java process is concerned. *) 显然可以创建一个完整的文件系统驻留在内存中,如 RAM 磁盘,但就 Java 进程而言,它仍然是“在磁盘上”(而不是在 Java 堆内存中)。

You could use an in-memory filesystem, such as Jimfs您可以使用内存文件系统,例如Jimfs

Here's a usage example from their 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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM