Spec-Zone.ru › Haskell 7

System.IO

Авторские права (c) Университет Глазго 2001
Лицензия BSD (см. файл libraries/base/LICENSE)
Поддержка libraries@haskell.org
Устойчивость стабильная
Переносимость переносимая
Safe Haskell Надёжная
Язык Haskell2010

Содержание

  • Монад IO
  • Файлы и дескрипторы
    • Стандартные дескрипторы
  • Открытие и закрытие файлов
    • Открытие файлов
    • Закрытие файлов
    • Особые случаи
    • Блокировка файлов
  • Операции с дескрипторами
    • Определение и изменение размера файла
    • Обнаружение конца входных данных
    • Операции с буфером
    • Перемещение указателя дескриптора
    • Свойства дескриптора
    • Операции с терминалом (не переносимо: только GHC)
    • Отображение состояния дескриптора (не переносимо: только GHC)
  • Ввод и вывод текста
    • Ввод текста
    • Вывод текста
    • Особые случаи для стандартного ввода и вывода
  • Ввод и вывод двоичных данных
  • Временные файлы
  • Кодирование/декодирование Юникода
    • Кодировки Юникода
  • Преобразование символов новой строки

Описание

Стандартная библиотека ввода-вывода.

Монад IO

data IO a :: * -> * Исходный код

Значение типа IO a представляет собой вычисление, которое при выполнении выполняет некоторое ввод-вывод, прежде чем вернуть значение типа a.

Существует только один способ «выполнить» действие ввода-вывода: связать его с Main.main в вашей программе. При запуске программы ввод-вывод будет выполнен. Невозможно выполнить ввод-вывод из произвольной функции, если только эта функция сама не находится в IO монаде и не вызывается в какой-то момент, прямо или косвенно, из Main.main.

IO является монадой, поэтому действия IO можно комбинировать, используя либо синтаксис do, либо операции >> и >>= из класса Monad.

Примеры реализации

Monad IO
Functor IO
MonadFix IO
Applicative IO
(~) * a () => HPrintfType (IO a)
(~) * a () => PrintfType (IO a)

fixIO :: (a -> IO a) -> IO a Исходный код

Файлы и дескрипторы

type FilePath = String Исходный код

Имена файлов и каталогов — это значения типа String, точное значение которого зависит от операционной системы. Файлы могут быть открыты, что приводит к получению дескриптора, который затем можно использовать для работы с содержимым этого файла.

data Handle Исходный код

Haskell определяет операции для чтения и записи символов из и в файлы, представленные значениями типа Handle. Каждое значение этого типа является дескриптором: записью, используемой системой выполнения Haskell для управления вводом-выводом с объектами файловой системы. Дескриптор имеет, как минимум, следующие свойства:

  • управление вводом, выводом или обоими;
  • является открытым, закрытым или полузакрытым;
  • является ли объект позиционируемым;
  • отключена буферизация или она включена на основе строк или блоков;
  • буфер (длина которого может быть нулевой).

Большинство дескрипторов также будут иметь текущую позицию ввода-вывода, указывающую, где произойдёт следующая операция ввода или вывода. Дескриптор является читаемым, если он управляет только вводом или и вводом, и выводом; аналогично, он является записываемым, если он управляет только выводом или и вводом, и выводом. Дескриптор является открытым при первом выделении. После закрытия его нельзя больше использовать ни для ввода, ни для вывода, хотя реализация не может повторно использовать его хранилище, пока на него ссылаются. Дескрипторы находятся в классах Show и Eq. Строка, полученная при отображении дескриптора, зависит от системы; она должна содержать достаточную информацию для идентификации дескриптора для отладки. Два дескриптора равны в соответствии с == только в том случае, если они идентичны; не предпринимается попыток сравнить внутреннее состояние различных дескрипторов на равенство.

Примеры реализации

Eq Handle
Show Handle

Примечание GHC: дескриптор Handle будет автоматически закрыт, когда сборщик мусора обнаружит, что на него больше нет ссылок в программе. Однако, полагаться на это поведение не рекомендуется: поведение сборщика мусора непредсказуемо. Если возможно, используйте явное hClose, чтобы закрыть Handle при необходимости.

Стандартные дескрипторы

Три дескриптора выделяются при инициализации программы и изначально открыты.

stdin :: Handle Исходный код

Дескриптор, управляющий вводом из стандартного канала ввода Haskell-программы.

stdout :: Handle Исходный код

Дескриптор, управляющий выводом в стандартный канал вывода Haskell-программы.

