Как создать новый java.io.File в памяти?

100

Как я могу создавать новые File(из java.io) в памяти, а не на жестком диске?

Я использую язык Java. Я не хочу сохранять файл на жестком диске.

Я столкнулся с плохим API ( java.util.jar.JarFile). Он ожидает File fileот String filename. У меня нет файла (только byte[]содержимое), и я могу создать временный файл, но это не красивое решение. Мне нужно проверить дайджест подписанной банки.

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

Приветствуются любые примеры того, как получить манифест без создания временного файла.

Ggorlen
источник
8
Значит, вам просто нужны байты в памяти?
Сотириос Делиманолис
6
Что вы пытаетесь с этим делатьFile ?
Джон Скит
5
А Fileпо определению находится на жестком диске.
Uwe Plonus
3
какой смысл создавать файл, если он вам не нужен в постоянной памяти?
Bhavik Shah
7
Вау, отсутствие воображения в StackOverflow просто поражает. Кому-то может понадобиться файл в памяти просто, потому что они используют интерфейс, для которого требуется файл. Интерфейс должен был быть написан для InputStream, но это не так. Временный файл кажется излишним, поэтому предпочтительнее использовать java.io.File в памяти.
Новатерата

Ответы:

31

Для записи в поток в памяти используйте:

new ByteArrayOutputStream();
haraldK
источник
5
Это не отвечает на вопрос, поскольку ByteArrayOutputStream не может использоваться с интерфейсом, требующим файлового объекта.
FableBlaze
1
@FableBlaze Что ж, тогда ответ на вопрос - «это невозможно». Этот ответ пытается быть прагматичным и рассказывать, что пользователь может сделать вместо этого. Ответ Андреаса явно более подробный и лучший (попытка ответа).
haraldK
«Это невозможно», на мой взгляд, было бы правильным ответом. Однако я думаю, что файловая система в памяти (упомянутая в комментариях к ответу Андреаса) также может быть упомянута, потому что, если вы по какой-то причине не можете писать на жесткий диск, это может быть способ обойти это.
FableBlaze
81

Как я могу создать новый файл (из java.io) в памяти, а не на жестком диске?

Может вы сбиваете с толку Fileи Stream:

  • A File- абстрактное представление путей к файлам и каталогам . Используя Fileобъект, вы можете получить доступ к метаданным файла в файловой системе и выполнить некоторые операции с файлами в этой файловой системе, например удалить или создать файл. Но Fileкласс не предоставляет методов для чтения и записи содержимого файла.
  • Для чтения и записи из файла вы используете Streamобъект, например FileInputStreamили FileOutputStream. Эти потоки могут быть созданы из Fileобъекта, а затем использоваться для чтения и записи в файл.

Вы можете создать поток на основе байтового буфера, который находится в памяти , используя a ByteArrayInputStreamи a ByteArrayOutputStreamдля чтения и записи в байтовый буфер аналогично тому, как вы читаете и пишете из файла. byteМассив содержит содержимое «файла». FileТогда вам не нужен объект.

И потоки, File...и ByteArray...потоки наследуются от java.io.OutputStreamи java.io.InputStream, соответственно, поэтому вы можете использовать общий суперкласс, чтобы скрыть, читаете ли вы из файла или из массива байтов.

Андреас Фестер
источник
96
Я не уверен, что это то, что хотел исходный плакат, но один из примеров, когда «Файл в памяти» был бы полезен, - это когда вы хотите повторно использовать существующую библиотеку, которой требуется java.io.File в качестве входного параметра, но вы на самом деле хотите использовать «файлы», хранящиеся в памяти. В этом случае я думаю, что одним из решений было бы использование Apache Commons VFS для создания экземпляра DefaultFileSystemManager и его использования для создания RamFileProvider. Я бы добавил это как (более полный) правильный ответ, но похоже, что этот вопрос был закрыт некоторое время назад ...
Сорин Постельнику
2
+1 Я искал такое решение, чтобы модульный тест приходил на компонент без необходимости использовать реальный файл
GClaramunt
3
Если вы не хотите создавать «настоящий файл», вы можете попробовать создать временный файл. Смотрите createTempFileдля java.io.file. Этот файл можно настроить на автоматическое удаление при выходе из модульного теста.
Эндрю-Дюфрен
2
Это не отвечает на вопрос. Как хорошо сказал @SorinPostelnicu, «Файл» в памяти - это что-то вроде файловой системы в памяти или около того.
Фелипе
1
Вероятно, суммирует вариант использования OP и ценный метод уменьшения задержки с дорогостоящим вводом-выводом системного диска.
Эдди Б.
3

Вы можете использовать файловую систему в памяти, такую ​​как Jimfs

Вот пример использования из их 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);
Тедвард
источник