Maintainer | Bas van Dijk <v.dijk.bas@gmail.com> |
---|
This module exports a Handle
to a file which is parameterized with the
IOMode the handle is in. All operations on handles explicitly specify the
needed IOMode. This way it is impossible to read from a write-only handle or
write to a read-only handle for example.
This modules re-exports everything from System.IO
so you can just replace:
import System.IO
with: import System.IO.ExplicitIOModes
, change some type
signatures and expect everything to type-check.
There's one exception to this last statement: If you are using the standard
handles stdin
, stdout
or stderr
in a mode which isn't their default
mode (ReadMode
for stdin
and WriteMode
for stdout
and stderr
) you
have to cast
these handles to the expected IOMode.
- data IO a
- fixIO :: (a -> IO a) -> IO a
- type FilePath = String
- data Handle ioMode
- data IOMode ioMode where
- regularIOMode :: IOMode ioMode -> IOMode
- data ReadMode
- data WriteMode
- data AppendMode
- data ReadWriteMode
- class ReadModes ioMode
- class WriteModes ioMode
- stdin :: Handle ReadMode
- stdout :: Handle WriteMode
- stderr :: Handle WriteMode
- cast :: forall anyIOMode castedIOMode. CheckMode castedIOMode => Handle anyIOMode -> IO (Maybe (Handle castedIOMode))
- class CheckMode ioMode
- withFile :: FilePath -> IOMode ioMode -> (Handle ioMode -> IO α) -> IO α
- openFile :: FilePath -> IOMode ioMode -> IO (Handle ioMode)
- hClose :: Handle ioMode -> IO ()
- readFile :: FilePath -> IO String
- writeFile :: FilePath -> String -> IO ()
- appendFile :: FilePath -> String -> IO ()
- hFileSize :: Handle ioMode -> IO Integer
- hSetFileSize :: Handle ioMode -> Integer -> IO ()
- hIsEOF :: ReadModes ioMode => Handle ioMode -> IO Bool
- isEOF :: IO Bool
- data BufferMode
- = NoBuffering
- | LineBuffering
- | BlockBuffering (Maybe Int)
- hSetBuffering :: Handle ioMode -> BufferMode -> IO ()
- hGetBuffering :: Handle ioMode -> IO BufferMode
- hFlush :: Handle ioMode -> IO ()
- hGetPosn :: Handle ioMode -> IO HandlePosn
- hSetPosn :: HandlePosn -> IO ()
- data HandlePosn
- hSeek :: Handle ioMode -> SeekMode -> Integer -> IO ()
- data SeekMode
- hTell :: Handle ioMode -> IO Integer
- hIsOpen :: Handle ioMode -> IO Bool
- hIsClosed :: Handle ioMode -> IO Bool
- hIsReadable :: Handle ioMode -> IO Bool
- hIsWritable :: Handle ioMode -> IO Bool
- hIsSeekable :: Handle ioMode -> IO Bool
- hIsTerminalDevice :: Handle ioMode -> IO Bool
- hSetEcho :: Handle ioMode -> Bool -> IO ()
- hGetEcho :: Handle ioMode -> IO Bool
- hShow :: Handle ioMode -> IO String
- hWaitForInput :: ReadModes ioMode => Handle ioMode -> Int -> IO Bool
- hReady :: ReadModes ioMode => Handle ioMode -> IO Bool
- hGetChar :: ReadModes ioMode => Handle ioMode -> IO Char
- hGetLine :: ReadModes ioMode => Handle ioMode -> IO String
- hLookAhead :: ReadModes ioMode => Handle ioMode -> IO Char
- hGetContents :: ReadModes ioMode => Handle ioMode -> IO String
- hPutChar :: WriteModes ioMode => Handle ioMode -> Char -> IO ()
- hPutStr :: WriteModes ioMode => Handle ioMode -> String -> IO ()
- hPutStrLn :: WriteModes ioMode => Handle ioMode -> String -> IO ()
- hPrint :: (WriteModes ioMode, Show α) => Handle ioMode -> α -> IO ()
- interact :: (String -> String) -> IO ()
- putChar :: Char -> IO ()
- putStr :: String -> IO ()
- putStrLn :: String -> IO ()
- print :: Show a => a -> IO ()
- getChar :: IO Char
- getLine :: IO String
- getContents :: IO String
- readIO :: Read a => String -> IO a
- readLn :: Read a => IO a
- withBinaryFile :: FilePath -> IOMode ioMode -> (Handle ioMode -> IO r) -> IO r
- openBinaryFile :: FilePath -> IOMode ioMode -> IO (Handle ioMode)
- hSetBinaryMode :: Handle ioMode -> Bool -> IO ()
- hPutBuf :: WriteModes ioMode => Handle ioMode -> Ptr α -> Int -> IO ()
- hGetBuf :: ReadModes ioMode => Handle ioMode -> Ptr α -> Int -> IO Int
- hPutBufNonBlocking :: WriteModes ioMode => Handle ioMode -> Ptr α -> Int -> IO Int
- hGetBufNonBlocking :: ReadModes ioMode => Handle ioMode -> Ptr α -> Int -> IO Int
- openTempFile :: FilePath -> String -> IO (FilePath, Handle ReadWriteMode)
- openBinaryTempFile :: FilePath -> String -> IO (FilePath, Handle ReadWriteMode)
- openTempFileWithDefaultPermissions :: FilePath -> String -> IO (FilePath, Handle ReadWriteMode)
- openBinaryTempFileWithDefaultPermissions :: FilePath -> String -> IO (FilePath, Handle ReadWriteMode)
- hSetEncoding :: Handle ioMode -> TextEncoding -> IO ()
- hGetEncoding :: Handle ioMode -> IO (Maybe TextEncoding)
- data TextEncoding
- latin1 :: TextEncoding
- utf8 :: TextEncoding
- utf8_bom :: TextEncoding
- utf16 :: TextEncoding
- utf16le :: TextEncoding
- utf16be :: TextEncoding
- utf32 :: TextEncoding
- utf32le :: TextEncoding
- utf32be :: TextEncoding
- localeEncoding :: TextEncoding
- mkTextEncoding :: String -> IO TextEncoding
- hSetNewlineMode :: Handle ioMode -> NewlineMode -> IO ()
- data Newline
- nativeNewline :: Newline
- data NewlineMode = NewlineMode {}
- noNewlineTranslation :: NewlineMode
- universalNewlineMode :: NewlineMode
- nativeNewlineMode :: NewlineMode
The IO monad
data IO a
A value of type
is a computation which, when performed,
does some I/O before returning a value of type IO
aa
.
There is really only one way to "perform" an I/O action: bind it to
Main.main
in your program. When your program is run, the I/O will
be performed. It isn't possible to perform I/O from an arbitrary
function, unless that function is itself in the IO
monad and called
at some point, directly or indirectly, from Main.main
.
IO
is a monad, so IO
actions can be combined using either the do-notation
or the >> and >>= operations from the Monad class.
Files and handles
File and directory names are values of type String
, whose precise
meaning is operating system dependent. Files can be opened, yielding a
handle which can then be used to operate on the contents of that file.
A handle to a file with an explicit IOMode.
Wraps: System.IO.
.
Handle
IO Modes
Types that represent the IOMode a Handle
can be in.
data IOMode ioMode whereSource
The IOMode GADT which for each constructor specifies the associated IOMode type.
Also see: System.IO.
IOMode
.
regularIOMode :: IOMode ioMode -> IOModeSource
Retrieves the regular System.IO.
IOMode
.
data ReadWriteMode Source
Both read and write.
Class of readable IO mode types.
class WriteModes ioMode Source
Class of writable IO mode types.
Standard handles
These standard handles have concrete IOModes by default which work
for the majority of cases. In the rare occasion that you know these
handles have different IOModes you can cast
them.
cast :: forall anyIOMode castedIOMode. CheckMode castedIOMode => Handle anyIOMode -> IO (Maybe (Handle castedIOMode))Source
Cast the IOMode of a handle if the handle supports it.
Opening and closing files
Opening files
withFile :: FilePath -> IOMode ioMode -> (Handle ioMode -> IO α) -> IO αSource
Wraps: System.IO.
withFile
.
Closing files
Special cases
readFile :: FilePath -> IO String
The readFile
function reads a file and
returns the contents of the file as a string.
The file is read lazily, on demand, as with getContents
.
writeFile :: FilePath -> String -> IO ()
The computation writeFile
file str
function writes the string str
,
to the file file
.
appendFile :: FilePath -> String -> IO ()
The computation appendFile
file str
function appends the string str
,
to the file file
.
Note that writeFile
and appendFile
write a literal string
to a file. To write a value of any printable type, as with print
,
use the show
function to convert the value to a string first.
main = appendFile "squares" (show [(x,x*x) | x <- [0,0.1..2]])
Operations on handles
Determining and changing the size of a file
hSetFileSize :: Handle ioMode -> Integer -> IO ()Source
Wraps: System.IO.
hSetFileSize
.
Detecting the end of input
Buffering operations
data BufferMode
Three kinds of buffering are supported: line-buffering, block-buffering or no-buffering. These modes have the following effects. For output, items are written out, or flushed, from the internal buffer according to the buffer mode:
- line-buffering: the entire output buffer is flushed whenever a newline is output, the buffer overflows, a System.IO.hFlush is issued, or the handle is closed.
- block-buffering: the entire buffer is written out whenever it overflows, a System.IO.hFlush is issued, or the handle is closed.
- no-buffering: output is written immediately, and never stored in the buffer.
An implementation is free to flush the buffer more frequently, but not less frequently, than specified above. The output buffer is emptied as soon as it has been written out.
Similarly, input occurs according to the buffer mode for the handle:
- line-buffering: when the buffer for the handle is not empty, the next item is obtained from the buffer; otherwise, when the buffer is empty, characters up to and including the next newline character are read into the buffer. No characters are available until the newline character is available or the buffer is full.
- block-buffering: when the buffer for the handle becomes empty, the next block of data is read into the buffer.
- no-buffering: the next input item is read and returned. The System.IO.hLookAhead operation implies that even a no-buffered handle may require a one-character buffer.
The default buffering mode when a handle is opened is implementation-dependent and may depend on the file system object which is attached to that handle. For most implementations, physical files will normally be block-buffered and terminals will normally be line-buffered.
NoBuffering | buffering is disabled if possible. |
LineBuffering | line-buffering should be enabled if possible. |
BlockBuffering (Maybe Int) | block-buffering should be enabled if possible.
The size of the buffer is |
hSetBuffering :: Handle ioMode -> BufferMode -> IO ()Source
Wraps: System.IO.
hSetBuffering
.
hGetBuffering :: Handle ioMode -> IO BufferModeSource
Wraps: System.IO.
hGetBuffering
.
Repositioning handles
hSetPosn :: HandlePosn -> IO ()
data HandlePosn
data SeekMode
A mode that determines the effect of hSeek hdl mode i
, as follows:
AbsoluteSeek | the position of |
RelativeSeek | the position of |
SeekFromEnd | the position of |
Handle properties
hIsReadable :: Handle ioMode -> IO BoolSource
Wraps: System.IO.
hIsReadable
.
hIsWritable :: Handle ioMode -> IO BoolSource
Wraps: System.IO.
hIsWritable
.
hIsSeekable :: Handle ioMode -> IO BoolSource
Wraps: System.IO.
hIsSeekable
.
Terminal operations (not portable: GHC/Hugs only)
hIsTerminalDevice :: Handle ioMode -> IO BoolSource
Wraps: System.IO.
hIsTerminalDevice
.
Showing handle state (not portable: GHC only)
Text input and output
Text input
Note that the following text input operations are polymorphic in the
IOMode of the given handle. However the IOModes are restricted to
ReadModes
only which can be either ReadMode
or ReadWriteMode
.
hWaitForInput :: ReadModes ioMode => Handle ioMode -> Int -> IO BoolSource
Wraps: System.IO.
hWaitForInput
.
hLookAhead :: ReadModes ioMode => Handle ioMode -> IO CharSource
Wraps: System.IO.
hLookAhead
.
hGetContents :: ReadModes ioMode => Handle ioMode -> IO StringSource
Wraps: System.IO.
hGetContents
.
Text ouput
Note that the following text output operations are polymorphic in the
IOMode of the given handle. However the IOModes are restricted to
WriteModes
only which can be either WriteMode
, AppendMode
or
ReadWriteMode
.
Special cases for standard input and output
These functions are also exported by the "Prelude".
interact :: (String -> String) -> IO ()
The interact
function takes a function of type String->String
as its argument. The entire input from the standard input device is
passed to this function as its argument, and the resulting string is
output on the standard output device.
The print
function outputs a value of any printable type to the
standard output device.
Printable types are those that are instances of class Show
; print
converts values to strings for output using the show
operation and
adds a newline.
For example, a program to print the first 20 integers and their powers of 2 could be written as:
main = print ([(n, 2^n) | n <- [0..19]])
getContents :: IO String
The getContents
operation returns all user input as a single string,
which is read lazily as it is needed
(same as hGetContents
stdin
).
Binary input and output
withBinaryFile :: FilePath -> IOMode ioMode -> (Handle ioMode -> IO r) -> IO rSource
Wraps: System.IO.
withBinaryFile
.
openBinaryFile :: FilePath -> IOMode ioMode -> IO (Handle ioMode)Source
Wraps: System.IO.
openBinaryFile
.
hSetBinaryMode :: Handle ioMode -> Bool -> IO ()Source
Wraps: System.IO.
hSetBinaryMode
.
hPutBuf :: WriteModes ioMode => Handle ioMode -> Ptr α -> Int -> IO ()Source
Wraps: System.IO.
hPutBuf
.
hGetBuf :: ReadModes ioMode => Handle ioMode -> Ptr α -> Int -> IO IntSource
Wraps: System.IO.
hGetBuf
.
hPutBufNonBlocking :: WriteModes ioMode => Handle ioMode -> Ptr α -> Int -> IO IntSource
Wraps: System.IO.
hPutBufNonBlocking
.
hGetBufNonBlocking :: ReadModes ioMode => Handle ioMode -> Ptr α -> Int -> IO IntSource
Wraps: System.IO.
hGetBufNonBlocking
.
Temporary files
openTempFile :: FilePath -> String -> IO (FilePath, Handle ReadWriteMode)Source
Wraps: System.IO.
openTempFile
.
openBinaryTempFile :: FilePath -> String -> IO (FilePath, Handle ReadWriteMode)Source
Wraps: System.IO.
openBinaryTempFile
.
openTempFileWithDefaultPermissions :: FilePath -> String -> IO (FilePath, Handle ReadWriteMode)Source
openBinaryTempFileWithDefaultPermissions :: FilePath -> String -> IO (FilePath, Handle ReadWriteMode)Source
Unicode encoding/decoding
hSetEncoding :: Handle ioMode -> TextEncoding -> IO ()Source
hGetEncoding :: Handle ioMode -> IO (Maybe TextEncoding)Source
Unicode encodings
data TextEncoding
A TextEncoding
is a specification of a conversion scheme
between sequences of bytes and sequences of Unicode characters.
For example, UTF-8 is an encoding of Unicode characters into a sequence
of bytes. The TextEncoding
for UTF-8 is utf8.
The Latin1 (ISO8859-1) encoding. This encoding maps bytes
directly to the first 256 Unicode code points, and is thus not a
complete Unicode encoding. An attempt to write a character greater than
'\255' to a Handle using the latin1
encoding will result in an error.
utf8 :: TextEncoding
The UTF-8 Unicode encoding
The UTF-8 Unicode encoding, with a byte-order-mark (BOM; the byte
sequence 0xEF 0xBB 0xBF). This encoding behaves like utf8
,
except that on input, the BOM sequence is ignored at the beginning
of the stream, and on output, the BOM sequence is prepended.
The byte-order-mark is strictly unnecessary in UTF-8, but is sometimes used to identify the encoding of a file.
The UTF-16 Unicode encoding (a byte-order-mark should be used to indicate endianness).
The UTF-16 Unicode encoding (litte-endian)
The UTF-16 Unicode encoding (big-endian)
The UTF-32 Unicode encoding (a byte-order-mark should be used to indicate endianness).
The UTF-32 Unicode encoding (litte-endian)
The UTF-32 Unicode encoding (big-endian)
localeEncoding :: TextEncoding
The Unicode encoding of the current locale
mkTextEncoding :: String -> IO TextEncoding
Look up the named Unicode encoding. May fail with
- isDoesNotExistError if the encoding is unknown
The set of known encodings is system-dependent, but includes at least:
UTF-8
-
UTF-16
,UTF-16BE
,UTF-16LE
-
UTF-32
,UTF-32BE
,UTF-32LE
On systems using GNU iconv (e.g. Linux), there is additional notation for specifying how illegal characters are handled:
- a suffix of
//IGNORE
, e.g.UTF-8//IGNORE
, will cause all illegal sequences on input to be ignored, and on output will drop all code points that have no representation in the target encoding. - a suffix of
//TRANSLIT
will choose a replacement character for illegal sequences or code points.
On Windows, you can access supported code pages with the prefix
CP
; for example, "CP1250"
.
Newline conversion
hSetNewlineMode :: Handle ioMode -> NewlineMode -> IO ()Source
data Newline
The representation of a newline in the external file or stream.
data NewlineMode
Specifies the translation, if any, of newline characters between internal Strings and the external file or stream. Haskell Strings are assumed to represent newlines with the '\n' character; the newline mode specifies how to translate '\n' on output, and what to translate into '\n' on input.
noNewlineTranslation :: NewlineMode
Do no newline translation at all.
noNewlineTranslation = NewlineMode { inputNL = LF, outputNL = LF }
universalNewlineMode :: NewlineMode
Map '\r\n' into '\n' on input, and '\n' to the native newline
represetnation on output. This mode can be used on any platform, and
works with text files using any newline convention. The downside is
that readFile >>= writeFile
might yield a different file.
universalNewlineMode = NewlineMode { inputNL = CRLF,
outputNL = nativeNewline }
nativeNewlineMode :: NewlineMode
Use the native newline representation on both input and output
nativeNewlineMode = NewlineMode { inputNL = nativeNewline
outputNL = nativeNewline }