stderr :: Handle Исходный код

Дескриптор, управляющий выводом в стандартный канал ошибок Haskell-программы.

Открытие и закрытие файлов

Открытие файлов

withFile :: FilePath -> IOMode -> (Handle -> IO r) -> IO r Исходный код

withFile name mode act открывает файл с помощью openFile и передает полученный дескриптор в вычисление act. Дескриптор будет закрыт при выходе из withFile, независимо от того, нормальным ли завершением это произошло, или было вызвано исключением. Если закрытие дескриптора вызывает исключение, то это исключение будет вызвано withFile вместо любого исключения, вызванного act.

openFile :: FilePath -> IOMode -> IO Handle Исходный код

Вычисление openFile file mode выделяет и возвращает новый открытый дескриптор для управления файлом file. Он управляет вводом, если mode равно ReadMode, выводом, если mode равно WriteMode или AppendMode, и и вводом, и выводом, если режим равен ReadWriteMode.

Если файл не существует и открыт для вывода, он должен быть создан как новый файл. Если mode равен WriteMode и файл уже существует, он должен быть усечён до нулевой длины. Некоторые операционные системы удаляют пустые файлы, поэтому нет гарантии, что файл будет существовать после openFile с mode WriteMode, если он не будет успешно записан позже. Дескриптор позиционируется в конце файла, если mode равно AppendMode, и в противном случае в начале (в этом случае его внутренняя позиция равна 0). Начальный режим буфера зависит от реализации.

Эта операция может завершиться ошибкой:

  • isAlreadyInUseError если файл уже открыт и не может быть повторно открыт;
  • isDoesNotExistError если файл не существует; или
  • isPermissionError если у пользователя нет разрешения на открытие файла.

Примечание: если вы будете работать с файлами, содержащими двоичные данные, вам следует использовать openBinaryFile.

data IOMode Исходный код

См. openFile

Конструкторы

ReadMode
WriteMode
AppendMode
ReadWriteMode

Примеры реализации

Enum IOMode
Eq IOMode
Ord IOMode
Read IOMode
Show IOMode
Ix IOMode

Закрытие файлов

hClose :: Handle -> IO () Source

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

Особые случаи

Эти функции также экспортированы в Prelude.

readFile :: FilePath -> IO String Source

Функция readFile считывает файл и возвращает содержимое файла в виде строки. Файл считывается лениво, по требованию, как и с getContents.

writeFile :: FilePath -> String -> IO () Source

Вычисление writeFile file str функции записывает строку str, в файл file.

appendFile :: FilePath -> String -> IO () Source

Вычисление appendFile file str функции добавляет строку str, к файлу file.

Обратите внимание, что writeFile и appendFile записывают литеральную строку в файл. Чтобы записать значение любого печатного типа, как с print, сначала используйте функцию show для преобразования значения в строку.

main = appendFile "squares" (show [(x,x*x) | x <- [0,0.1..2]])

Блокировка файлов

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

Предупреждение: операция readFile удерживает полузакрытый дескриптор файла до тех пор, пока все содержимое файла не будет израсходовано. Следовательно, попытка записи в файл (например, с помощью writeFile), который ранее был открыт с помощью readFile, обычно приведет к ошибке с isAlreadyInUseError.

Операции с дескрипторами

Определение и изменение размера файла

hFileSize :: Handle -> IO Integer Source

Для дескриптора файла hdl, присоединенного к физическому файлу, hFileSize hdl возвращает размер этого файла в байтах по 8 бит.

hSetFileSize :: Handle -> Integer -> IO () Source

hSetFileSize hdl size обрезает физический файл с дескриптором hdl до size байтов.

Обнаружение конца ввода

hIsEOF :: Handle -> IO Bool Source

Для читаемого дескриптора файла hdl, hIsEOF hdl возвращает True, если дальнейший ввод не может быть получен из hdl или для физического файла, если текущая позиция ввода-вывода равна длине файла. В противном случае возвращается False.

ПРИМЕЧАНИЕ: hIsEOF может заблокироваться, потому что ему нужно попытаться прочитать из потока, чтобы определить, есть ли больше данных для чтения.

isEOF :: IO Bool Source

Вычисление isEOF идентично hIsEOF, за исключением того, что оно работает только на stdin.

Операции буферизации

data BufferMode Source

