Отображаемые в память файлы в Java

Я пытался написать очень быстрый Java-код, который должен выполнять много операций ввода-вывода. Я использую файл отображения памяти, который возвращает ByteBuffer:

public static ByteBuffer byteBufferForFile(String fname){
    FileChannel vectorChannel;
    ByteBuffer vector;
    try {
        vectorChannel = new FileInputStream(fname).getChannel();
    } catch (FileNotFoundException e1) {
        e1.printStackTrace();
        return null;
    }
    try {
        vector = vectorChannel.map(MapMode.READ_ONLY,0,vectorChannel.size());
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
    return vector;
}

У меня проблема в том, что метод ByarBuffer .array() (который должен возвращать массив byte[]) не работает для файлов только для чтения. Я хочу написать свой код так, чтобы он работал как с буферами памяти, созданными в памяти, так и с буферами, считываемыми с диска. Но я не хочу оборачивать все мои буферы функцией ByteBuffer.wrap(), потому что я боюсь, что это замедлит процесс. Итак, я написал две версии всего: одна для байта [], другая для байтового буфера.

Должен ли я просто обернуть все? Или мне все дважды написать?

4 ответа

Решение

Кто-нибудь проверял, действительно ли ByteBuffers созданный с помощью поддержки отображения памяти .array() во-первых, независимо от readonly/readwrite?

Насколько я могу судить, из моего возни, ответ - НЕТ. ByteBufferСпособность вернуть прямой byte[] массив через ByteBuffer.array() определяется наличием ByteBuffer.hb (byte[]), который всегда равен нулю, когда MappedByteBuffer создано.

Что-то вроде отстой для меня, потому что я надеялся сделать что-то похожее на то, что хотел сделать автор вопроса.

Всегда хорошо не изобретать колеса. Apache предоставил прекрасную библиотеку для выполнения операций ввода-вывода. Взгляните на http://commons.apache.org/io/description.html

Вот сценарий, которому он служит. Предположим, у вас есть некоторые данные, которые вы бы предпочли сохранить в памяти, но вы не знаете заранее, сколько будет данных. Если их слишком много, вы хотите записать их на диск, а не загружать память, но вы не хотите записывать на диск, пока вам это не нужно, потому что диск медленный и является ресурсом, который требует отслеживания для очистки.

Итак, вы создаете временный буфер и начинаете писать в него. Если / когда вы достигнете порогового значения для того, что вы хотите сохранить в памяти, вам нужно будет создать файл, записать, что находится в буфере для этого файла, и записать все последующие данные в файл вместо буфера.

Это то, что DeferredOutputStream делает для вас. Он скрывает всю неразбериху в момент переключения. Все, что вам нужно сделать, это сначала создать отложенный поток, настроить пороговое значение, а затем просто записать все, что душе угодно.

РЕДАКТИРОВАТЬ: Я только что сделал небольшой повторный поиск с помощью Google и нашел эту ссылку: http://lists.apple.com/archives/java-dev/2004/Apr/msg00086.html(молниеносное чтение / запись файла). Очень впечатляюще.

Обертывание байта [] не замедлит процесс... не будет копий огромных массивов или других небольших недостатков производительности. Из JavaDocs: java.nio.ByteBuffer.wrap ()

Оборачивает байтовый массив в буфер.

Новый буфер будет поддержан данным байтовым массивом; то есть изменения в буфере приведут к изменению массива и наоборот. Емкость и предел нового буфера будут равны array.length, его позиция будет равна нулю, а его метка будет неопределенной. Его резервный массив будет заданным массивом, а его смещение массива будет равно нулю.

Использование функциональности ByteBuffer.wrap() не накладывает больших затрат. Он выделяет простой объект и инициализирует несколько целых чисел. Таким образом, написание вашего алгоритма для ByteBuffer - ваш лучший выбор, если вам нужно работать с файлами только для чтения.

Другие вопросы по тегам