テンポラリファイルを扱う方法を検証しました。
テンポラリディレクトリを扱う方法の検証は以下を参照してください。
Haskell でテンポラリディレクトリを扱う方法 - Qiita
検証コード
SystemIoTempTest2.hs
import qualified GHC.IO.Handle as GIH
import qualified System.Directory as SD
import qualified System.IO.Temp as SIT
main :: IO ()
main = do
(path, handle) <- SIT.openTempFile "/tmp" "hoge.txt"
putStrLn $ "path: '" ++ path ++ "'"
putStrLn $ "handle: '" ++ show handle ++ "'"
GIH.hShow handle >>= \x -> putStrLn $ "hShow: '" ++ x ++ "'"
GIH.hIsOpen handle >>= \x -> putStrLn $ "hIsOpen: '" ++ show x ++ "'"
GIH.hIsClosed handle >>= \x -> putStrLn $ "hIsClosed: '" ++ show x ++ "'"
GIH.hIsReadable handle >>= \x -> putStrLn $ "hIsReadable: '" ++ show x ++ "'"
GIH.hIsWritable handle >>= \x -> putStrLn $ "hIsWritable: '" ++ show x ++ "'"
GIH.hIsSeekable handle >>= \x -> putStrLn $ "hIsSeekable: '" ++ show x ++ "'"
GIH.hPutStr handle "hogehoge"
GIH.hFlush handle
GIH.hSeek handle GIH.AbsoluteSeek 0
contents1 <- GIH.hGetContents handle
putStrLn $ "contents1: '" ++ contents1 ++ "'"
GIH.hIsClosed handle >>= \x -> putStrLn $ "hIsClosed: '" ++ show x ++ "'"
GIH.hClose handle
contents2 <- readFile path
putStrLn $ "contents2: '" ++ contents2 ++ "'"
writeFile path "fugafuga"
contents3 <- readFile path
putStrLn $ "contents3: '" ++ contents3 ++ "'"
SD.removeFile path
実行結果は以下のようになります。
$ runhaskell SystemIoTempTest2.hs
path: '/tmp/hoge24220.txt'
handle: '{handle: /tmp/hoge24220.txt}'
hShow: '{loc=/tmp/hoge24220.txt,type=read-writable,buffering=block (2048)}'
hIsOpen: 'True'
hIsClosed: 'False'
hIsReadable: 'True'
hIsWritable: 'True'
hIsSeekable: 'True'
contents1: 'hogehoge'
hIsClosed: 'True'
contents2: 'hogehoge'
contents3: 'fugafuga'
テンポラリファイルは作成した後、自分で削除する必要があります。逆に言えば、削除のタイミングを自分で決定できるので、また削除せずに残しておくこともできるので、自由度はかなり高いです。
コードでは "hoge.txt" を渡していますが、拡張子の前に自動的にユニークになるように数値が入ります。ファイルを作成するディレクトリとして "/tmp" を指定していますが、場合によってはカレントディレクトリでも良いかもしれません。
気をつける点は、以下だと思います。
-
hGetContentsを呼び出す前に、hSeekでファイル読み書きの位置を読み出す場所に移動しておく -
hGetContentsは遅延評価なので、読みだしたコンテンツを使用する前にhCloseでハンドルを閉じると、内容が空白文字になる
テンポラリファイルの内容をハンドルで低レベル関数を使用して操作するのではなく、さっさと hClose で閉じてから、writeFile と readFile で操作するのが簡単で良いのではないかと思います。