Поддерживаются три типа буферизации: буферизация строк, буферизация блоков или отсутствие буферизации. Эти режимы имеют следующие эффекты. Для вывода элементы выводятся или сбрасываются из внутреннего буфера в соответствии с режимом буферизации:

  • буферизация строк: весь буфер вывода сбрасывается всякий раз, когда выводится символ новой строки, буфер переполняется, вызывается hFlush или закрывается дескриптор файла.
  • буферизация блоков: весь буфер записывается, когда он переполняется, вызывается hFlush или закрывается дескриптор файла.
  • без буферизации: вывод записывается немедленно и никогда не хранится в буфере.

Реализация может сбрасывать буфер чаще, но не реже, чем указано выше. Буфер вывода опустошается сразу после записи.

Аналогично, ввод происходит в соответствии с режимом буферизации для дескриптора файла:

  • буферизация строк: когда буфер дескриптора файла не пуст, следующий элемент берется из буфера; в противном случае, когда буфер пуст, символы до и включая следующий символ новой строки считываются в буфер. Никакие символы недоступны, пока символ новой строки не станет доступным или буфер не заполнится.
  • буферизация блоков: когда буфер дескриптора файла становится пустым, следующий блок данных считывается в буфер.
  • без буферизации: следующий элемент ввода считывается и возвращается. Операция hLookAhead подразумевает, что даже дескриптор без буферизации может потребовать буфер на один символ.

Установленный по умолчанию режим буферизации при открытии дескриптора зависит от реализации и может зависеть от объекта файловой системы, связанного с этим дескриптором. Для большинства реализаций физические файлы обычно буферизируются блоками, а терминалы обычно буферизируются строками.

Конструкторы

NoBuffering

буферизация отключена, если это возможно.

LineBuffering

буферизация строк должна быть включена, если это возможно.

BlockBuffering (Maybe Int)

буферизация блоков должна быть включена, если это возможно. Размер буфера равен n элементам, если аргумент равен Just n, в противном случае размер зависит от реализации.

Примеры реализации

Eq BufferMode
Ord BufferMode
Read BufferMode
Show BufferMode

hSetBuffering :: Handle -> BufferMode -> IO () Source

Вычисление hSetBuffering hdl mode устанавливает режим буферизации для дескриптора hdl при последующих операциях чтения и записи.

Если режим буферизации изменяется с BlockBuffering или LineBuffering на NoBuffering, то

  • если hdl доступен для записи, буфер очищается, как для hFlush;
  • если hdl недоступен для записи, содержимое буфера отбрасывается.

Данная операция может завершиться неудачей с:

  • isPermissionError если дескриптор уже был использован для чтения или записи, и реализация не позволяет изменить режим буферизации.

hGetBuffering :: Handle -> IO BufferMode Source

Вычисление hGetBuffering hdl возвращает текущий режим буферизации для hdl.

hFlush :: Handle -> IO () Source

Действие hFlush hdl вызывает немедленную отправку в операционную систему всех элементов, буферизованных для вывода в дескрипторе hdl.

Данная операция может завершиться неудачей с:

  • isFullError если устройство заполнено;
  • isPermissionError если будет превышен лимит системных ресурсов. В этом случае не определено, будут ли символы в буфере отброшены или сохранены.

Перемещение дескрипторов

hGetPosn :: Handle -> IO HandlePosn Source

Вычисление hGetPosn hdl возвращает текущую позицию ввода-вывода для hdl как значение абстрактного типа HandlePosn.

hSetPosn :: HandlePosn -> IO () Source

Если вызов hGetPosn hdl возвращает позицию p, то вычисление hSetPosn p устанавливает позицию hdl на позицию, которую она занимала в момент вызова hGetPosn.

Данная операция может завершиться неудачей с:

  • isPermissionError если будет превышен лимит системных ресурсов.

data HandlePosn Source

Реализации

Eq HandlePosn
Show HandlePosn

hSeek :: Handle -> SeekMode -> Integer -> IO () Source

Вычисление hSeek hdl mode i устанавливает позицию дескриптора hdl в зависимости от mode. Смещение i задается в байтах.

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

Данная операция может завершиться неудачей с:

  • isIllegalOperationError если дескриптор не поддерживает перемещение или не поддерживает запрошенный режим перемещения.
  • isPermissionError если будет превышен лимит системных ресурсов.

data SeekMode Source

Режим, определяющий действие hSeek hdl mode i.

Конструкторы

AbsoluteSeek

позиция hdl устанавливается в i.

RelativeSeek

позиция hdl устанавливается на смещение i от текущей позиции.

SeekFromEnd

позиция hdl устанавливается на смещение i от конца файла.

Реализации

Enum SeekMode
Eq SeekMode
Ord SeekMode
Read SeekMode
Show SeekMode
Ix SeekMode

