Я хотел написать программу, которая одновременно записывает в несколько файлов; подумал, что это будет возможно с помощью одного потока, используя неблокирующий режим. Но FileChannel не поддерживает неблокирующий режим. Кто-нибудь знает, почему?
Почему FileChannel в Java не является блокирующим?
Ответ 1
UNIX не поддерживает неблокирующий ввод-вывод для файлов, см. Неблокирующий ввод-вывод с обычными файлами. Поскольку Java должна (по крайней мере, пытаться) обеспечить такое же поведение на всех платформах, FileChannel
не реализует SelectableChannel
.
Однако Java 7 будет включать новый класс AsynchronousFileChannel
, который поддерживает асинхронный ввод-вывод файлов, что является другим механизмом, блокирующий ввод-вывод. Одна из его реализаций WindowsAsynchronousFileChannelImpl
дает преимущества неблокирующего API ввода-вывода в Windows (см. Асинхронный ввод-вывод в Windows).
Тем временем вы можете использовать несколько потоков для достижения того же эффекта. Но это уже реализовано в SimpleAsynchronousFileChannelImpl
, который переносится во всех операционных системах.
Как правило, только разъемы и трубки действительно поддерживают неблокирующий ввод-вывод через механизм select()
.
@Прочитайте комментарии таким образом:
"AsynchronousFileChannel поддерживает асинхронный ввод-вывод, а не без блокировки".
На мой взгляд, асинхронный ввод-вывод (с использованием, например, Future
или CompletionHandler
) является формой неблокирующего ввода-вывода.
- Он не блокирует поток, выполняющий вызов
read(...)
на канале. - Вы можете использовать
Future.isDone()
, чтобы избежать блокировки позже.
(И, конечно, ввод-вывод с использованием Selector
также может быть асинхронным... в зависимости от того, как вы используете API.)
В отличие от этого, если вы читаете на FileChannel
и в настоящее время нет доступных данных, поток блокирует... (обычно), пока данные не станут доступными.
Ответ 2
Проще говоря, большинство операционных систем не обрабатывают обычные файлы как что-то, что может блокировать - поэтому они не позволяют вам явно установить их в неблокирующее состояние.