diff --git a/bytestring-handle.cabal b/bytestring-handle.cabal
--- a/bytestring-handle.cabal
+++ b/bytestring-handle.cabal
@@ -1,5 +1,5 @@
 name:                bytestring-handle
-version:             0.1.0.0
+version:             0.1.0.1
 synopsis:            ByteString-backed Handles
 -- description:
 homepage:            http://hub.darcs.net/ganesh/bytestring-handle
diff --git a/src/Data/ByteString/Handle/Read.hs b/src/Data/ByteString/Handle/Read.hs
--- a/src/Data/ByteString/Handle/Read.hs
+++ b/src/Data/ByteString/Handle/Read.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE CPP, DeriveDataTypeable #-}
+{-# LANGUAGE CPP, DeriveDataTypeable, ForeignFunctionInterface #-}
 module Data.ByteString.Handle.Read
     ( readHandle
     ) where
@@ -11,14 +11,18 @@
 import Data.Maybe ( fromMaybe )
 import Data.Typeable ( Typeable )
 import Data.Word ( Word8 )
+import Foreign.C.Types ( CSize(..) )
 import Foreign.ForeignPtr ( newForeignPtr_ )
-import Foreign.Ptr ( nullPtr )
+import Foreign.Ptr ( Ptr, nullPtr, plusPtr )
 import System.IO
     ( Handle, IOMode( ReadMode )
     , noNewlineTranslation, nativeNewlineMode
     )
 
-import GHC.IO.Buffer ( BufferState(..), emptyBuffer, Buffer(..) )
+import GHC.IO.Buffer
+    ( BufferState(..), Buffer(..)
+    , emptyBuffer, isEmptyBuffer, newBuffer, newByteBuffer
+    , bufferElems, withBuffer, withRawBuffer )
 import GHC.IO.BufferedIO ( BufferedIO(..) )
 import GHC.IO.Device ( IODevice(..), IODeviceType(..), SeekMode(..) )
 #if MIN_VERSION_base(4,5,0)
@@ -62,6 +66,9 @@
                          0
                          ReadBuffer
 
+foreign import ccall unsafe "memmove"
+   memmove :: Ptr a -> Ptr a -> CSize -> IO (Ptr a)
+
 instance BufferedIO ReadState where
     emptyWriteBuffer _ _ = ioException unsupportedOperation
     flushWriteBuffer _ _ = ioException unsupportedOperation
@@ -74,26 +81,35 @@
        (count, buf) <- fillReadBuffer0 rs bufIn
        return (fromMaybe 0 count, buf)
 
-    fillReadBuffer0 rs _ = do
+    fillReadBuffer0 rs bufIn = do
         ss <- readIORef (read_seek_state rs)
         case seek_after ss of
               [] -> do
-                buf <- nullReadBuffer
-                return (Nothing, buf)
+                return (Nothing, bufIn)
               (chunk:chunks) ->
-                let (ptr, bsOffset, _) = BI.toForeignPtr chunk
-                    buf = (emptyBuffer ptr (bsOffset + B.length chunk) ReadBuffer) {
-                              bufL = bsOffset + seek_pos ss, bufR = bsOffset + B.length chunk
-                          }
-                in do writeIORef (read_seek_state rs)
-                                 (SeekState {
-                                      seek_before = chunk:seek_before ss,
-                                      seek_after = chunks,
-                                      seek_pos = 0,
-                                      seek_before_length = fromIntegral (B.length chunk) + seek_before_length ss
-                                  })
-                      return (Just (B.length chunk - seek_pos ss), buf)
-
+                  let (ptr, bsOffset_noseek, _) = BI.toForeignPtr chunk
+                      bsOffset = bsOffset_noseek + seek_pos ss
+                      bsOffsetEnd = bsOffset_noseek + B.length chunk
+                  in do buf <- if isEmptyBuffer bufIn
+                                then return (emptyBuffer ptr bsOffsetEnd ReadBuffer) {
+                                                bufL = bsOffset, bufR = bsOffsetEnd
+                                            }
+                                else do let sz = bufferElems bufIn + B.length chunk - seek_pos ss
+                                        buf <- newByteBuffer sz ReadBuffer
+                                        withBuffer buf $ \buf_ptr -> do
+                                          withBuffer bufIn $ \buf_in_ptr ->
+                                            memmove buf_ptr (buf_in_ptr `plusPtr` bufL bufIn) (fromIntegral $ bufferElems bufIn)
+                                          withRawBuffer ptr $ \ptr_ptr ->
+                                            memmove (buf_ptr `plusPtr` bufferElems bufIn) (ptr_ptr `plusPtr` bsOffset) (fromIntegral (bsOffsetEnd - bsOffset))
+                                        return (buf { bufR = sz })
+                        writeIORef (read_seek_state rs)
+                                   (SeekState {
+                                        seek_before = chunk:seek_before ss,
+                                        seek_after = chunks,
+                                        seek_pos = 0,
+                                        seek_before_length = fromIntegral (B.length chunk) + seek_before_length ss
+                                    })
+                        return (Just (B.length chunk - seek_pos ss), buf)
 
 normalisedSeekState :: [B.ByteString] -> [B.ByteString] -> Integer -> Integer -> Maybe SeekState
 normalisedSeekState (x:before) after beforeLen pos
