手習いにファイルを分割するプログラムを書いてみました。

 GHCのドキュメントを見ても、どうやってバイナリファイルを取扱うのか分かりませんでした。ぐぐってみると、System.IO.openBinaryFileという関数が見つかったのでこれを使ってみました。

 英文マニュアルをあさるのは疲れるので、もう少し日本語情報がほしいところです。

{-  Usage: splitfile path -}

module Main (main) where

import IO (bracket)
import System (getArgs)
import System.IO (IOMode(ReadMode, WriteMode), openBinaryFile)
import System.IO (hGetContents, hClose, hPutStr)

main :: IO ()
main = do args <- getArgs
          splitFile (head args)

blockSize = 1024

splitFile :: String -> IO ()
splitFile path = do content <- readBinaryFile path
                    putFiles $ zip (map (makeFileName) [1, 2 ..])
                                   (split blockSize content)
                 where
                    makeFileName :: Int -> String
                    makeFileName n = path ++ "." ++ (show n)

readBinaryFile :: FilePath -> IO String
readBinaryFile path = openBinaryFile path ReadMode >>= hGetContents

writeBinaryFile :: FilePath -> String -> IO ()
writeBinaryFile path str = bracket (openBinaryFile path WriteMode)
                                   hClose
                                   (\h -> hPutStr h str)

split :: Int -> String -> [String]
split n []  = []
split n str = take n str : split n (drop n str)

putFiles :: [(String, String)] -> IO ()
putFiles [] = return ()
putFiles ((path, content):xs) = do writeBinaryFile path content
                                   putFiles xs