hTell :: Handle -> IO Integer Source

Вычисление hTell hdl возвращает текущую позицию дескриптора hdl, как количество байтов от начала файла. Возвращённое значение может быть затем передано в hSeek для перемещения дескриптора в текущую позицию.

Данная операция может завершиться неудачей с:

  • isIllegalOperationError если дескриптор не поддерживает перемещение.

Свойства дескрипторов

hIsOpen :: Handle -> IO Bool Source

hIsClosed :: Handle -> IO Bool Source

hIsReadable :: Handle -> IO Bool Source

hIsWritable :: Handle -> IO Bool Source

hIsSeekable :: Handle -> IO Bool Source

Операции с терминалом (не переносимая: только GHC)

hIsTerminalDevice :: Handle -> IO Bool Source

Подключен ли дескриптор к терминалу?

hSetEcho :: Handle -> Bool -> IO () Source

Установить состояние эха для дескриптора, подключенного к терминалу.

hGetEcho :: Handle -> IO Bool Source

Получить состояние эха для дескриптора, подключенного к терминалу.

Отображение состояния дескриптора (не переносимая: только GHC)

hShow :: Handle -> IO String Source

hShow находится в IO монаде и дает более полный вывод, чем (чистый) экземпляр Show для Handle.

Текстовый ввод и вывод

Текстовый ввод

hWaitForInput :: Handle -> Int -> IO Bool Source

Вычисление hWaitForInput hdl t ожидает, пока ввод не станет доступен в дескрипторе hdl. Оно возвращает True, как только ввод становится доступен в hdl, или False, если ввод недоступен в течение t миллисекунд. Обратите внимание, что hWaitForInput ожидает, пока не станут доступны один или несколько полных символов, что означает, что ему необходимо выполнить декодирование, и поэтому он может завершиться ошибкой декодирования.

Если t меньше нуля, то hWaitForInput ожидает неопределенно долго.

Эта операция может завершиться ошибкой:

  • isEOFError если достигнут конец файла.
  • ошибка декодирования, если ввод начинается с недопустимой последовательности байтов в кодировке этого дескриптора.

ПРИМЕЧАНИЕ для пользователей GHC: если вы не используете флаг -threaded, hWaitForInput hdl t, где t >= 0 будет блокировать все остальные потоки Haskell на время вызова. В этом отношении он ведет себя как внешний вызов safe.

hReady :: Handle -> IO Bool Source

Вычисление hReady hdl указывает, доступен ли хотя бы один элемент для ввода из дескриптора hdl.

Эта операция может завершиться ошибкой:

  • isEOFError если достигнут конец файла.

hGetChar :: Handle -> IO Char Source

Вычисление hGetChar hdl считывает символ из файла или канала, управляемого hdl, блокируя до тех пор, пока символ не станет доступен.

Эта операция может завершиться ошибкой:

  • isEOFError если достигнут конец файла.

hGetLine :: Handle -> IO String Source

Вычисление hGetLine hdl считывает строку из файла или канала, управляемого hdl.

Эта операция может завершиться ошибкой:

  • isEOFError если при чтении первого символа строки встречен конец файла.

Если hGetLine встречает конец файла в любой другой точке при чтении строки, это рассматривается как разделитель строки, и возвращается (частичная) строка.

hLookAhead :: Handle -> IO Char Source

Вычисление hLookAhead возвращает следующий символ из дескриптора, не удаляя его из буфера ввода, блокируя до тех пор, пока символ не станет доступен.

Эта операция может завершиться ошибкой:

  • isEOFError если достигнут конец файла.

hGetContents :: Handle -> IO String Source

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

Любая операция, которая завершается ошибкой из-за закрытия дескриптора, также завершается ошибкой, если дескриптор полузакрыт. Единственным исключением является hClose. Полузакрытый дескриптор закрывается:

  • если к нему применяется hClose;
  • если возникает ошибка ввода-вывода при чтении элемента из дескриптора;
  • или после того, как все содержимое дескриптора будет считано.

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

Любые ошибки ввода-вывода, обнаруженные, пока дескриптор полузакрыт, просто игнорируются.

Эта операция может завершиться ошибкой:

  • isEOFError если достигнут конец файла.

Текстовый вывод

hPutChar :: Handle -> Char -> IO () Source

Вычисление hPutChar hdl ch записывает символ ch в файл или канал, управляемый hdl. Символы могут буферизоваться, если буферизация включена для hdl.

Эта операция может завершиться ошибкой:

  • isFullError если устройство заполнено; или
  • isPermissionError если будет превышен другой системный ресурсный лимит.

hPutStr :: Handle -> String -> IO () Source

Вычисление hPutStr hdl s записывает строку s в файл или канал, управляемый hdl.

Эта операция может завершиться ошибкой:

  • isFullError если устройство заполнено; или
  • isPermissionError если будет превышен другой системный ресурсный лимит.

hPutStrLn :: Handle -> String -> IO () Source

То же самое, что и hPutStr, но добавляет символ новой строки.

hPrint :: Show a => Handle -> a -> IO () Source

Вычисление hPrint hdl t записывает строковое представление t, заданное функцией shows, в файл или канал, управляемый hdl, и добавляет символ новой строки.

Эта операция может завершиться ошибкой:

  • isFullError если устройство заполнено; или
  • isPermissionError если будет превышен другой системный ресурсный лимит.

Специальные случаи для стандартного ввода и вывода

Эти функции также экспортируются Prelude.

interact :: (String -> String) -> IO () Source

Функция interact принимает в качестве аргумента функцию типа String->String. Весь ввод со стандартного устройства ввода передается этой функции в качестве аргумента, а результирующая строка выводится на стандартное устройство вывода.

putChar :: Char -> IO () Source

Записать символ на стандартное устройство вывода (то же самое, что и hPutChar stdout).

putStr :: String -> IO () Source

Записать строку на стандартное устройство вывода (то же самое, что и hPutStr stdout).

putStrLn :: String -> IO () Source

То же самое, что и putStr, но добавляет символ новой строки.

print :: Show a => a -> IO () Source

Функция print выводит значение любого печатаемого типа на стандартное устройство вывода. Печатаемые типы — это те, которые являются экземплярами класса Show; print преобразует значения в строки для вывода с помощью операции show и добавляет символ новой строки.

Например, программу для вывода первых 20 целых чисел и их степеней 2 можно написать так:

main = print ([(n, 2^n) | n <- [0..19]])

getChar :: IO Char Source

Считывает символ со стандартного устройства ввода (аналогично hGetChar stdin).

getLine :: IO String Source

Считывает строку со стандартного устройства ввода (аналогично hGetLine stdin).

getContents :: IO String Source

Операция getContents возвращает весь введённый пользователем текст как одну строку, которая считывается лениво по мере необходимости (аналогично hGetContents stdin).

readIO :: Read a => String -> IO a Source

Функция readIO похожа на read, за исключением того, что она сигнализирует об ошибке разбора в монаде IO, а не завершает программу.

readLn :: Read a => IO a Source

Функция readLn объединяет getLine и readIO.

Ввод и вывод двоичных данных

withBinaryFile :: FilePath -> IOMode -> (Handle -> IO r) -> IO r Source

withBinaryFile name mode act открывает файл в режиме openBinaryFile и передаёт полученный дескриптор вычислению act. Дескриптор будет закрыт при завершении withBinaryFile, независимо от того, было ли это нормальным завершением или возникновением исключения.

openBinaryFile :: FilePath -> IOMode -> IO Handle Source

Аналогично openFile, но открывает файл в двоичном режиме. В Windows, чтение файла в текстовом режиме (по умолчанию) преобразует CRLF в LF, а запись преобразует LF в CRLF. Это обычно то, что нужно для текстовых файлов. В случае с двоичными файлами это нежелательно; также, как обычно в системах Microsoft, текстовый режим считает символ Control-Z как EOF. Двоичный режим отключает все специальное обращение с символами конца строки и конца файла. (См. также hSetBinaryMode.)

hSetBinaryMode :: Handle -> Bool -> IO () Source

Устанавливает двоичный режим (True) или текстовый режим (False) для открытого дескриптора. (См. также openBinaryFile.)

Это эквивалентно вызову hSetEncoding с char8, вместе с hSetNewlineMode с noNewlineTranslation.

hPutBuf :: Handle -> Ptr a -> Int -> IO () Source

hPutBuf hdl buf count записывает count 8-битных байтов из буфера buf в дескриптор hdl. Возвращает ().

hPutBuf игнорирует любые кодировки, которые могут применяться к Handle, записывая байты напрямую в подлежащий файл или устройство.

hPutBuf игнорирует действующую TextEncoding и NewlineMode на Handle, и записывает байты напрямую.

Эта операция может завершиться неудачно:

  • ResourceVanished если дескриптор является конвейром или сокетом, и конец для чтения закрыт. (Если это POSIX-система, и программа не запросила игнорирование SIGPIPE, то вместо этого может быть отправлено SIGPIPE, стандартное действие которого — завершить программу).

