Подобно тому как функция >hGetContents
работает по аналогии с функцией >getContents
, но с указанным файлом, существуют функции >hGetLine
, >hPutStr
, >hPutStrLn
, >hGetChar
и т. д., ведущие себя так же, как их варианты без буквы >h
, но принимающие дескриптор как параметр и работающие с файлом, а не со стандартным вводом-выводом. Пример: >putStrLn
– это функция, принимающая строку и возвращающая действие ввода-вывода, которое напечатает строку на терминале, а затем выполнит перевод на новую строку. Функция >hPutStrLn
принимает дескриптор файла и строку и возвращает действие, которое запишет строку в файл и затем поместит в файл символ(ы) перехода на новую строку. Функция >hGetLine
принимает дескриптор и возвращает действие, которое считывает строку из файла.
Загрузка файлов и обработка их содержимого в виде строк настолько распространена, что есть три маленькие удобные функции, которые делают эту задачу ещё легче.
Сигнатура функции >readFile
такова:
>readFile :: FilePath –> IO String
Мы помним, что тип >FilePath
– это просто удобное обозначение для >String
. Функция >readFile
принимает путь к файлу и возвращает действие ввода-вывода, которое прочитает файл (лениво, конечно же) и свяжет содержимое файла в виде строки с некоторым именем. Обычно это более удобно, чем вызывать функцию >openFile
и связывать дескриптор с именем, а затем вызывать функцию >hGetContents
. Вот как мы могли бы переписать предыдущий пример с использованием >readFile
:
>import System.IO
>main = do
> contents <– readFile "girlfriend.txt"
> putStr contents
Так как мы не получаем дескриптор файла в качестве результата, то не можем закрыть его сами. Если мы используем функцию >readFile
, за нас это сделает язык Haskell.
Функция >writeFile
имеет тип
>writeFile :: FilePath –> String –> IO ()
Она принимает путь к файлу и строку для записи в файл и возвращает действие ввода-вывода, которое выполнит запись. Если такой файл уже существует, перед записью он будет обрезан до нулевой длины. Вот как получить версию файла girlfriend.txt в верхнем регистре и записать её в файл girlfriendcaps.txt:
>import System.IO
>import Data.Char
>main = do
> contents <– readFile "girlfriend.txt"
> writeFile "girlfriendcaps.txt" (map toUpper contents)
Функция >appendFile
имеет ту же сигнатуру, что и >writeFile
, и действует почти так же. Она только не обрезает уже существующий файл до нулевой длины перед записью, а добавляет новое содержимое в конец файла.