Haskell ファイル入出力の学習

個人開発したアプリの宣伝
目的地が設定できる手帳のような使い心地のTODOアプリを公開しています。
Todo with Location

Todo with Location

  • Yoshiko Ichikawa
  • Productivity
  • Free

スポンサードリンク

ファイルを読む

readfile.hs

import Control.Monad
import Data.Char

main = forever $ do
  l <- getLine
  putStrLn $ map toUpper l
$ ghc --make readfile.hs 
$ ./readfile < data.txt


getContents関数

入力ストリームから文字列を得る関数。入力ストリームは遅延読み込みを行う。<-ですべてのデータを読み込まず必要に応じて読み込む。

import Data.Char

main = do
  contents <- getContents
  putStr $ map toUpper contents


interact関数

interactはString -> String型の関数を引数として、入力をその関数に渡した結果を出力する。以下は上記のgetContentsの例と同義。

import Data.Char

main = do
  interact toUpperByString

toUpperByString :: String -> String
toUpperByString  = map toUpper


ファイルを読む
import System.IO

main = do
  handle <- openFile "data.txt" ReadMode
  contents <- hGetContents handle
  putStr contents
  hClose handle
ghci> :t openFile 
openFile :: FilePath -> IOMode -> IO Handle

FilePathはStringのシノニム。

IOModeは列挙タイプ

data IOMode = ReadMode | WriteMode | AppendMode | ReadWriteMode

Handleはそのファイルのポインタ(場所)を示す。IO Handleはファイルを開いた後、Handleを返すという意味と読める。

ghci> :t hGetContents
hGetContents :: Handle -> IO String

hGetContentsはHandleで示した位置からgetContents同様、遅延読み込みを行い読み込んだStringを返す。


withFile関数

withFileはオープンしたファイルに対してラムダで処理を記述できる。以下の定義を見ればわかりやすい。

ghci> :t withFile 
withFile :: FilePath -> IOMode -> (Handle -> IO r) -> IO r
import System.IO

main = do
  withFile "data.txt" ReadMode $ \handle -> do
    contents <- hGetContents handle
    putStr contents


bracket、brackerOnError関数

例外が起きた際でも確実にリソースを開放できる操作を行える。 bracketは例外発生、処理終了時に2つ目の引数の開放操作を、brackerOnErrorは例外時に開放操作を行う。

bracket handle 開放操作 handle操作として記述する

ghci> :t bracket
bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
import System.IO
import Control.Exception

main = do
  bracket (openFile "data.txt" ReadMode) (\handle -> hClose handle) (\handle -> do 
    text <- hGetContents handle
    putStrLn text
    )


readFile, writeFile, appendFile関数

readFileはopenFileとhGetContentsをつなげたような関数。ハンドルはHaskellが自動で閉じる。

import System.IO

main = do
  contents <- readFile "data.txt"
  putStrLn contents

writeFileはその名の通り、指定したファイルに上書き書き込みを行う。

ghci> import System.IO
ghci> :t writeFile 
writeFile :: FilePath -> String -> IO ()
import System.IO

main = do
  contents <- readFile "data.txt"
  writeFile "dest.txt" contents

appendFile指定したファイルに上書きではなく末尾追記の書き込みを行う。

ghci> :t appendFile
appendFile :: FilePath -> String -> IO ()


openTempFile関数

必ず存在しないファイルをオープンする。つまりこの関数で開くファイルは上書きの可能性がない。ということ。


removeFile、renameFile関数

System.Directoryパッケージに入る。名前通りの挙動。