hGetBuf :: Handle -> Ptr a -> Int -> IO Int Source

hGetBuf hdl buf count считывает данные из дескриптора hdl в буфер buf до тех пор, пока не достигнет конца файла или не будет прочитано count 8-битных байтов. Возвращает количество фактически прочитанных байтов. Может быть равно нулю, если конец файла достигнут до чтения любых данных (или если count равно нулю).

hGetBuf никогда не вызывает исключение EOF, вместо этого возвращает значение меньше count.

Если дескриптор является конвейром или сокетом, и конец для записи закрыт, hGetBuf будет вести себя так, как будто достигнут конец файла.

hGetBuf игнорирует действующую TextEncoding и NewlineMode на Handle, и считывает байты напрямую.

hGetBufSome :: Handle -> Ptr a -> Int -> IO Int Source

hGetBufSome hdl buf count считывает данные из дескриптора hdl в буфер buf. Если какие-либо данные доступны для чтения, то hGetBufSome возвращает их немедленно; блокируется только если нет данных для чтения.

Возвращает количество фактически прочитанных байтов. Может быть равно нулю, если конец файла достигнут до чтения любых данных (или если count равно нулю).

hGetBufSome никогда не вызывает исключение EOF, вместо этого возвращает значение меньше count.

Если дескриптор является конвейром или сокетом, и конец для записи закрыт, hGetBufSome будет вести себя так, как будто достигнут конец файла.

hGetBufSome игнорирует действующую TextEncoding и NewlineMode на Handle, и считывает байты напрямую.

hPutBufNonBlocking :: Handle -> Ptr a -> Int -> IO Int Source

hGetBufNonBlocking :: Handle -> Ptr a -> Int -> IO Int Source

hGetBufNonBlocking hdl buf count считывает данные из дескриптора hdl в буфер buf до тех пор, пока не достигнет конца файла, или не будет прочитано count 8-битных байтов, или пока нет доступных данных для немедленного чтения.

hGetBufNonBlocking идентично hGetBuf, за исключением того, что она никогда не будет блокироваться в ожидании появления данных, а возвращает только те данные, которые доступны. Чтобы подождать появления данных перед вызовом hGetBufNonBlocking, используйте hWaitForInput.

Если дескриптор является конвейром или сокетом, и конец для записи закрыт, hGetBufNonBlocking будет вести себя так, как будто достигнут конец файла.

hGetBufNonBlocking игнорирует действующую TextEncoding и NewlineMode на Handle, и считывает байты напрямую.

ПРИМЕЧАНИЕ: в Windows эта функция работает некорректно; она ведет себя идентично hGetBuf.

Временные файлы

openTempFile Source

Аргументы

:: FilePath

Директория, в которой должен быть создан файл

-> String

Шаблон имени файла. Если шаблон "foo.ext", то создаваемый файл будет "fooXXX.ext", где XXX — некоторое случайное число.

-> IO (FilePath, Handle)

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

Файл создаётся с разрешениями, позволяющими только текущему пользователю читать/писать в него.

В некоторых случаях (см. ниже), файл будет создан безопасно в том смысле, что злоумышленник не сможет заставить openTempFile перезаписать другой файл в файловой системе, используя ваши учетные данные, разместив символические ссылки (в Unix) в месте, где должен быть создан временный файл. В Unix используются флаги O_CREAT и O_EXCL для предотвращения этой атаки, но обратите внимание, что O_EXCL иногда не поддерживается на NFS файловых системах, поэтому если вы полагаетесь на это поведение, лучше использовать только локальные файловые системы.

openBinaryTempFile :: FilePath -> String -> IO (FilePath, Handle) Source

Как openTempFile, но открывает файл в бинарном режиме. См. openBinaryFile для дополнительных комментариев.

openTempFileWithDefaultPermissions :: FilePath -> String -> IO (FilePath, Handle) Source

Как openTempFile, но использует права доступа по умолчанию.

openBinaryTempFileWithDefaultPermissions :: FilePath -> String -> IO (FilePath, Handle) Source

Как openBinaryTempFile, но использует права доступа по умолчанию.

Кодирование/декодирование Unicode

Поток в текстовом режиме Handle имеет ассоциированную TextEncoding, которая используется для декодирования байтов в символы Unicode при чтении и кодирования символов Unicode в байты при записи.

