代码之家  ›  专栏  ›  技术社区  ›  Bercovici Adrian

Haskell中的编码与有效IO

  •  0
  • Bercovici Adrian  · 技术社区  · 6 年前

    你好,我有点困惑,所有的Haskell模块需要编码的数据从 String ByteString 有效写作。

    Data.ByteString.Lazy Data.ByteString.Char8

    我需要知道什么?因为我不能得到所有这些可能的用法组合。。。。 Data.ByteString , Data.ByteString.Lazy文件 数据.ByteString.Char8 ,然后是 Data.Text …我需要什么才能轻松高效地将字符串写入文件,反之亦然?(正确编码)

    我和哈斯克尔正在读现实世界的书,对所有这些模块都感到困惑。

    2 回复  |  直到 6 年前
        1
  •  5
  •   K. A. Buhr    6 年前

    字符串和文本

    你可能知道,哈斯克尔 String [Char] ,在哪里 Char 是可以表示单个Unicode代码点的数据类型。这使得 完美的数据类型来表示文本数据,除了一个小问题--作为一个装箱的链表 烧焦 价值观——它有可能非常低效。

    Text 来自 text 文本 字符串 ,表示 值,但它不使用实际的Haskell列表,而是使用节省时间和空间的表示。它应该是你的代替品 每当您需要高效地处理文本(Unicode)数据时。

    文本 ,但它们包含在单独的模块中,因此您可以执行以下操作:

    import qualified Data.Text as TS
    import qualified Data.Text.Lazy as TL
    

    TS.Text TL.Text

    documentation for Data.Text . 简而言之,您应该默认使用严格版本。您只在两种情况下使用lazy版本。首先,如果你打算在一个大的 文本 一次值一点,把它当作文本“流”而不是“字符串”,那么懒惰的版本是个不错的选择。(例如,一个程序读取一个巨大的CSV数字文件时,可能会将该文件作为一个长文件读取 流式处理并将结果存储在一个高效的数字类型中,如 Vector Double 值以避免将整个输入文本保留在内存中。)其次,如果要构建大型 文本 Data.Text.Lazy.Builder .

    旁路环

    ByteString 来自 bytestring 文本 作为 [Word8] Word8 是Haskell类型,表示值为0-255的数据的单个无符号字节。等价地,你可以想到 表示要从文件中读取或写入的内存块或数据块,精确地表示为逐字节。它也有懒惰和严格的味道:

    import qualified Data.ByteString as BS
    import qualified Data.ByteString.Lazy as BL
    

    使用变体的注意事项与 .

    读取和写入文件

    字符串 文本

    Prelude 直接读写字符串:

    readFile :: FilePath -> IO String
    writeFile :: FilePath -> String -> IO ()
    

    此外,还有 readFile writeFile 文本 Data.Text.IO Data.Text.Lazy.IO 文本 另一个是在懒洋洋上操作 类型:

    readFile :: FilePath -> IO Text
    writeFile :: FilePath -> Text -> IO ()
    

    可以看出这些函数正在自动进行编码和解码,因为它们返回并接受 文本 ByteString公司 价值观。使用的默认编码将取决于操作系统及其配置。在典型的现代Linux发行版上,它将是UTF-8。

    或者,您可以使用 bytestring公司 包(同样,根据模块的不同,可以是惰性版本,也可以是严格版本):

    readFile :: FilePath -> IO ByteString
    writeFile :: FilePath -> ByteString -> IO ()
    

    它们的名字和 版本,但您可以看到它们正在处理原始字节,因为它们返回并接受 论据。在这种情况下,如果你想使用这些 作为文本数据,您需要自己解码或编码它们。如果 ByteString公司 Data.Text.Encoding (对于严格版本)或 Data.Text.Lazy.Encoding (对于懒惰的版本)是您想要的:

    decodeUtf8 :: ByteString -> Text
    encodeUtf8 :: Text -> ByteString
    

    Char8模块

    Data.ByteString.Char8 Data.ByteString.Lazy.Char8 是个特例。当纯ASCII文本使用几种“ASCII保留”编码方案(包括ASCII本身、Latin-1和其他Latin-x编码以及UTF-8)之一进行编码时,结果表明 只是一个简单的每字符一字节的Unicode编码点0到127。更一般地说,当文本被编码为拉丁语-1时,那么 烧焦 值并返回。

    因为这些函数只在这种特殊情况下工作,所以通常应该避免在特殊应用程序中使用它们。

    ByteString公司 这些中的变体 Char8 ByteString公司 变体;将其视为字符串 值而不是 字8 功能

    总体战略

    文本 Data.Text 以及来自 . 您可以将lazy变体用于流处理或从微小片段构建大字符串,并且您可以使用 Data.Text.Read 对于一些简单的解析。

    你应该能够避免使用 在大多数情况下,如果您发现需要来回转换,那么这些转换函数 Data.Text.Lazy )将非常有用:

    pack :: String -> Text
    unpack :: Text -> String
    

    如果您需要对编码进行更多的控制,您可以 仍然 文本 在整个程序中,除了读写文件的“边缘”。在这些边缘,使用 Data.ByteString Data.ByteString.Lazy 数据.文本.编码 .

    Data.Text.Lazy文件 包含:

    toStrict :: TL.Text -> TS.Text     -- convert lazy to strict
    fromStrict :: TS.Text -> TL.Text   -- vice versa
    

    包含的相应函数 ByteString公司

    toStrict :: BL.ByteString -> BS.ByteString
    fromStrict :: BS.ByteString -> BL.ByteString
    
        2
  •  3
  •   user12457    6 年前

    这取决于你处理的数据类型以及你计划如何传递这些数据。

    如果要处理Unicode字符串,请使用 Text

    Lazy 该模块的版本。否则,整个数据将加载到单个数据结构中。

    何时使用 Data.ByteString Data.ByteString.Char8 ByteString 是一种数据结构,可用于存储字节序列,每种类型: Word8 Char ByteString公司 类型。

    因为我们经常会处理二进制数据和基于字符的数据,如果我们在不同的模块中分别保留字节和字符的操作,那就很方便了;这样当我们需要处理基于字符的数据时,只需要使用来自Char8模块的操作。

    推荐文章