【发布时间】:2015-02-18 17:57:02
【问题描述】:
我需要将文件读取为字节,而不是字符。 但是当我执行 getLine 或 getContents 时,我得到 IO String,并且需要 [Int],而不是 String。 我该怎么办?
【问题讨论】:
-
那么你的文件实际上是什么格式的?它是 32 位整数的平面文件吗?据我所知,你想要的是某种反序列化。
我需要将文件读取为字节,而不是字符。 但是当我执行 getLine 或 getContents 时,我得到 IO String,并且需要 [Int],而不是 String。 我该怎么办?
【问题讨论】:
Data.ByteString 具有严格的 Word8 数组的内部表示。
您使用它的方式与您已经习惯的方式差不多。导入合格的,例如
import qualified Data.ByteString as B
然后做类似的事情
main = do
str <- B.getLine
let bytes = B.unpack str
print bytes
我不确定你是如何相信你需要 Int 的。你想要一个正确的字节表示,例如Word8.
【讨论】:
您可能要求某种形式的反序列化,这应该被视为一个单独的步骤。首先考虑您正在读取某种二进制文件(即它不是文本)。为此,我们可能需要bytestring 并且可以这样做:
import qualified Data.ByteString.Lazy as BL
...
contents <- BL.readFile someFile
获取文件内容后,我们可以将它们从任何形式(String、Text、ByteString 等)转换。你说你想要[Int],但这并不能告诉我们数据的形式是什么——这些32位整数是大端的吗? 64位?有多少,你知道吗?让我们假设 32 位大端整数...并假设文件完全由这些值组成:
import qualified Data.ByteString.Lazy as BL
import Data.Binary.Get
import Control.Monad
import Foreign.Storable
import Data.Word
readAndDecode :: FilePath -> IO [Int]
readAndDecode someFile =
do contents <- BL.readFile someFile
let nrWord32 = fromIntegral (BL.length contents) `div` sizeOf (undefined :: Word32)
return $ runGet (map fromIntegral `fmap` replicateM nrWord32 getWord32be) contents
即我们读取文件,计算文件中32位字的数量,解码,将每个Word32转换成Int
【讨论】: