Jak utworzyć nowy plik java.io. w pamięci?

105

Jak mogę utworzyć nowy File(z java.io) w pamięci, a nie na dysku twardym?

Używam języka Java. Nie chcę zapisywać pliku na dysku twardym.

Mam do czynienia ze złym API ( java.util.jar.JarFile). To oczekując File fileod String filename. Nie mam pliku (tylko byte[]zawartość) i mogę utworzyć plik tymczasowy, ale nie jest to piękne rozwiązanie. Muszę zweryfikować skrót podpisanego słoika.

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

Wszelkie przykłady, jak osiągnąć manifestację bez tworzenia pliku tymczasowego, będą mile widziane.

ggorlen
źródło
8
Więc chcesz tylko bajtów w pamięci?
Sotirios Delimanolis,
6
Co próbujesz z tym zrobićFile ?
Jon Skeet,
5
A Filez definicji znajduje się na dysku twardym.
Uwe Plonus,
3
Jaki jest sens tworzenia pliku, jeśli nie chcesz go mieć w pamięci trwałej?
Bhavik Shah,
9
Wow, brak wyobraźni na StackOverflow jest zdumiewający. Ktoś może potrzebować prostego pliku w pamięci, ponieważ używa interfejsu, który wymaga pliku. Interfejs powinien zostać napisany dla InputStream, ale tak nie było. Plik tymczasowy wydaje się po prostu przesadzony, więc preferowany byłby plik java.io.File w pamięci.
Novaterata

Odpowiedzi:

31

Aby pisać do strumienia, w pamięci użyj:

new ByteArrayOutputStream();
haraldK
źródło
6
To nie daje odpowiedzi na pytanie, ponieważ ByteArrayOutputStream nie nadaje się do użytku z interfejsem, który wymaga obiektu pliku.
FableBlaze
1
@FableBlaze Cóż, odpowiedź na pytanie brzmi więc „to niemożliwe”. Ta odpowiedź stara się być pragmatyczna i mówi, co użytkownik może zrobić zamiast tego. Odpowiedź Andreasa jest wyraźnie dokładniejsza i lepsza (próba odpowiedzi).
haraldK
Moim zdaniem „to niemożliwe” byłoby poprawną odpowiedzią. Myślę jednak, że można również wspomnieć o systemie plików w pamięci (wspomnianym w komentarzach do odpowiedzi Andreasa), ponieważ jeśli z jakiegoś powodu nie możesz pisać na dysk twardy, to może to być sposób na obejście tego problemu.
FableBlaze
83

Jak mogę utworzyć nowy plik (z java.io) w pamięci, a nie na dysku twardym?

Może jesteś mylący Filei Stream:

  • A Filejest abstrakcyjną reprezentacją nazw ścieżek do plików i katalogów . Korzystając z Fileobiektu, można uzyskać dostęp do metadanych pliku w systemie plików i wykonać pewne operacje na plikach w tym systemie plików, takie jak usunięcie lub utworzenie pliku. Ale Fileklasa nie zapewnia metod do odczytu i zapisu zawartości pliku.
  • Aby czytać i pisać z pliku, używasz Streamobiektu, takiego jak FileInputStreamlub FileOutputStream. Te strumienie mogą być tworzone z Fileobiektu, a następnie używane do odczytu i zapisu w pliku.

Możesz utworzyć strumień na podstawie bufora bajtowego, który znajduje się w pamięci , używając a ByteArrayInputStreami a ByteArrayOutputStreamdo odczytywania i zapisywania w buforze bajtowym w podobny sposób, jak czytasz i zapisujesz z pliku. byteTablica zawiera treści „plik za”. Nie potrzebujeszFile wtedy przedmiotu.

Zarówno strumienie, jak File...i ByteArray...strumienie , odpowiednio, dziedziczą z java.io.OutputStreami java.io.InputStream, dzięki czemu można użyć wspólnej nadklasy do ukrycia, czy czytasz z pliku, czy z tablicy bajtów.

Andreas Fester
źródło
97
Nie jestem pewien, czy tego właśnie chciał oryginalny plakat, ale jednym z przykładów, kiedy przydałby się „Plik w pamięci”, jest sytuacja, gdy chcesz ponownie użyć istniejącej biblioteki, która wymaga java.io.File jako parametru wejściowego, ale faktycznie chce użyć „plików” przechowywanych w pamięci. W takim przypadku myślę, że jednym z rozwiązań byłoby użycie Apache Commons VFS do utworzenia wystąpienia DefaultFileSystemManager i użycie go do utworzenia RamFileProvider.
Dodałbym
2
+1 Szukałem tego rodzaju rozwiązania, aby test jednostkowy pochodził z komponentu bez konieczności użycia rzeczywistego pliku
GClaramunt
3
Jeśli nie chcesz tworzyć „rzeczywistego pliku”, możesz spróbować utworzyć plik tymczasowy. Zobacz createTempFilena java.io.file. Ten plik można ustawić na automatyczne usuwanie po zakończeniu testu jednostkowego.
Andrew-Dufresne
2
To nie odpowiada na pytanie. Jak dobrze powiedział @SorinPostelnicu, "Plik" w pamięci jest czymś w rodzaju systemu plików w pamięci.
Felipe
1
Prawdopodobnie podsumowuje przypadek użycia OP i cenną metodę zmniejszania opóźnień za pomocą drogich operacji we / wy dysku systemowego.
Eddie B
5

Możesz użyć systemu plików w pamięci, takiego jak Jimfs

Oto przykład użycia z ich pliku 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);
Tedward
źródło