2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Haskell でテンポラリファイルを扱う方法

Posted at

テンポラリファイルを扱う方法を検証しました。

テンポラリディレクトリを扱う方法の検証は以下を参照してください。

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 で閉じてから、writeFilereadFile で操作するのが簡単で良いのではないかと思います。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?