Кодировка по умолчанию TextEncoding совпадает с кодировкой по умолчанию вашей системы, которая также доступна как localeEncoding. (Примечание GHC: в Windows мы в настоящее время не поддерживаем двухбайтовые кодировки; если кодовая страница консоли не поддерживается, то localeEncoding будет latin1.)

Ошибки кодирования и декодирования всегда обнаруживаются и сообщаются, за исключением ленивого ввода-вывода (hGetContents, getContents и readFile), где ошибка декодирования просто приводит к завершению потока символов, как и другие ошибки ввода-вывода.

hSetEncoding :: Handle -> TextEncoding -> IO () Source

Действие hSetEncoding hdl encoding изменяет текстовую кодировку для дескриптора hdl на encoding. Кодировка по умолчанию при создании Handle — это localeEncoding, а именно кодировка по умолчанию для текущей локали.

Чтобы создать Handle без какой-либо кодировки, используйте openBinaryFile. Чтобы остановить дальнейшее кодирование или декодирование существующего Handle, используйте hSetBinaryMode.

hSetEncoding может потребоваться очистить буферизованные данные, чтобы изменить кодировку.

hGetEncoding :: Handle -> IO (Maybe TextEncoding) Source

Возвращает текущую TextEncoding для указанного Handle, или Nothing, если Handle находится в бинарном режиме.

Обратите внимание, что TextEncoding ничего не запоминает о состоянии используемого кодера/декодера в этом Handle. Например, если используется кодировка UTF-16, то использование hGetEncoding и hSetEncoding для сохранения и восстановления кодировки может привести к записи в файл дополнительной метки порядка байтов.

Кодировки Unicode

data TextEncoding Source

TextEncoding — это спецификация схемы преобразования между последовательностями байтов и последовательностями символов Unicode.

Например, UTF-8 — это кодировка символов Unicode в последовательность байтов. TextEncoding для UTF-8 — это utf8.

Экземпляры

Show TextEncoding

latin1 :: TextEncoding Source

Кодировка Latin1 (ISO8859-1). Эта кодировка напрямую отображает байты на первые 256 кодовых точек Unicode и, таким образом, не является полной кодировкой Unicode. Попытка записать символ больше, чем '\255', в Handle с использованием кодировки latin1 приведет к ошибке.

utf8 :: TextEncoding Source

Кодировка Unicode UTF-8

utf8_bom :: TextEncoding Source

Кодировка Unicode UTF-8 с меткой порядка байтов (BOM; байтовая последовательность 0xEF 0xBB 0xBF). Эта кодировка ведет себя как utf8, за исключением того, что на входе последовательность BOM игнорируется в начале потока, а на выходе последовательность BOM добавляется в начало.

Метка порядка байтов строго говоря не является необходимой в UTF-8, но иногда используется для идентификации кодировки файла.

utf16 :: TextEncoding Source

Кодировка Unicode UTF-16 (следует использовать метку порядка байтов для указания порядка байтов).

utf16le :: TextEncoding Source

Кодировка Unicode UTF-16 (little-endian)

utf16be :: TextEncoding Source

Кодировка Unicode UTF-16 (big-endian)

utf32 :: TextEncoding Source

Кодировка Unicode UTF-32 (следует использовать метку порядка байтов для указания порядка байтов).

utf32le :: TextEncoding Source

Кодировка Unicode UTF-32 (little-endian)

utf32be :: TextEncoding Source

Кодировка Unicode UTF-32 (big-endian)

localeEncoding :: TextEncoding Source

Кодировка Unicode текущей локали

Это начальная кодировка локали: если она была впоследствии изменена с помощью setLocaleEncoding, это значение не будет отражать это изменение.

char8 :: TextEncoding Source

Кодировка, в которой кодовые точки Unicode преобразуются в байты путем взятия кодовой точки по модулю 256. При декодировании байты напрямую преобразуются в эквивалентную кодовую точку.

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

С версии: 4.4.0.0

mkTextEncoding :: String -> IO TextEncoding Source

Ищет именованную кодировку Unicode. Может завершиться ошибкой с

  • isDoesNotExistError если кодировка неизвестна

Набор известных кодировок зависит от системы, но включает как минимум:

  • UTF-8
  • UTF-16, UTF-16BE, UTF-16LE
  • UTF-32, UTF-32BE, UTF-32LE

