23

我有一个带有惰性ByteString的函数,我希望返回严格ByteStrings的列表(惰性应该转移到输出的列表类型)。

import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as L
csVals :: L.ByteString -> [B.ByteString]

我想这样做是出于各种原因,几个词法函数需要 strict ByteString,我可以保证上面ByteStrings 的输出中输出的 strictcsVal非常小。

我如何在ByteString不分的情况下进行“严格化” ?

更新0

我想要一个 Lazy ByteString,并严格ByteString包含它的所有数据。

4

5 回答 5

39

bytestring包现在导出一个toStrict函数:

http://hackage.haskell.org/packages/archive/bytestring/0.10.2.0/doc/html/Data-ByteString-Lazy.html#v:toStrict

这可能不是你想要的,但它肯定回答了这篇文章标题中的问题:)

于 2012-11-29T18:16:48.257 回答
17

就像@sclv 在上面的评论中所说,惰性字节串只是严格字节串的列表。有两种方法可以将惰性 ByteString 转换为严格(来源:关于添加 toStrict 函数的haskell 邮件列表讨论)- 来自以下电子邮件线程的相关代码:

一、相关库:

import qualified Data.ByteString               as B
import qualified Data.ByteString.Internal      as BI
import qualified Data.ByteString.Lazy          as BL
import qualified Data.ByteString.Lazy.Internal as BLI
import           Foreign.ForeignPtr
import           Foreign.Ptr

方法 1(与@sclv 相同):

toStrict1 :: BL.ByteString -> B.ByteString
toStrict1 = B.concat . BL.toChunks

方法二:

toStrict2 :: BL.ByteString -> B.ByteString
toStrict2 BLI.Empty = B.empty
toStrict2 (BLI.Chunk c BLI.Empty) = c
toStrict2 lb = BI.unsafeCreate len $ go lb
  where
    len = BLI.foldlChunks (\l sb -> l + B.length sb) 0 lb

    go  BLI.Empty                   _   = return ()
    go (BLI.Chunk (BI.PS fp s l) r) ptr =
        withForeignPtr fp $ \p -> do
            BI.memcpy ptr (p `plusPtr` s) (fromIntegral l)
            go r (ptr `plusPtr` l)

如果性能是一个问题,我建议查看上面的电子邮件线程。它也有标准基准。在这些基准测试中,toStrict2 比 toStrict1 快。

于 2011-12-18T15:27:52.027 回答
5

如果有问题的惰性字节字符串 <= 严格字节字符串的最大大小:

toStrict = fromMaybe SB.empty . listToMaybe . toChunks

toChunks使每个块尽可能大(可能最后一个除外)。

如果惰性 ByteString 的大小大于严格 ByteString 的大小,那么这是不可能的:这正是惰性 ByteString 的用途。

于 2011-10-19T06:30:42.433 回答
2

Data.ByteString.Lazy.Char8 现在具有 toStrict 和 fromStrict 函数。

于 2017-10-09T22:22:09.633 回答
1

您还可以使用blaze-builder从惰性构建严格的 ByteString

toStrict :: BL.ByteString -> BS.ByteString
toStrict = toByteString . fromLazyByteString

它必须有效。

于 2013-04-06T16:54:54.783 回答