diff --git a/hw-prim.cabal b/hw-prim.cabal
--- a/hw-prim.cabal
+++ b/hw-prim.cabal
@@ -3,7 +3,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           hw-prim
-version:        0.6.2.7
+version:        0.6.2.8
 synopsis:       Primitive functions and data types
 description:    Primitive functions and data types.
 category:       Data
diff --git a/src/HaskellWorks/Data/ByteString/Lazy.hs b/src/HaskellWorks/Data/ByteString/Lazy.hs
--- a/src/HaskellWorks/Data/ByteString/Lazy.hs
+++ b/src/HaskellWorks/Data/ByteString/Lazy.hs
@@ -1,17 +1,24 @@
+{-# LANGUAGE CPP               #-}
 {-# LANGUAGE FlexibleInstances #-}
 
 module HaskellWorks.Data.ByteString.Lazy
   ( ToLazyByteString(..)
   , resegment
   , resegmentPadded
+  , hGetContentsChunkedBy
   ) where
 
 import Data.Word
 import HaskellWorks.Data.ByteString (ToByteString (..))
 
-import qualified Data.ByteString.Lazy         as LBS
-import qualified Data.Vector.Storable         as DVS
-import qualified HaskellWorks.Data.ByteString as BS
+import qualified Data.ByteString               as BS
+import qualified Data.ByteString.Internal      as BS
+import qualified Data.ByteString.Lazy          as LBS
+import qualified Data.ByteString.Lazy.Internal as LBS
+import qualified Data.Vector.Storable          as DVS
+import qualified HaskellWorks.Data.ByteString  as BS
+import qualified System.IO                     as IO
+import qualified System.IO.Unsafe              as IO
 
 class ToLazyByteString a where
   toLazyByteString :: a -> LBS.ByteString
@@ -57,3 +64,12 @@
 
 resegmentPadded :: Int -> LBS.ByteString -> LBS.ByteString
 resegmentPadded multiple = LBS.fromChunks . BS.resegmentPadded multiple . LBS.toChunks
+
+hGetContentsChunkedBy :: Int -> IO.Handle -> IO LBS.ByteString
+hGetContentsChunkedBy k h = lazyRead
+  where lazyRead = IO.unsafeInterleaveIO loop
+        loop = do
+            c <- BS.createAndTrim k $ \p -> IO.hGetBuf h p k
+            if BS.null c
+              then IO.hClose h >> return LBS.Empty
+              else LBS.Chunk c <$> lazyRead
