Очистить или “сбросить” файловый дескриптор без read()?
-
20-09-2019 - |
Вопрос
(Примечание:Это не вопрос о том, как смыть write()
.Это и есть тот самый другой конец об этом, так сказать.)
Можно ли очистить файловый дескриптор, в котором есть данные для чтения без вынужденный read()
это?Возможно, вас не интересуют данные, и поэтому чтение всего этого приведет к пустой трате места и циклов, для которых вы могли бы найти лучшее применение.
Если это невозможно в POSIX, есть ли в каких-либо операционных системах какие-либо непереносимые способы сделать это?
Обновить: Пожалуйста, обратите внимание, что я говорю о файловые дескрипторы, не Стримы.
Решение
В потоках доступен fclean, который очищает буфер записи и возвращает буфер чтения обратно в систему ввода-вывода.
http://www.gnu.org/software/hello/manual/libc/Cleaning-Streams.html
Если то, что вы действительно хотите сделать, это пропустить байты, изменение положения указателя на файл является правильным действием.Просто пропустите вперед столько байтов, сколько вы не хотите читать.
http://www.gnu.org/software/hello/manual/libc/File-Position-Primitive.html#File-Position-Primitive
Другие советы
Если вы имеете дело с tty, взгляните на tcflush()
:
#include <termios.h>
int tcflush(int fildes, int queue_selector);
После успешного завершения tcflush() отбрасывает данные, записанные в объект , на который ссылается fildes (открытый файл дескриптор, связанный с терминалом) но не переданные или полученные данные но не читается, в зависимости от значения из queue_selector [...]
Для POSIX используйте lseek(2)
или lseek64(3)
стремиться вперед.Для Windows используйте SetFilePointer()
или SetFilePointerEx()
.
Ни read(), ни flush() не являются частью стандартных C или C ++, но, безусловно, ни одна из стандартных функций не поддерживает очистку входных потоков.Я бы предположил, что это отражает что-то, недоступное в базовых операционных системах.Обычный способ вообще избежать чтения чего-либо - это пропустить это с помощью какой-нибудь функции seek().
Если вы знаете количество байтов, которые нужно пропустить, вы можете сделать lseek(fd, n, SEEK_CUR);
для систем POSIX.Есть fseek()
также, для FILE *
Объекты.В POSIX, я думаю, вы можете безопасно выполнять поиск после конца файла, идея заключается в том, что если позже будет записано больше данных, чтобы данные проходили мимо позиции, установленной с lseek()
, теперь вы сможете прочитать больше данных.
Согласно это, система POSIX сделает это на fflush(stream);
.
Для потока, открытого для чтения, если файл еще не находится в EOF, и файл способен к поиску, смещение файла базового описания открытого файла должно быть скорректировано таким образом, чтобы следующая операция над описанием открытого файла имела дело с байтом после последнего, прочитанного из или записанного в сбрасываемый поток.
Linux 2.6.17 или более поздней версии с библиотекой GNU C версии 2.5 или более поздней содержат splice()
системный вызов, который может быть использован для отправки данных из одного файлового дескриптора в другой без копирования его в пространство пользователя.Это можно использовать для удаления данных, просто открыв /dev/null
и splice
ввод данных из дескриптора исходного файла в /dev/null
дескриптор файла.