通过霍夫曼编码算法将字节写入文件

Write bytes to file from Huffman encoding algorithm

我正在学习Haskell,作为第一个挑战,我选择编写霍夫曼编码的实现,该算法几乎完成了,只缺少读写文件到字节文件的部分。 我需要做的是一种基于我构建的二进制字符串编写文件的方法。

例如,如果从 txt 文件中读取以下字符串 Hello,经过哈夫曼算法后,我得到以下映射,它将符号映射到他的二进制数作为字符串

[
  ("H": "110"),
  ("e": "111"),
  ("l": "0"),
  ("o": "10")
]

我需要替换读取的字符串中的字节并将二进制数作为字节写入文件,我尝试使用 ByteString 包和 writeFile 函数,但是该函数将二进制数写入纯文本和不是字节。

这样 Hello 就变成了 110111010 应该作为字节写入文件。

您可以将 '0''1' 的字符串写入带有 writeFile :: FilePath -> String -> IO () 的文件。例如:

main :: IO ()
main = <b>writeFile</b> "out.txt" "110111010"

您还可以将八位转换为 Word8,然后将 ByteString 写入具有 WriteFile :: FilePath -> ByteString -> IO () of the Data.ByteString module:

的文件
import Data.ByteString(writeFile, pack)
import Data.Word(Word8)

writeWord8s :: [Word8] -> IO ()
writeWord8s = writeFile "out.txt" . pack

您可以将 Bool 的列表转换为 Word8,但是这必须是八的倍数。例如,您可以 "pad" 它与 0s (或 1s 或其他东西),但它应该是八的倍数:

import Data.Bool(bool)
import Data.Bits((.|.), shiftL)
import Data.Word(Word8)

toWord8 :: [Bool] -> Word8
toWord8 = foldl ((. bool 0 1) . (.|.) . (`shiftL` 1)) 0

pack8pad0 :: [Bool] -> [Word8]
pack8pad0 [] = []
pack8pad0 xs
    | null ys = [toWord8 (y ++ replicate (8 - length y) False)]
    | otherwise = toWord8 y : pack8pad0 ys
    where (y, ys) = splitAt 8 xs

我将输入映射到 '0''1'String 作为练习。