@@ -18,19 +18,22 @@
18-- Read and write streams and arrays to and from file handles. File handle IO
18-- Read and write streams and arrays to and from file handles. File handle IO
19-- APIs are quite similar to "Streamly.Mem.Array" read write APIs. In that
19-- APIs are quite similar to "Streamly.Mem.Array" read write APIs. In that
20-- regard, arrays can be considered as in-memory files or files can be
20-- regard, arrays can be considered as in-memory files or files can be
21−-- considered as on-disk arrays. IO APIs are divided into two categories,
21+-- considered as on-disk arrays.
22−-- sequential streaming IO APIs and random access IO APIs. Control over the
22+--
23−-- file reading and writing behavior in terms of buffering, encoding, decoding
23+-- Control over file reading and writing behavior in terms of buffering,
24−-- is in the hands of the programmer, the 'TextEncoding', 'NewLineMode', and
24+-- encoding, decoding is in the hands of the programmer, the 'TextEncoding',
25−-- 'Buffering' options of the underlying handle provided by GHC are not needed
25+-- 'NewLineMode', and 'Buffering' options of the underlying handle provided by
26−-- and ignored.
26+-- GHC are not needed and ignored.
28-- > import qualified Streamly.FileSystem.Handle as FH
28-- > import qualified Streamly.FileSystem.Handle as FH
31+-- IO APIs are divided into two categories, sequential streaming IO APIs and
32+-- random access IO APIs.
31module Streamly.FileSystem.Handle
34module Streamly.FileSystem.Handle
33− -- * Streaming IO
36+ -- * Sequential/Streaming IO
34 -- | Stream data to or from a file or device sequentially. When reading,
37 -- | Stream data to or from a file or device sequentially. When reading,
35 -- the stream is lazy and generated on-demand as the consumer consumes it.
38 -- the stream is lazy and generated on-demand as the consumer consumes it.
36 -- Read IO requests to the IO device are performed in chunks limited to a
39 -- Read IO requests to the IO device are performed in chunks limited to a
@@ -48,7 +51,12 @@ module Streamly.FileSystem.Handle
48 -- Devices like terminals, pipes, sockets and fifos do not have random
51 -- Devices like terminals, pipes, sockets and fifos do not have random
49 -- access capability.
52 -- access capability.
51− -- ** Read Handle to Stream
54+ -- ** Read From Handle
55+ -- | 'TextEncoding', 'NewLineMode', and 'Buffering' options of the
56+ -- underlying handle are ignored. The read occurs from the current seek
57+ -- position of the file handle. The stream ends as soon as EOF is
53 -- , readUtf8
61 -- , readUtf8
54 -- , readLines
62 -- , readLines
@@ -63,7 +71,12 @@ module Streamly.FileSystem.Handle
63 -- , readArraysOf
71 -- , readArraysOf
64 , readArrays
72 , readArrays
66− -- ** Write File from Stream
74+ -- ** Write to Handle
75+ -- | 'TextEncoding', 'NewLineMode', and 'Buffering' options of the
76+ -- underlying handle are ignored. The write occurs from the current seek
77+ -- position of the file handle. The write behavior depends on the 'IOMode'
68 -- , writeUtf8
81 -- , writeUtf8
69 -- , writeUtf8ByLines
82 -- , writeUtf8ByLines
@@ -157,7 +170,7 @@ readArrayUpto size h = do
157-- Array IO (output)
170-- Array IO (output)
158-------------------------------------------------------------------------------
171-------------------------------------------------------------------------------
160−-- | Write an Array to a file handle.
173+-- | Write an 'Array' to a file handle.
162-- @since 0.7.0
175-- @since 0.7.0
163{-# INLINABLE writeArray #-}
176{-# INLINABLE writeArray #-}
@@ -188,6 +201,10 @@ _readArraysOfUpto size h = go
189 else yld arr go
202 else yld arr go
204+-- | @readArraysOfUpto size handle@ reads a stream of arrays from the file
205+-- handle @handle@. The maximum size of a single array is limited to @size@.
191{-# INLINE_NORMAL readArraysOfUpto #-}
208{-# INLINE_NORMAL readArraysOfUpto #-}
192readArraysOfUpto :: (IsStream t, MonadIO m) => Int -> Handle -> t m (Array Word8)
209readArraysOfUpto :: (IsStream t, MonadIO m) => Int -> Handle -> t m (Array Word8)
193readArraysOfUpto size h = D.fromStreamD (D.Stream step ())
210readArraysOfUpto size h = D.fromStreamD (D.Stream step ())
@@ -202,10 +219,9 @@ readArraysOfUpto size h = D.fromStreamD (D.Stream step ())
203-- XXX read 'Array a' instead of Word8
220-- XXX read 'Array a' instead of Word8
205−-- | @readArrays h@ reads a stream of arrays from file handle @h@.
222+-- | @readArrays handle@ reads a stream of arrays from the specified file
206−-- The maximum size of a single array is limited to @defaultChunkSize@.
223+-- handle. The maximum size of a single array is limited to
207−-- 'readArrays' ignores the prevailing 'TextEncoding' and 'NewlineMode'
224+-- @defaultChunkSize@.
210-- > readArrays = readArraysOfUpto defaultChunkSize
226-- > readArrays = readArraysOfUpto defaultChunkSize
@@ -223,19 +239,19 @@ readArrays = readArraysOfUpto defaultChunkSize
223-- also control the read throughput in mbps or IOPS.
239-- also control the read throughput in mbps or IOPS.
225-- | @readByChunksUpto chunkSize handle@ reads a byte stream from a file
241-- | @readByChunksUpto chunkSize handle@ reads a byte stream from a file
226−-- handle, reads are performed in chunks of up to @chunkSize@. The stream ends
242+-- handle, reads are performed in chunks of up to @chunkSize@.
227−-- as soon as EOF is encountered.
229{-# INLINE readByChunksUpto #-}
245{-# INLINE readByChunksUpto #-}
230readByChunksUpto :: (IsStream t, MonadIO m) => Int -> Handle -> t m Word8
246readByChunksUpto :: (IsStream t, MonadIO m) => Int -> Handle -> t m Word8
231readByChunksUpto chunkSize h = A.flattenArrays $ readArraysOfUpto chunkSize h
247readByChunksUpto chunkSize h = A.flattenArrays $ readArraysOfUpto chunkSize h
250+-- Generate a stream of elements of the given type from a file 'Handle'.
234-- read :: (IsStream t, MonadIO m, Storable a) => Handle -> t m a
251-- read :: (IsStream t, MonadIO m, Storable a) => Handle -> t m a
236-- > read = 'readByChunks' A.defaultChunkSize
253-- > read = 'readByChunks' A.defaultChunkSize
237−-- | Generate a stream of elements of the given type from a file 'Handle'. The
254+-- | Generate a byte stream from a file 'Handle'.
238−-- stream ends when EOF is encountered.
240-- @since 0.7.0
256-- @since 0.7.0
241{-# INLINE read #-}
257{-# INLINE read #-}
@@ -253,10 +269,10 @@ read = A.flattenArrays . readArrays
253writeArrays :: (MonadIO m, Storable a) => Handle -> SerialT m (Array a) -> m ()
269writeArrays :: (MonadIO m, Storable a) => Handle -> SerialT m (Array a) -> m ()
254writeArrays h m = S.mapM_ (liftIO . writeArray h) m
270writeArrays h m = S.mapM_ (liftIO . writeArray h) m
272+-- | @writeArraysPackedUpto chunkSize handle stream@ writes a stream of arrays
256−-- | Write a stream of arrays to a handle after coalescing them in chunks of
273+-- to @handle@ after coalescing the adjacent arrays in chunks of @chunkSize@.
257−-- specified size. The chunk size is only a maximum and the actual writes could
274+-- The chunk size is only a maximum and the actual writes could be smaller as
258−-- be smaller than that as we do not split the arrays to fit them to the
275+-- we do not split the arrays to fit exactly to the specified size.
261-- @since 0.7.0
277-- @since 0.7.0
262{-# INLINE writeArraysPackedUpto #-}
278{-# INLINE writeArraysPackedUpto #-}
@@ -272,9 +288,9 @@ writeArraysPackedUpto n h xs = writeArrays h $ A.packArraysChunksOf n xs
272-- do not want buffering to occur at GHC level as well. Same thing applies to
288-- do not want buffering to occur at GHC level as well. Same thing applies to
273-- writes as well.
289-- writes as well.
275−-- | Like 'write' but provides control over the write buffer. Output will
291+-- | @writeByChunksOf chunkSize handle stream@ writes @stream@ to @handle@ in
276−-- be written to the IO device as soon as we collect the specified number of
292+-- chunks of @chunkSize@. A write is performed to the IO device as soon as we
277−-- input elements.
293+-- collect the required input size.
279-- @since 0.7.0
295-- @since 0.7.0
280{-# INLINE writeByChunksOf #-}
296{-# INLINE writeByChunksOf #-}
@@ -283,9 +299,8 @@ writeByChunksOf n h m = writeArrays h $ A.arraysOf n m
284-- > write = 'writeByChunksOf' A.defaultChunkSize
300-- > write = 'writeByChunksOf' A.defaultChunkSize
286−-- | Write a byte stream to a file handle. Combines the bytes in chunks of size
302+-- | Write a byte stream to a file handle. Combines the bytes in chunks of
287−-- up to 'A.defaultChunkSize' before writing. Note that the write behavior
303+-- up to 'A.defaultChunkSize' before writing.
288−-- depends on the 'IOMode' and the current seek position of the handle.
290-- @since 0.7.0
305-- @since 0.7.0
291{-# INLINE write #-}
306{-# INLINE write #-}
@@ -370,6 +385,23 @@ writeByFrames :: (IsStream t, MonadIO m, Storable a)
370 => Array a -> Handle -> t m a -> m ()
385 => Array a -> Handle -> t m a -> m ()
371writeByFrames = undefined
386writeByFrames = undefined
388+-------------------------------------------------------------------------------
390+-------------------------------------------------------------------------------
392+-- | Write collecting the input in sessions of n seconds or if chunkSize
394+{-# INLINE writeByChunksOrSessionsOf #-}
395+writeByChunksOrSessionsOf :: MonadIO m
396+ => Int -> Double -> Handle -> SerialT m Word8 -> m ()
397+writeByChunksOrSessionsOf chunkSize sessionSize h m = undefined
399+-- | Write collecting the input in sessions of n seconds or if defaultChunkSize
401+{-# INLINE writeBySessionsOf #-}
402+writeBySessionsOf :: MonadIO m => Double -> Handle -> SerialT m Word8 -> m ()
403+writeBySessionsOf n = writeByChunksOrSessionsOf defaultChunkSize n
373-------------------------------------------------------------------------------
405-------------------------------------------------------------------------------
374-- Random Access IO (Seek)
406-- Random Access IO (Seek)
375-------------------------------------------------------------------------------
407-------------------------------------------------------------------------------