FileInput / OutputStream по сравнению с FileChannels, что дает лучшую производительность

Я пишу программу, которая должна копировать из папки в папку большой, но небольшой объем данных (в диапазоне нескольких десятков фотографий сразу). Первоначально я использовал java.io.FileOutputStream, чтобы просто читать в буфер и записывать, но потом я услышал о потенциальном увеличении производительности с помощью java.nio.FileChannel.

У меня нет ресурсов для проведения серьезного контролируемого теста с данными, которые у меня есть, но, похоже, нет единого мнения о преимуществах каждого из них (кроме того, что FileChannel является потокобезопасным). Некоторые пользователи сообщают, что FileChannel отлично подходит для файлов меньшего размера, другие сообщают о значительном увеличении скорости работы с файлами большего размера.

Мне интересно, знает ли кто-нибудь, в чем именно заключалась цель создания FileChannel: было ли оно разработано для лучшей производительности? В каких случаях? И есть ли значительное повышение производительности для общих типов данных или различия, которые я должен ожидать увидеть, незначительны, потому что я не работаю с данными, которые достаточно специализированы?

РЕДАКТИРОВАТЬ: Предположим, что мои данные не должны быть потокобезопасными.


person donnyton    schedule 05.07.2011    source источник
comment
В некоторой степени дублирует - stackoverflow.com/questions/106770/.   -  person mindas    schedule 06.07.2011
comment
Да, подобные вопросы задавали много раз, но я хорошо осведомлен о существующих пакетах ввода-вывода. Сейчас меня больше интересует необработанное сравнение производительности каждого из них.   -  person donnyton    schedule 06.07.2011


Ответы (3)


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

Каналы - это средства для копирования информации в буферы. Это обеспечивает более низкий уровень доступа к процедурам ввода и вывода. Благодаря продуманному определению размера буфера ускорение может быть впечатляющим. Структурирование кода вокруг буферов может сократить время, затрачиваемое на цикл чтения (также увеличивая производительность). Наконец, хотя можно выполнить предварительную проверку состояния входного потока в попытке избежать блокировки, каналы и буферы позволяют выполнять операции неблокирующим образом (даже в наихудших условиях).

person Edwin Buck    schedule 05.07.2011

FileChannel.transferFrom/To должен быть быстрее, чем поток ввода-вывода для копирования файлов.

Или вы можете просто использовать Java 7 _ 2_. Это должно быть как можно быстрее.

Однако, в конце концов, производительность заметно не изменится - узким местом является скорость жесткого диска.


FileChannel не является неблокирующим, и его нельзя выбрать. Не уверен, собираются ли они добавлять эти функции в будущем. Хотя в Java 7 есть AsynchronousFileChannel.

person irreputable    schedule 05.07.2011
comment
Я хотел добавить, что, в зависимости от реализации, операция transferXXX() может быть намного быстрее, потому что данные не копируются между ядром и пользовательским пространством в памяти. - person erickson; 06.07.2011
comment
Так и должно быть, как и утверждается - было бы обидно, если бы этот API был хотя бы не медленнее, чем потоковый API. Однако жаль, что многие люди сообщают, что во многих ситуациях это действительно медленнее. - person irreputable; 06.07.2011

Вы смотрели commons-io?

FileUtils.copyFileToDirectory(srcFile, destDir);
person Thor    schedule 05.07.2011
comment
Мне не нужна такая большая функциональность ввода-вывода. Это не тяжелая программа ввода-вывода, время от времени бывает только одна операция, которая копирует много файлов и должна быть быстрой. - person donnyton; 06.07.2011
comment
Вот почему я упомянул об этом. Производительность ввода-вывода во многом зависит от стратегии буферизации. Библиотека доступна годами, с постоянными обновлениями и большим количеством часов программирования, потраченных на нее. Я предполагаю, что он работает лучше, чем собственные реализации, даже когда на него потрачена определенная сумма. - person Thor; 06.07.2011