125

如何在内存中创建新的File(从java.io),而不是在硬盘上?

我正在使用 Java 语言。我不想将文件保存在硬盘上。

我面临着一个糟糕的 API ( java.util.jar.JarFile)。它期待File file. String filename我没有文件(只有byte[]内容)并且可以创建临时文件,但这不是很好的解决方案。我需要验证签名 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();

任何有关如何在不创建临时文件的情况下获得清单的示例都将不胜感激。

4

4 回答 4

89

如何在内存而不是硬盘中创建新文件(来自 java.io)?

也许您感到困惑File并且Stream

  • AFile是文件和目录路径名的抽象表示。使用File对象,您可以访问文件系统中的文件元数据,并对该文件系统上的文件执行一些操作,例如删除或创建文件。但是File该类不提供读取和写入文件内容的方法。
  • 要从文件中读取和写入,您正在使用一个Stream对象,例如FileInputStreamFileOutputStream。这些流可以从File对象创建,然后用于读取和写入文件。

您可以基于驻留在内存中的字节缓冲区创建流,方法是使用 aByteArrayInputStream和 aByteArrayOutputStream以与从文件读取和写入类似的方式读取和写入字节缓冲区。byte数组包含“文件”的内容。那么你就不需要File对象了。

File...和流都分别ByteArray...继承自java.io.OutputStreamjava.io.InputStream,因此您可以使用公共超类来隐藏您是从文件读取还是从字节数组读取。

于 2013-07-11T13:53:39.350 回答
34

不可能创建一个java.io.File将其内容保存在(Java 堆)内存中的 *。

相反,通常您会使用流。要在内存中写入流,请使用:

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

但不幸的是,流不能用作 的输入java.util.jar.JarFile,正如您所提到的,它只能使用包含有效 JAR文件File路径的 a或 a 。我相信像你现在这样使用临时文件是唯一的选择,除非你想使用不同的 API。String

如果您可以使用不同的 API,那么在同一个包中方便地有一个类,命名为JarInputStream您可以使用。archiveContent只需将数组包装在ByteArrayInputStream, 中即可读取 JAR 的内容并提取清单:

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

*) 显然可以创建一个驻留在内存中的完整文件系统,例如 RAM 磁盘,但就 Java 进程而言,它仍然是“在磁盘上”(而不是在 Java 堆内存中)。

于 2013-07-11T13:54:27.640 回答
11

您可以使用内存中的文件系统,例如Jimfs

这是他们自述文件中的一个使用示例:

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);
于 2020-05-21T17:33:08.507 回答
1

我认为临时文件可以是另一种解决方案。

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

这里有一个答案。

于 2021-09-05T06:00:38.147 回答