@@ -86,7 +86,8 @@ module Streamly.FileSystem.Handle
8686 -- -- * Array Write
8787 , writeArray
8888 , writeArrays
89− , writeArraysPackedUpto
89+ -- , writeArraysPackedUpto
90+ , writeArraysInChunksOf
9091
9192 -- -- * Random Access (Seek)
9293 -- -- | Unlike the streaming APIs listed above, these APIs apply to devices or
@@ -122,10 +123,12 @@ import Prelude hiding (read)
122123import Streamly.Memory.Array.Types (Array(..))
123124import Streamly.Streams.Serial (SerialT)
124125import Streamly.Streams.StreamK.Type (IsStream, mkStream)
125−import Streamly.Memory.Array.Types (defaultChunkSize, shrinkToFit)
126−-- import Streamly.Fold (Fold)
126+import Streamly.Memory.Array.Types (defaultChunkSize, shrinkToFit, lpackArraysChunksOf)
127+import Streamly.Fold (Fold)
127128-- import Streamly.String (encodeUtf8, decodeUtf8, foldLines)
128129
130+import qualified Streamly.Fold as FL
131+import qualified Streamly.Fold.Types as FL
129132import qualified Streamly.Memory.Array as A
130133import qualified Streamly.Memory.ArrayStream as AS
131134import qualified Streamly.Prelude as S
@@ -265,12 +268,20 @@ read = AS.flatten . readArrays
265268-- Writing
266269-------------------------------------------------------------------------------
267270
271+-- | Write a stream of arrays to a handle.
272+--
273+-- @since 0.7.0
274+{-# INLINE writeArraysS #-}
275+writeArraysS :: (MonadIO m, Storable a)
276+ => Handle -> SerialT m (Array a) -> m ()
277+writeArraysS h m = S.mapM_ (liftIO . writeArray h) m
278+
268279-- | Write a stream of arrays to a handle.
269280--
270281-- @since 0.7.0
271282{-# INLINE writeArrays #-}
272−writeArrays :: (MonadIO m, Storable a) => Handle -> SerialT m (Array a) -> m ()
273−writeArrays h m = S.mapM_ (liftIO . writeArray h) m
283+writeArrays :: (MonadIO m, Storable a) => Handle -> Fold m (Array a) ()
284+writeArrays h = FL.drainBy (liftIO . writeArray h)
274285
275286-- | @writeArraysPackedUpto chunkSize handle stream@ writes a stream of arrays
276287-- to @handle@ after coalescing the adjacent arrays in chunks of @chunkSize@.
@@ -278,10 +289,22 @@ writeArrays h m = S.mapM_ (liftIO . writeArray h) m
278289-- we do not split the arrays to fit exactly to the specified size.
279290--
280291-- @since 0.7.0
281−{-# INLINE writeArraysPackedUpto #-}
282−writeArraysPackedUpto :: (MonadIO m, Storable a)
292+{-# INLINE _writeArraysPackedUpto #-}
293+_writeArraysPackedUpto :: (MonadIO m, Storable a)
283294 => Int -> Handle -> SerialT m (Array a) -> m ()
284−writeArraysPackedUpto n h xs = writeArrays h $ AS.compact n xs
295+_writeArraysPackedUpto n h xs = writeArraysS h $ AS.compact n xs
296+
297+-- | @writeArraysInChunksOf chunkSize handle@ writes a stream of arrays
298+-- to @handle@ after coalescing the adjacent arrays in chunks of @chunkSize@.
299+-- We never split an array, if a single array is bigger than the specified size
300+-- it emitted as it is. Multiple arrays are coalesed as long as the total size
301+-- remains below the specified size.
302+--
303+-- @since 0.7.0
304+{-# INLINE writeArraysInChunksOf #-}
305+writeArraysInChunksOf :: (MonadIO m, Storable a)
306+ => Int -> Handle -> Fold m (Array a) ()
307+writeArraysInChunksOf n h = lpackArraysChunksOf n (writeArrays h)
285308
286309-- GHC buffer size dEFAULT_FD_BUFFER_SIZE=8192 bytes.
287310--
@@ -296,18 +319,37 @@ writeArraysPackedUpto n h xs = writeArrays h $ AS.compact n xs
296319-- collect the required input size.
297320--
298321-- @since 0.7.0
322+{-# INLINE writeInChunksOfS #-}
323+writeInChunksOfS :: MonadIO m => Int -> Handle -> SerialT m Word8 -> m ()
324+writeInChunksOfS n h m = writeArraysS h $ AS.arraysOf n m
325+
326+-- | @writeInChunksOf chunkSize handle@ writes the input stream to @handle@ in
327+-- chunks of @chunkSize@. A write is performed to the IO device as soon as we
328+-- collect the required input size.
329+--
330+-- @since 0.7.0
299331{-# INLINE writeInChunksOf #-}
300−writeInChunksOf :: MonadIO m => Int -> Handle -> SerialT m Word8 -> m ()
301−writeInChunksOf n h m = writeArrays h $ AS.arraysOf n m
332+writeInChunksOf :: MonadIO m => Int -> Handle -> Fold m Word8 ()
333+writeInChunksOf n h = FL.lchunksOf n A.write (writeArrays h)
334+
335+-- > write = 'writeInChunksOf' A.defaultChunkSize
336+--
337+-- | Write a byte stream to a file handle. Accumulates the input in chunks of
338+-- up to 'A.defaultChunkSize' before writing.
339+--
340+-- @since 0.7.0
341+{-# INLINE _writeS #-}
342+_writeS :: MonadIO m => Handle -> SerialT m Word8 -> m ()
343+_writeS = writeInChunksOfS defaultChunkSize
302344
303345-- > write = 'writeInChunksOf' A.defaultChunkSize
304346--
305−-- | Write a byte stream to a file handle. Combines the bytes in chunks of
347+-- | Write a byte stream to a file handle. Accumulates the input in chunks of
306348-- up to 'A.defaultChunkSize' before writing.
307349--
308350-- @since 0.7.0
309351{-# INLINE write #-}
310−write :: MonadIO m => Handle -> SerialT m Word8 -> m ()
352+write :: MonadIO m => Handle -> Fold m Word8 ()
311353write = writeInChunksOf defaultChunkSize
312354
313355{-