Что вернет метод чтения, если он прочитает файл и встретит байт, равный 1
Обновлено: 21.11.2024
Как заглянуть в строку! , но просматривает байты, помещает их в строку байтов и возвращает число прочитанных байтов.
( peek-bytes-avail! | bstr | tr>
skip-bytes-amt | |
[ | прогресс |
в | |
начальная позиция | |
end-pos ] ) |
Результат peek-bytes-avail! равен 0 только в том случае, если прогресс становится готовым до просмотра байтов.
( peek-bytes-avail!* | bstr | < /tr>
skip-bytes-amt | |
[ | прогресс |
в | |
начальная позиция | tr>|
end-pos ] ) |
Подобно read-bytes-avail!* , но для просмотра и с параметрами skip-bytes-amt и progress, такими как peek-bytes-avail! . Поскольку эта процедура никогда не блокируется, она может завершиться до того, как из порта будет доступно даже skip-bytes-amt bytes.
( peek-bytes-avail!/enable-break | bstr td> |
skip-bytes-amt | |
[ | прогресс |
в | |
начальная позиция | |
end-pos ] ) |
Подобно read-bytes-avail!/enable-break , но для просмотра и с параметрами skip-bytes-amt и progress, такими как peek-bytes-avail! .
Изменено в версии 6.8.0.2 базы пакетов: добавлены аргументы special-wrap и source-name.
Изменено в версии 6.8.0.2 базы пакетов: добавлены аргументы special-wrap и source-name.
То же, что и read-char , но выполняет просмотр вместо чтения и пропускает skip-bytes-amt байты (не символы) в начале порта.
То же, что peek-char , но если входной порт возвращает небайтовое значение после skip-bytes-amt байтовых позиций, то результат зависит от special-wrap :
Если special-wrap является процедурой, то для получения результата применяется специальное значение (как для read-char-or-special ).
Если special-wrap имеет значение ' special , то ' special возвращается вместо специального значения — без вызова процедуры специального значения, которая возвращается реализацией входного порта.
Изменено в версии 6.8.0.2 базы пакетов: добавлены аргументы special-wrap и source-name.
Изменено в версии 6.90.0.16: добавлено ' special как опция для special-wrap .
Похож на peek-char-or-special , но просматривает и возвращает байт вместо символа и поддерживает аргумент прогресса, такой как peek-bytes-avail! .
Изменено в версии 6.8.0.2 базы пакетов: добавлены аргументы special-wrap и source-name.
Изменено в версии 6.90.0.16: добавлено ' special как опция для special-wrap .
Возвращает синхронизируемое событие (см. События), которое становится готовым к синхронизации после любого последующего чтения из in или после закрытия in. После того, как событие становится готовым, оно остается готовым. Результатом синхронизации события прогресса является само событие прогресса.
Попытки зафиксировать как прочитанные первые amt ранее просмотренные байты, специальные значения, не являющиеся байтами, и eof s из in , или первое eof или специальное значение, полученное из in . Можно зафиксировать eof в середине потока, но eof, когда порт исчерпан, не обязательно фиксируется, так как он не соответствует данным в потоке.
Чтение фиксируется только в том случае, если прогресс не становится готовым первым (т. е. если ни один другой процесс не выполняет чтение первым) и только если evt выбирается синхронизацией в пределах порта-фиксации-просмотра (в этом случае результатом события является игнорируется); evt должно быть событием установки канала, каналом, семафором, событием просмотра семафора, событием всегда или событием никогда. Приостановка потока, вызывающего port-commit-peeked, может или не может помешать выполнению фиксации.
Если данные не были загружены и прогресс не готов, возникает исключение exn:fail:contract. Если в текущем начале потока in было просмотрено меньше элементов, чем amt, то только просмотренные элементы фиксируются как прочитанные. Если поток in в настоящее время начинается с eof или небайтового специального значения, то только eof или специальное значение фиксируется как прочитанное.
Если прогресс не является результатом применения port-progress-evt к in , возникает исключение exn:fail:contract.
Байт готов? и готовы? функции подходят для относительно небольшого числа приложений, поскольку порты предназначены для поддержки потоковой передачи данных среди одновременно работающих производителей и потребителей; тот факт, что байт или символ не готовы в какой-то момент, не обязательно означает, что производитель закончил поставку данных. (Кроме того, если порт имеет несколько потребителей, данные могут потребляться между моментом, когда данный процесс использует byte-ready? для опроса порта, и моментом, когда он считывает данные из порта.) Использование byte-ready? имеет смысл, если вы внедряете свой собственный планировщик или знаете, что реализация и использование порта особенно ограничены.
Видите байт-готов? для примечания о том, как байт готов? и готовы? редко бывают правильным выбором.
Основные спецификации Open Group, выпуск 6
Стандарт IEEE 1003.1, издание 2004 г.
Авторские права © IEEE и The Open Group, 2001-2004. Все права защищены. Более новая редакция этого документа находится здесь
ОБЗОР
ОПИСАНИЕ
Если ни один процесс не открыл канал для записи, read() возвращает 0, чтобы указать конец файла.
Если в каком-то процессе канал открыт для записи и установлен O_NONBLOCK, функция read() должна вернуть -1 и установить для errno значение [EAGAIN].< /p>
Если в каком-то процессе канал открыт для записи, а O_NONBLOCK не установлен, read() должен заблокировать вызывающий поток до тех пор, пока некоторые данные не будут записаны или канал не будет закрыт всеми процессами, которые имели трубка открыта для письма.
Если установлен O_NONBLOCK, read() возвращает -1 и устанавливает для errno значение [EAGAIN].
Если O_NONBLOCK не установлен, read() должен заблокировать вызывающий поток, пока некоторые данные не станут доступными.
Использование флага O_NONBLOCK не действует, если доступны некоторые данные.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
После успешного завершения read() [XSI] и pread() должны возвращать неотрицательное целое число, указывающее количество фактически прочитанных байтов. В противном случае функции должны вернуть -1 и установить errno для указания ошибки.
ОШИБКИ
Функции read() и [XSI] pread() завершатся ошибкой, если:
[EAGAIN] Флаг O_NONBLOCK установлен для файловый дескриптор, и поток будет задержан. [EBADF] Аргумент fildes не является допустимым файловым дескриптором, открытым для чтения. [EBADMSG] [XSR] Файл представляет собой файл STREAM, для которого установлен обычный режим управления, а сообщение, ожидающее чтения, включает управляющую часть. [EINTR] Операция чтения была прервана из-за получения сигнала, и данные не были переданы. [EINVAL] [XSR] STREAM или мультиплексор, на который ссылается fildes, связан (прямо или косвенно) ниже по потоку от мультиплексора. [EIO] Процесс является членом фонового процесса, пытающегося выполнить чтение со своего управляющего терминала, процесс игнорирует или блокирует сигнал SIGTTIN, или группа процессов потеряла связь. Эта ошибка также может быть вызвана причинами, определяемыми реализацией. [EISDIR] [XSI] Аргумент fildes указывает на каталог, и реализация не позволяет читать каталог с помощью read() или pread(). Вместо этого следует использовать функцию readdir(). [EOVERFLOW] Файл является обычным файлом, nbyte больше 0, начальная позиция находится перед концом файла, а начальная позиция больше или равна максимальному смещению, установленному в описание открытого файла, связанное с fildes.Функция read() завершается ошибкой, если:
[EAGAIN] или [EWOULDBLOCK] Дескриптор файла предназначен для сокета, помечен как O_NONBLOCK, и нет данных, ожидающих получения. . [ECONNRESET] Была предпринята попытка чтения сокета, и соединение было принудительно закрыто узлом. [ENOTCONN] Попытка чтения из неподключенного сокета. [ETIMEDOUT] Была предпринята попытка чтения сокета, и время ожидания передачи истекло.Функции read() и [XSI] pread() могут завершиться ошибкой, если:
[EIO] Произошла физическая ошибка ввода-вывода. [ENOBUFS] Недостаточно ресурсов в системе для выполнения операции. [ENOMEM] Недостаточно памяти для выполнения запроса. [ENXIO] Был сделан запрос несуществующего устройства, или запрос был за пределами возможностей устройства.Функция pread() не работает, а указатель файла остается неизменным, если:
[EINVAL] [XSI] Аргумент offset недействителен. . Значение отрицательное. [EOVERFLOW] [XSI] Файл является обычным файлом, и была предпринята попытка чтения с максимальным смещением, связанным с файлом, или за его пределами. [ENXIO] [XSI] Запрос выходит за рамки возможностей устройства. [ESPIPE] [XSI] fildes связан с каналом или FIFO.
ПРИМЕРЫ
Чтение данных в буфер
В следующем примере данные считываются из файла, связанного с файловым дескриптором fd, в буфер, на который указывает buf.
ПРИМЕНЕНИЕ ПРИЛОЖЕНИЯ
ОБОСНОВАНИЕ
В этом томе IEEE Std 1003.1-2001 не указано значение смещения файла после возврата ошибки; слишком много случаев. Для ошибок программирования, таких как [EBADF], эта концепция не имеет смысла, поскольку не задействован файл. Очевидно, что для ошибок, обнаруживаемых немедленно, таких как [EAGAIN], указатель не должен меняться. Однако после прерывания или аппаратной ошибки обновленное значение было бы очень полезно, и это поведение многих реализаций.
Обратите внимание, что read() нулевых байтов не изменяет время_время. Функция read(), которая запрашивает больше нуля байтов, но возвращает ноль, должна изменить st_atime.
Реализации разрешены, но не обязательны для выполнения проверка ошибок для запросов read() с нулевыми байтами.
Ввод и вывод
Использование операций ввода-вывода с большим количеством байтов всегда вызывало проблемы. Такие идеи, как lread() и lwrite() (с использованием и возвратом длинных значений), рассматривались одно время. Текущее решение состоит в использовании абстрактных типов в стандартной функции ISO C для read() и write(). Абстрактные типы могут быть объявлены так, чтобы существующие функции работали, но также могут быть объявлены так, чтобы более крупные типы могли быть представлены в будущих реализациях. Предполагается, что любые ограничения, ограничивающие максимальный диапазон size_t, также ограничивают переносимые запросы ввода-вывода тем же диапазоном. Этот том IEEE Std 1003.1-2001 также дополнительно ограничивает диапазон, требуя, чтобы количество байтов было ограничено, чтобы возвращаемое значение со знаком оставалось значимым. Поскольку возвращаемый тип также является (со знаком) абстрактным типом, количество байтов может быть определено реализацией так, чтобы оно было больше, чем может содержать int.
Разработчики стандарта рассматривали возможность добавления требований атомарности к каналу или FIFO. , но признал, что из-за природы конвейеров и FIFO не может быть гарантии атомарности чтения или любого другого размера, который способствовал бы переносимости приложений.
Этот том IEEE Std 1003.1-2001 требует, чтобы не предпринимались никакие действия для read() или write(), когда nbyte равен нулю. Это не должно иметь приоритет над обнаружением ошибок (таких как недопустимые указатели буфера или файловые дескрипторы). Это согласуется с остальной частью этого тома IEEE Std 1003.1-2001, но формулировка здесь может быть неправильно истолкована, поскольку требует обнаружения нулевого регистра перед любыми другими ошибками. Нулевое значение считается правильным значением, для которого семантика не является операцией.
Ввод-вывод должен быть атомарным для обычных файлов, каналов и FIFO. Атомарность означает, что все байты одной операции, начавшейся вместе, заканчиваются вместе без чередования других операций ввода-вывода. Это известный атрибут терминалов, что это не соблюдается, и терминалы явно (и неявно постоянно) исключаются, что делает поведение неопределенным. Поведение для других типов устройств также не указано, но формулировка подразумевает, что будущие стандарты могут указать атомарность (или нет).
Были рекомендации добавить параметры формата для чтения () и write() для обработки сетевых передач между разнородными файловыми системами и базовыми типами оборудования. Такое средство может потребоваться для поддержки представления сервисов уровня OSI. Однако было определено, что это должно соответствовать аналогичным возможностям языка C, и это выходит за рамки этого тома IEEE Std 1003.1-2001. Эта концепция была предложена разработчикам стандарта ISO C для рассмотрения в качестве возможной области для будущей работы.
В 4.3 BSD функции read() или write (), прерываемая сигналом перед передачей каких-либо данных, по умолчанию не возвращает ошибку [EINTR], а перезапускается. В версиях 4.2 BSD, 4.3 BSD и Восьмой редакции есть дополнительная функция select(), целью которой является приостановка до выполнения заданного действия (данные для чтения, место для записи и т. д.). обнаружен на указанных файловых дескрипторах. Обычно в приложениях, написанных для этих систем, select() используется перед read() в ситуациях (например, при вводе с клавиатуры), когда прерывание ввода-вывода из-за требуется сигнал.
Вопрос о том, какие файлы или типы файлов являются прерываемыми, считается проблемой дизайна реализации. На это часто влияют в первую очередь проблемы с оборудованием и надежностью.
Нет ссылок на действия, предпринятые после «неисправимой ошибки». Считается, что описание того, что происходит в случае аппаратных ошибок, выходит за рамки этого тома IEEE Std 1003.1-2001.
Предыдущие версии IEEE Std 1003.1-2001 допускали два очень разных поведения в отношении обработка прерываний.Чтобы свести к минимуму возникшую путаницу, было решено, что стандарт IEEE Std 1003.1-2001 должен поддерживать только одно из этих режимов. Историческая практика в системах, производных от AT&T, заключалась в том, что read() и write() возвращали -1 и устанавливали errno в [EINTR] при прерывании. после того, как некоторые, но не все запрошенные данные были переданы. Однако FIPS 151-1 и FIPS 151-2 Министерства торговли США требуют исторического поведения BSD, при котором read() и write() возвращают количество байтов. фактически передано до прерывания. Если при передаче каких-либо данных возвращается -1, исправить ошибку на доступном для поиска устройстве будет сложно, а на недоступном для поиска устройстве невозможно. Большинство новых реализаций поддерживают это поведение. Стандарт IEEE Std 1003.1-2001 требует возврата количества переданных байтов.
Стандарт IEEE 1003.1-2001 не определяет, когда реализация, которая буферизует read(), фактически перемещает данные в предоставленный пользователем буфер, поэтому реализация может сделать это в самый последний возможный момент. Следовательно, прерывание, поступившее ранее, может не привести к тому, что функция read() вернет неполный счетчик байтов, а скорее вернет -1 и установит для errno значение [EINTR].
Также было рассмотрено объединение двух предыдущих вариантов и установка для errno значения [EINTR] при возврате короткого счетчика. Однако не только нет существующей практики, реализующей это, но и противоречит идее о том, что при установке errno ответственная функция должна возвращать -1.
БУДУЩИЕ НАПРАВЛЕНИЯ
СМ. ТАКЖЕ
ИСТОРИЯ ИЗМЕНЕНИЙ
Впервые выпущено в выпуске 1. Создано на основе выпуска 1 SVID.
В компьютерных науках файл — это ресурс, используемый для дискретной записи данных на запоминающее устройство компьютера. В Java ресурс обычно представляет собой объект, реализующий интерфейс AutoCloseable.
Чтение файлов и ресурсов имеет множество применений:
- Статистика, аналитика и отчеты
- Машинное обучение
- Работа с большими текстовыми файлами или журналами
Иногда эти файлы могут быть абсурдно большими, храниться в гигабайтах или терабайтах, и их полное чтение неэффективно.
Возможность читать файл построчно дает нам возможность искать только нужную информацию и прекращать поиск, как только мы находим то, что ищем. Это также позволяет нам разбивать данные на логические части, как если бы файл был в формате CSV.
Есть несколько различных вариантов, когда вам нужно прочитать файл построчно.
Сканер
Один из самых простых способов чтения файла построчно в Java можно реализовать с помощью класса Scanner. Сканер разбивает входные данные на токены, используя шаблон разделителя, которым в нашем случае является символ новой строки:
Метод hasNextLine() возвращает значение true, если во входных данных этого сканера есть другая строка, но сам сканер в этот момент не проходит дальше ввода и не считывает никаких данных.
Чтобы прочитать строку и двигаться дальше, мы должны использовать метод nextLine(). Этот метод продвигает сканер за текущую строку и возвращает ввод, который не был достигнут изначально. Этот метод возвращает оставшуюся часть текущей строки, исключая любой разделитель строк в конце строки. Затем позиция чтения устанавливается в начало следующей строки, которая будет прочитана и возвращена при повторном вызове метода.
Поскольку этот метод продолжает искать во входных данных разделитель строк, он может буферизовать весь ввод при поиске конца строки, если разделители строк отсутствуют.
Буферизованное чтение
Класс BufferedReader представляет собой эффективный способ чтения символов, массивов и строк из потока ввода символов.
Как указано в названии, этот класс использует буфер. Объем данных, которые буферизуются по умолчанию, составляет 8192 байта, но для повышения производительности можно задать другой размер:
Файл или экземпляр класса File не является подходящим источником данных для BufferedReader , поэтому нам нужно использовать FileReader , который расширяет InputStreamReader . Это удобный класс для чтения информации из текстовых файлов, и он не обязательно подходит для чтения необработанного потока байтов:
Инициализация буферизованного считывателя была написана с использованием синтаксиса try-with-resources, специфичного для Java 7 или более поздней версии. Если вы используете более старую версию, вы должны инициализировать переменную br перед оператором try и закрыть ее в блоке finally.
Вот пример предыдущего кода без синтаксиса try-with-resources:
Код будет перебирать строки предоставленного файла и остановится, когда встретит нулевую строку, которая является концом файла.
Не запутайтесь, так как нуль не равен пустой строке, и файл будет читаться до конца.
Метод линий
В классе BufferedReader также есть метод lines, возвращающий Stream . Этот поток содержит строки, которые были прочитаны BufferedReader в качестве его элементов.
Вы можете легко преобразовать этот поток в список, если вам нужно:
Чтение этого списка аналогично чтению потока, описанному в следующем разделе:
Бесплатная электронная книга: Git Essentials
Ознакомьтесь с нашим практическим руководством по изучению Git, включающим передовые практики, общепринятые стандарты и памятку. Перестаньте гуглить команды Git и на самом деле изучите их!
Потоки Java 8
Если вы уже знакомы с потоками Java 8, вы можете использовать их как более чистую альтернативу устаревшему циклу:
Здесь мы снова используем синтаксис try-with-resources, инициализируя поток строк с помощью статического вспомогательного метода Files.lines(). Справочник по методу System.out::println используется для демонстрационных целей, и вы должны заменить его любым кодом, который вы будете использовать для обработки строк текста.
Помимо чистого API, потоки очень полезны, когда вы хотите применить несколько операций к данным или что-то отфильтровать.
Предположим, у нас есть задача напечатать все строки, найденные в заданном текстовом файле и заканчивающиеся символом «/». Строки должны быть преобразованы в верхний регистр и отсортированы по алфавиту.
Изменив наш первоначальный пример "Streams API", мы получим очень чистую реализацию:
Метод filter() возвращает поток, состоящий из элементов этого потока, соответствующих заданному предикату. В нашем случае мы оставляем только те, которые заканчиваются на "/".
Метод map() возвращает поток, состоящий из результатов применения заданной функции к элементам этого потока.
Метод toUpperCase() класса String помогает нам достичь желаемого результата и используется здесь как ссылка на метод, как и вызов println из нашего предыдущего примера.
Метод sorted() возвращает поток, состоящий из элементов этого потока, отсортированных в естественном порядке. Вы также можете указать собственный Comparator , и в этом случае сортировка будет выполняться в соответствии с ним.
Хотя порядок операций для методов filter() , sorted() и map() может быть изменен, forEach() всегда следует помещать в конец, поскольку это терминальная операция. Он возвращает void, и, если уж на то пошло, к нему больше ничего нельзя привязать.
Общие ресурсы Apache
Если вы уже используете Apache Commons в своем проекте, вам может понадобиться помощник, который считывает все строки из файла в список:
Помните, что при таком подходе все строки из файла считываются в список строк, и только после этого начинается выполнение цикла for. Это может занять много времени, и дважды подумайте, прежде чем использовать его для больших текстовых файлов.
Заключение
Существует несколько способов чтения файла построчно в Java, и выбор подходящего подхода полностью зависит от программиста. Вы должны подумать о размере файлов, которые вы планируете обрабатывать, требованиях к производительности, стиле кода и библиотеках, которые уже есть в проекте. Не забудьте протестировать некоторые крайние случаи, такие как огромные, пустые или несуществующие файлы, и вам будет удобно работать с любым из предоставленных примеров.
Читайте также: