Самый быстрый и чистый способ загрузить запись файловой системы в файл с отображением памяти (NIO2)

Я хотел бы извлечь запись zip/jar в память, чтобы я мог закрыть zip-поток/FS и сохранить файл в JVM, не имея дело с временными копиями.

Один из вариантов — использовать Files.readAllLines(Path pathToZipFSentry), но, похоже, он использовал буферизованный ридер, который может сильно наказывать большие файлы.

Итак, я изучаю, как это сделать в Java NIO2, и кажется, что путь заканчивается MappedByteBuffer через FileChannels.

Я не могу использовать RandomAccessFile.getChannel(), поскольку я исхожу из пути виртуальной файловой системы, а не из буквального файла. Я не могу использовать Files.newByteChannel(rscPath, StandardOpenOption.READ), а затем (fileChannel.)map(), потому что он возвращает SeekableByteChannel, у которого нет карты в интерфейсе...

Есть ли для этого один/два высокоуровневых вкладыша с помощью Path(s)/File(s)/FileSystem(s)/FileChannel(s) в Java8? Я бы ожидал что-то вроде InMemoryFile file = Files.loadIntoMem(Path) Я 1 час искал вариант закрытия...


person Whimusical    schedule 15.02.2015    source источник
comment
Вы пробовали и FileChannel.open()? Но в любом случае это не решит проблему, что вы не можете напрямую mmap() из записи zip в любом случае; где-то будет временная копия   -  person fge    schedule 15.02.2015
comment
Это именно тот подход, через который я прохожу сейчас, и тот самый страх, который я испытываю, пока я продвигаюсь вперед, но я чувствую, что это должен быть более легкий вариант где-то здесь.   -  person Whimusical    schedule 15.02.2015
comment
Кстати, подтверждено, com.sun.nio.zipfs.ZipFileSystem.map() возвращает NotSupportedoperationException();   -  person Whimusical    schedule 15.02.2015


Ответы (1)


Вы не можете загрузить это прямо в память.

У вас есть FileChannel.open(), из которого вы можете затем .map(), но это все равно создаст временную запись на вашем диске.

Существует также memoryfilesystem, но, к сожалению, она не будет обрабатывать файлы, достаточно большие, чтобы быть полезной.

Лучшее решение, которое я вижу, это Files.copy() во временный файл и mmap(); затем скопируйте обратно в zip-файл, когда закончите с изменениями.

Но в основном, это то, что вы уже делаете, так что...

person fge    schedule 15.02.2015
comment
Меня интересует, что создаст временную запись на вашем диске... Не следует ли отображать от 0 до size() 100% загрузку в памяти в MappedByteBuffer? - person Whimusical; 15.02.2015
comment
Это маловероятно по той простой причине, что запись zip является последовательной по определению; однако для *Streams это другая история. Но сопоставления — это, ну, произвольный доступ. - person fge; 15.02.2015
comment
Вы имеете в виду, что временный файл нужен ДО полной загрузки или он нужен после операции загрузки? - person Whimusical; 15.02.2015