Существует дополнительная нотация (заимствованная из GNU iconv) для указания того, как обрабатываются недопустимые символы:

  • суффикс //IGNORE, например UTF-8//IGNORE, приведет к игнорированию всех недопустимых последовательностей на входе, а на выходе будут отброшены все кодовые точки, которые не имеют представления в целевой кодировке.
  • суффикс //TRANSLIT выберет символ замены для недопустимых последовательностей или кодовых точек.
  • суффикс //ROUNDTRIP будет использовать механизм экранирования в стиле PEP383 для представления любых недопустимых байтов на входе как кодовых точек Unicode (в частности, как одиночных суррогатных пар, которые обычно являются недопустимыми в UTF-32). На выходе эти специальные кодовые точки обнаруживаются и преобразуются обратно в соответствующие исходные байты.

Теоретически, этот механизм позволяет произвольным данным проходить через String без потери данных. На практике существуют два ограничения, о которых следует помнить:

  1. Это может сработать только для кодировок, являющихся расширением ASCII, так как по соображениям безопасности мы отказываемся от экранирования байтов, меньших 128. Многие кодировки, представляющие интерес, являются расширениями ASCII (в частности, вы можете предположить, что кодировка локали является расширением ASCII), но многие (например, UTF-16) таковыми не являются.
  2. Если основная кодировка сама по себе необратима, этот механизм может потерпеть неудачу. Обратимые кодировки — это те, которые имеют инъективное отображение в Юникод. Почти все кодировки соответствуют этому критерию, но некоторые — нет. Заметим, что Shift-JIS (CP932) и Big5 содержат несколько различных кодировок одного и того же кодового пункта Юникода.

В Windows вы можете получить доступ к поддерживаемым кодовым страницам с префиксом CP; например, "CP1250".

Преобразование символов новой строки

В Haskell новая строка всегда представлена символом '\n'. Однако в файлах и внешних потоках символов новая строка может быть представлена другой последовательностью символов, например, '\r\n'.

В текстовом режиме Handle есть связанный NewlineMode, который определяет, как преобразовывать символы новой строки. NewlineMode указывает перевод вводных и выходных символов новой строки отдельно, так что, например, вы можете переводить '\r\n' в '\n' на входе, но оставлять новые строки как '\n' на выходе.

По умолчанию NewlineMode для Handle — nativeNewlineMode, что не производит преобразования в системах Unix, но преобразует '\r\n' в '\n' и обратно в системах Windows.

В бинарном режиме Handle преобразование символов новой строки не выполняется вообще.

hSetNewlineMode :: Handle -> NewlineMode -> IO () Исходный код

Установите NewlineMode для указанного Handle. Сначала все буферизованные данные сбрасываются.

data Newline Исходный код

Представление символа новой строки во внешнем файле или потоке.

Конструкторы

LF

'\n'

CRLF

'\r\n'

Реализации

Eq Newline
Ord Newline
Read Newline
Show Newline

nativeNewline :: Newline Исходный код

Представление символа новой строки по умолчанию для текущей платформы: LF в системах Unix, CRLF в системах Windows.

data NewlineMode Исходный код

Определяет преобразование, если таковое имеется, символов новой строки между внутренними строками и внешним файлом или потоком. Предполагается, что строки Haskell представляют новые строки символом '\n'; режим новой строки определяет, как преобразовать '\n' на выходе и что преобразовать в '\n' на входе.

Конструкторы

NewlineMode

Поля

inputNL :: Newline

представление символов новой строки на входе

outputNL :: Newline

представление символов новой строки на выходе

Реализации

Eq NewlineMode
Ord NewlineMode
Read NewlineMode
Show NewlineMode

noNewlineTranslation :: NewlineMode Исходный код

Не выполнять преобразование символов новой строки вообще.

noNewlineTranslation  = NewlineMode { inputNL  = LF, outputNL = LF }

universalNewlineMode :: NewlineMode Исходный код

Преобразовать '\r\n' в '\n' на входе и '\n' в символ новой строки по умолчанию на выходе. Этот режим может использоваться на любой платформе и работает с текстовыми файлами, использующими любую конвенцию новых строк. Недостатком является то, что readFile >>= writeFile может привести к получению другого файла.

universalNewlineMode  = NewlineMode { inputNL  = CRLF,
                                      outputNL = nativeNewline }

nativeNewlineMode :: NewlineMode Исходный код

Использовать родное представление символа новой строки как на входе, так и на выходе.

nativeNewlineMode  = NewlineMode { inputNL  = nativeNewline
                                   outputNL = nativeNewline }

© The University of Glasgow and others
Licensed under a BSD-style license (see top of the page).
https://downloads.haskell.org/~ghc/7.10.3/docs/html/libraries/base-4.8.2.0/System-IO.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API