代码之家  ›  专栏  ›  技术社区  ›  Thomas Eding

将字符串转换为ByteString的最佳方法是什么

  •  24
  • Thomas Eding  · 技术社区  · 14 年前

    我对这个问题的本能反应是

    import qualified Data.ByteString as B
    import Data.Char (ord)
    
    packStr = B.pack . map (fromIntegral . ord)
    

    但这似乎并不令人满意。

    4 回复  |  直到 14 年前
        1
  •  41
  •   cmaher MSeifert    5 年前

    这里是Haskell String/Text/ByteString strict/lazy转换的备忘单,假设所需的编码是UTF-8。Data.Text.Encoding库有其他可用编码。

    请确保 写入(使用重载字符串):

    lazyByteString :: BL.ByteString
    lazyByteString = "lazyByteString ä ß" -- BAD!
    

    这将以一种意想不到的方式进行编码。尝试

    lazyByteString = BLU.fromString "lazyByteString ä ß" -- good
    

    相反。

    备忘单:

    import Data.ByteString.Lazy as BL
    import Data.ByteString as BS
    import Data.Text as TS
    import Data.Text.Lazy as TL
    import Data.ByteString.Lazy.UTF8 as BLU -- from utf8-string
    import Data.ByteString.UTF8 as BSU      -- from utf8-string
    import Data.Text.Encoding as TSE
    import Data.Text.Lazy.Encoding as TLE
    
    -- String <-> ByteString
    
    BLU.toString   :: BL.ByteString -> String
    BLU.fromString :: String -> BL.ByteString
    BSU.toString   :: BS.ByteString -> String
    BSU.fromString :: String -> BS.ByteString
    
    -- String <-> Text
    
    TL.unpack :: TL.Text -> String
    TL.pack   :: String -> TL.Text
    TS.unpack :: TS.Text -> String
    TS.pack   :: String -> TS.Text
    
    -- ByteString <-> Text
    
    TLE.encodeUtf8 :: TL.Text -> BL.ByteString
    TLE.decodeUtf8 :: BL.ByteString -> TL.Text
    TSE.encodeUtf8 :: TS.Text -> BS.ByteString
    TSE.decodeUtf8 :: BS.ByteString -> TS.Text
    
    -- Lazy <-> Strict
    
    BL.fromStrict :: BS.ByteString -> BL.ByteString
    BL.toStrict   :: BL.ByteString -> BS.ByteString
    TL.fromStrict :: TS.Text -> TL.Text
    TL.toStrict   :: TL.Text -> TS.Text
    

    请+1皮克的答案,因为他正确地处理编码。

        2
  •  27
  •   psygo    3 年前

    Data.ByteString.UTF8.fromString 也很有用。这个 Char8 版本将丢失unicode编码,UTF8将使一个UTF8编码 ByteString . 你得选一个。

        3
  •  16
  •   robx    11 年前

    安全的方法包括编码unicode字符串:

    import qualified Data.ByteString as B
    import qualified Data.Text as T
    import Data.Text.Encoding (encodeUtf8)
    
    packStr'' :: String -> B.ByteString
    packStr'' = encodeUtf8 . T.pack
    

    关于其他答案:Data.ByteString.Char8.pack实际上与问题中的版本相同,不太可能是您想要的:

    import qualified Data.ByteString as B
    import qualified Data.ByteString.Char8 as C
    import qualified Data.Text as T
    import Data.Text.Encoding (encodeUtf8)
    import Data.Char (ord)
    
    packStr, packStr', packStr'' :: String -> B.ByteString
    packStr   = B.pack . map (fromIntegral . ord)
    packStr'  = C.pack
    packStr'' = encodeUtf8 . T.pack
    
    *Main> packStr "hellö♥"
    "hell\246e"
    *Main> packStr' "hellö♥"
    "hell\246e"
    *Main> packStr'' "hellö♥"
    "hell\195\182\226\153\165"