User Tools

Site Tools


codesnippets:filesystemioandstreams

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
codesnippets:filesystemioandstreams [2021/04/20 13:01] – created f2b216codesnippets:filesystemioandstreams [2025/10/08 00:48] (current) – external edit 127.0.0.1
Line 1: Line 1:
 +~~DISCUSSION ~~
 ====== Filesystem IO and streams ====== ====== Filesystem IO and streams ======
  
   *example:   *example:
-    * code<code Haskell>+    * code, module FileSystem<code Haskell>
 {-| {-|
 Description : is to provides a generalised, abstract, and save interface to the files system. Description : is to provides a generalised, abstract, and save interface to the files system.
Line 17: Line 18:
         * uniform types for identification of input and output streams ('Inp', 'Out')         * uniform types for identification of input and output streams ('Inp', 'Out')
  
-        * higher order functions (stream handler functions, '(SysIo.Handle -> IO s)', '(SysIo.Handle -> s -> IO ())') are applied on streams+        * higher order functions encapsulated in data types ('DataReader', 'DataWriter') are applied on streams
  
     * can not cause error by "invalid characters", as long as the stream handler functions do not cause them     * can not cause error by "invalid characters", as long as the stream handler functions do not cause them
  
-* supports the following file system features: +    * supports the following file system features: 
-  +     
-    * deletion of files +        * deletion of files 
-    reading and writing streams + 
-  +        processing (read and write at once) and writing streams 
-* supports the following data types: +     
-  +    * supports the following data types: 
-    * Octets+     
 +        * Octets 
 + 
 +NOTE: There is no isolated read function like the write function, because this would lead to errors like "illegal operation (delayed read on closed handle)"
 +Background: The function hGetContents needs an open file handle, that may be closed before the lazy String has been evaluated.
  
 * example * example
    
     @     @
-    import qualified OctetsVertable as Oct +import qualified FileSystem as FS 
-    import qualified FileSystem as FS+import qualified System.IO as SysIo
  
-    main :: IO () +main :: IO () 
-    main =  +main =  
-        do +        FS.processData 
-            o1 <- FS.readFromStream (FS.FileInp ".\\test\\Spec.hs"Oct.getOctets +            (FS.DataReader (FS.FileInp ".\\test\\a.txt"SysIo.hGetContents) 
-            FS.writeToStream (FS.FileOut ".\\test\\Spec-2.hs"Oct.putOctets o1 +            
-            FS.writeToStream FS.StdOut Oct.putOctets o1 +                FS.DataWriter (FS.FileOut ".\\test\\b.txt"SysIo.hPutStr,  
-            FS.writeToStream FS.StdErr Oct.putOctets o1+                FS.DataWriter FS.StdOut SysIo.hPutStr,  
 +                FS.DataWriter FS.StdErr SysIo.hPutStr 
 +            ]
     @     @
    
-    * copies the file "Spec.hs" in ".\test" to "Spec-2.hs+    * copies the file "a.txt" in ".\test" to "b.txt
-    * sends to octal representation to 'stdout', and 'stderr'+    * sends the file content of "a.txt" also to 'stdout', and 'stderr'
     * will not cause uncaught exception caused by "invalid characters"     * will not cause uncaught exception caused by "invalid characters"
 -} -}
Line 52: Line 59:
         Inp(..),          Inp(..), 
         Out(..),          Out(..), 
 +        DataReader(..), 
 +        DataWriter(..), 
         removeFileIfExists,          removeFileIfExists, 
-        readFromStream,  +        processData,  
-        writeToStream+        writeToData
     ) where     ) where
  
Line 83: Line 92:
                        | otherwise = Excp.throwIO e                        | otherwise = Excp.throwIO e
  
-readFromStream :: Inp -> (SysIo.Handle -> IO s) -> IO s +data DataReader s =  
-readFromStream StdInp f = f SysIo.stdin +    DataReader {  
-readFromStream (FileInp sFileName) f = +        rinp :: Inp,  
 +        rfRead :: (SysIo.Handle -> IO s) } 
 + 
 +data DataWriter s =  
 +    DataWriter {  
 +        rout :: Out,  
 +        rfWrite :: (SysIo.Handle -> s -> IO ()) } 
 + 
 +processData :: (DataReader a-> [DataWriter a] -> IO () 
 +processData (DataReader StdInp f) lwrt  
 +    do 
 +        dt <- f SysIo.stdin 
 +        processData' dt lwrt 
 +processData (DataReader (FileInp sFileName) f) lwrt 
     do     do
         hFile <- SysIo.openFile sFileName SysIo.ReadMode         hFile <- SysIo.openFile sFileName SysIo.ReadMode
-        <- f hFile+        dt <- f hFile 
 +        processData' dt lwrt
         SysIo.hClose hFile         SysIo.hClose hFile
-        return x 
  
-writeToStream :: Out -> (SysIo.Handle -> s -> IO ()) -> -> IO () +processData' :: -> [DataWriter a] -> IO () 
-writeToStream NullOut _ _ = return () +processData' x [] = return () 
-writeToStream StdOut f x = f SysIo.stdout x +processData' x (wrt:lrwrt) =  
-writeToStream StdErr f x = f SysIo.stderr x +    do 
-writeToStream (FileOut sFileName) f x = +        writeToData wrt x 
 +        processData' x lrwrt 
 + 
 +writeToData :: (DataWriter a) -> -> IO () 
 +writeToData (DataWriter NullOut __ = return () 
 +writeToData (DataWriter StdOut fx = f SysIo.stdout x 
 +writeToData (DataWriter StdErr fx = f SysIo.stderr x 
 +writeToData (DataWriter (FileOut sFileName) fx = 
     do     do
         hFile <- SysIo.openFile sFileName SysIo.WriteMode         hFile <- SysIo.openFile sFileName SysIo.WriteMode
Line 102: Line 131:
         SysIo.hClose hFile         SysIo.hClose hFile
 </code> </code>
 +    * code, use case of files system<code Haskell>
 +import qualified FileSystem as FS
 +import qualified System.IO as SysIo
 +
 +main :: IO ()
 +main = 
 +        FS.processData
 +            (FS.DataReader (FS.FileInp ".\\test\\a.txt") SysIo.hGetContents)
 +            [
 +                FS.DataWriter (FS.FileOut ".\\test\\b.txt") SysIo.hPutStr, 
 +                FS.DataWriter FS.StdOut SysIo.hPutStr, 
 +                FS.DataWriter FS.StdErr SysIo.hPutStr
 +            ]
 +</code>
 +    * compiles, error and warning free, with compiler: GHC 8.10.4, using compiler option -Wall
 +    * executes with output as file copy of "a.txt" to "b.txt", ''stdout'', and ''stderr''
 +  * example, with conversions
 +    * code:<code Haskell>
 +import qualified FileSystem as FS
 +import qualified System.IO as SysIo
 +import qualified Data.Char as Ch
 +
 +main :: IO ()
 +main = 
 +        FS.processData
 +            (FS.DataReader (FS.FileInp ".\\test\\a.txt") hGetToUpper)
 +            [
 +                FS.DataWriter (FS.FileOut ".\\test\\b.txt") SysIo.hPutStr, 
 +                FS.DataWriter FS.StdOut hPutToLower, 
 +                FS.DataWriter FS.StdErr SysIo.hPutStr
 +            ]
 +
 +hGetToUpper :: SysIo.Handle -> IO String
 +hGetToUpper h = 
 +    do
 +        s <- SysIo.hGetContents h
 +        return (fmap Ch.toUpper s)
 +
 +hPutToLower :: SysIo.Handle -> String -> IO ()
 +hPutToLower h s = SysIo.hPutStr h (fmap Ch.toLower s)
 +</code>
 +    * input, file "a.txt"<code>
 +The quick brown fox jumps over the lazy dog.
 +</code>
 +    * output, in terminal:<code>
 +the quick brown fox jumps over the lazy dog.
 +THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.
 +</code>
 +    * output, file "b.txt":<code>
 +THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.
 +</code>
 +
 +
 +===== ✎ =====
 +~~DISCUSSION~~
codesnippets/filesystemioandstreams.1618916488.txt.gz · Last modified: (external edit)

Except where otherwise noted, content on this wiki is licensed under the following license: CC0 1.0 Universal
CC0 1.0 Universal Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki