- 리스트랑 비슷한데 원소 하나의 크기가 1바이트이다.1
- 지연 평가 lazy 를 다루는 방식이 리스트와 다르다.
- 패키지 이름은
bytestring
- 모듈 이름은
Data.ByteString
- 지연 평가를 전혀 쓰지 않는다.
- thunk가 없어서 오버헤드가 적다.
- 메모리 소모 시점이 이르고 기간이 짧다.
- 모듈 이름은
Data.ByteString.Lazy
- lazy 하긴 하지만 리스트만큼 lazy 하지는 않다.
- 데이터를 chunk에 저장한다. chunk 하나의 크기는 64K이다.
- 데이터를 평가할 때 한 chunk만큼만 하고 나머지는 필요할 때 한다.
- 리스트가 제공하는 함수와 이름이 겹쳐서
import qualified
를 한다.
import qualified Data.ByteString.Lazy as B
import qualified Data.ByteString as S
[a] ~ ByteString
a ~ Word8
- 함수
pack
은Word8
리스트를 넣으면 리스트보다는 덜 lazy한ByteString
을 리턴한다.2
pack :: [Word8] -> ByteString
Int
랑 비슷하다.- 값 범위는
0 - 255
- 타입 클래스
Num
인스턴스 있다. 그래서5
와 같은 숫자 리터럴은 타입Word8
이 될 수 있다.
ghci> B.pack [99, 97, 110]
Chunk "can" Empty
Word8
범위보다 큰 수가 오면 0부터 다시 센다. 예를 들어336
은80
이 된다.Empty
는 리스트에서[]
와 같다.3- 함수
unpack
은pack
과 반대이다.ByteString
을 넣으면[Word8]
이 나온다.
unpack :: ByteString -> [Word8]
- 함수
fromChunks
는 strict bytestring 리스트를 넣으면 lazy bytestring을 리턴한다.4
fromChunks :: [S.ByteString] -> B.ByteString
ghci> :{
ghci| B.fromChunks [ S.pack [40,41,42]
ghci| , S.pack [43,44,45]
ghci| , S.pack [46,47,48] ]
ghci|:}
()*+,-./0
toChunks
는 반대로 lazy bytestring을 넣으면 strict bytestring 리스트를 리턴한다.
toChunks :: B.ByteString -> [S.ByteString]
- 리스트에서
:
은 bytestring에서cons
와 같다. - 바이트와 bytestring을 받아서 바이트를 bytestring 앞에 붙인다.
cons :: Word8 -> ByteString -> ByteString
cons
는 lazy 해서 앞에 붙이려는 게 1바이트인데도 64K짜리 chunk를 하나 새로 만든다. 그래서 앞에 여러개를 붙일 때는 strict 버전인cons'
를 쓰는 게 좋다.
ghci> B.cons 85 $ B.pack [80,81,82,83]
UPQRT
Data.List
에서 제공하는 것과 이름이 같은 함수를 지원한다 :head
,tail
,init
,null
,length
,map
,reverse
,foldl
,foldr
,concat
,takeWhile
,filter
등System.IO
도 마찬가지인데String
만ByteString
으로 바꾸면 된다.
System.IO.readFile :: FilePath -> IO String
ByteString.readFile :: FilePath -> IO ByteString
- strict bytestring으로 파일을 읽으면 내용 전체를 한 번에 읽는다.
- lazy bytestring으로 파일을 읽으면 한 번에 chunk만큼만 읽는다.
import System.Environment
import qualified Data.ByteString.Lazy as B
main = do
(fileName1:fileName2:_) <- getArgs
copyFile fileName1 fileName2
copyFile :: FilePath -> FilePath -> IO ()
copyFile source dest = do
contents <- B.readFile source
B.writeFile dest contents
Footnotes
-
Char
는 크기가 정해져 있지 않다. 유니코드는 여러 바이트가 필요하다. ↩ -
한 번에 64K만큼만 lazy 하다. ↩
-
특정 버전부터 출력 방식이 바뀌어서
Cons
와Empty
가 보이진 않는다. 스택오버플로우 링크 참고. ↩ -
이름이 반대여야 할 것 같다.↩