Movatterモバイル変換


[0]ホーム

URL:


{-# LANGUAGE Trustworthy #-}{-# LANGUAGE CPP, NoImplicitPrelude #-}------------------------------------------------------------------------------- |-- Module      :  System.IO-- Copyright   :  (c) The University of Glasgow 2001-- License     :  BSD-style (see the file libraries/base/LICENSE)---- Maintainer  :  libraries@haskell.org-- Stability   :  stable-- Portability :  portable---- The standard IO library.-------------------------------------------------------------------------------moduleSystem.IO(-- * The IO monadIO,-- instance MonadFixfixIO,-- :: (a -> IO a) -> IO a-- * Files and handlesFilePath,-- :: StringHandle,-- abstract, instance of: Eq, Show.-- | GHC note: a 'Handle' will be automatically closed when the garbage-- collector detects that it has become unreferenced by the program.-- However, relying on this behaviour is not generally recommended:-- the garbage collector is unpredictable.  If possible, use-- an explicit 'hClose' to close 'Handle's when they are no longer-- required.  GHC does not currently attempt to free up file-- descriptors when they have run out, it is your responsibility to-- ensure that this doesn't happen.-- ** Standard handles-- | Three handles are allocated during program initialisation,-- and are initially open.stdin,stdout,stderr,-- :: Handle-- * Opening and closing files-- ** Opening fileswithFile,openFile,-- :: FilePath -> IOMode -> IO HandleIOMode(ReadMode,WriteMode,AppendMode,ReadWriteMode),-- ** Closing fileshClose,-- :: Handle -> IO ()-- ** Special cases-- | These functions are also exported by the "Prelude".readFile,-- :: FilePath -> IO StringwriteFile,-- :: FilePath -> String -> IO ()appendFile,-- :: FilePath -> String -> IO ()-- ** File locking-- $locking-- * Operations on handles-- ** Determining and changing the size of a filehFileSize,-- :: Handle -> IO Integer#ifdef __GLASGOW_HASKELL__hSetFileSize,-- :: Handle -> Integer -> IO ()#endif-- ** Detecting the end of inputhIsEOF,-- :: Handle -> IO BoolisEOF,-- :: IO Bool-- ** Buffering operationsBufferMode(NoBuffering,LineBuffering,BlockBuffering),hSetBuffering,-- :: Handle -> BufferMode -> IO ()hGetBuffering,-- :: Handle -> IO BufferModehFlush,-- :: Handle -> IO ()-- ** Repositioning handleshGetPosn,-- :: Handle -> IO HandlePosnhSetPosn,-- :: HandlePosn -> IO ()HandlePosn,-- abstract, instance of: Eq, Show.hSeek,-- :: Handle -> SeekMode -> Integer -> IO ()SeekMode(AbsoluteSeek,RelativeSeek,SeekFromEnd),#if !defined(__NHC__)hTell,-- :: Handle -> IO Integer#endif-- ** Handle propertieshIsOpen,hIsClosed,-- :: Handle -> IO BoolhIsReadable,hIsWritable,-- :: Handle -> IO BoolhIsSeekable,-- :: Handle -> IO Bool-- ** Terminal operations (not portable: GHC\/Hugs only)#if !defined(__NHC__)hIsTerminalDevice,-- :: Handle -> IO BoolhSetEcho,-- :: Handle -> Bool -> IO ()hGetEcho,-- :: Handle -> IO Bool#endif-- ** Showing handle state (not portable: GHC only)#ifdef __GLASGOW_HASKELL__hShow,-- :: Handle -> IO String#endif-- * Text input and output-- ** Text inputhWaitForInput,-- :: Handle -> Int -> IO BoolhReady,-- :: Handle -> IO BoolhGetChar,-- :: Handle -> IO CharhGetLine,-- :: Handle -> IO [Char]hLookAhead,-- :: Handle -> IO CharhGetContents,-- :: Handle -> IO [Char]-- ** Text outputhPutChar,-- :: Handle -> Char -> IO ()hPutStr,-- :: Handle -> [Char] -> IO ()hPutStrLn,-- :: Handle -> [Char] -> IO ()hPrint,-- :: Show a => Handle -> a -> IO ()-- ** Special cases for standard input and output-- | These functions are also exported by the "Prelude".interact,-- :: (String -> String) -> IO ()putChar,-- :: Char   -> IO ()putStr,-- :: String -> IO ()putStrLn,-- :: String -> IO ()print,-- :: Show a => a -> IO ()getChar,-- :: IO ChargetLine,-- :: IO StringgetContents,-- :: IO StringreadIO,-- :: Read a => String -> IO areadLn,-- :: Read a => IO a-- * Binary input and outputwithBinaryFile,openBinaryFile,-- :: FilePath -> IOMode -> IO HandlehSetBinaryMode,-- :: Handle -> Bool -> IO ()hPutBuf,-- :: Handle -> Ptr a -> Int -> IO ()hGetBuf,-- :: Handle -> Ptr a -> Int -> IO Int#if !defined(__NHC__) && !defined(__HUGS__)hGetBufSome,-- :: Handle -> Ptr a -> Int -> IO InthPutBufNonBlocking,-- :: Handle -> Ptr a -> Int -> IO InthGetBufNonBlocking,-- :: Handle -> Ptr a -> Int -> IO Int#endif-- * Temporary filesopenTempFile,openBinaryTempFile,openTempFileWithDefaultPermissions,openBinaryTempFileWithDefaultPermissions,#if !defined(__NHC__) && !defined(__HUGS__)-- * Unicode encoding\/decoding-- | A text-mode 'Handle' has an associated 'TextEncoding', which-- is used to decode bytes into Unicode characters when reading,-- and encode Unicode characters into bytes when writing.---- The default 'TextEncoding' is the same as the default encoding-- on your system, which is also available as 'localeEncoding'.-- (GHC note: on Windows, we currently do not support double-byte-- encodings; if the console\'s code page is unsupported, then-- 'localeEncoding' will be 'latin1'.)---- Encoding and decoding errors are always detected and reported,-- except during lazy I/O ('hGetContents', 'getContents', and-- 'readFile'), where a decoding error merely results in-- termination of the character stream, as with other I/O errors.hSetEncoding,hGetEncoding,-- ** Unicode encodingsTextEncoding,latin1,utf8,utf8_bom,utf16,utf16le,utf16be,utf32,utf32le,utf32be,localeEncoding,char8,mkTextEncoding,#endif#if !defined(__NHC__) && !defined(__HUGS__)-- * Newline conversion-- | In Haskell, a newline is always represented by the character-- '\n'.  However, in files and external character streams, a-- newline may be represented by another character sequence, such-- as '\r\n'.---- A text-mode 'Handle' has an associated 'NewlineMode' that-- specifies how to transate newline characters.  The-- 'NewlineMode' specifies the input and output translation-- separately, so that for instance you can translate '\r\n'-- to '\n' on input, but leave newlines as '\n' on output.---- The default 'NewlineMode' for a 'Handle' is-- 'nativeNewlineMode', which does no translation on Unix systems,-- but translates '\r\n' to '\n' and back on Windows.---- Binary-mode 'Handle's do no newline translation at all.--hSetNewlineMode,Newline(..),nativeNewline,NewlineMode(..),noNewlineTranslation,universalNewlineMode,nativeNewlineMode,#endif)whereimportControl.Exception.Base#ifndef __NHC__importData.BitsimportData.ListimportData.MaybeimportForeign.C.ErrorimportForeign.C.TypesimportSystem.Posix.InternalsimportSystem.Posix.Types#endif#ifdef __GLASGOW_HASKELL__importGHC.BaseimportGHC.IOhiding(bracket,onException)importGHC.IO.IOModeimportGHC.IO.Handle.FDimportqualifiedGHC.IO.FDasFDimportGHC.IO.HandleimportGHC.IO.Handle.Text(hGetBufSome,hPutStrLn)importGHC.IORefimportGHC.IO.Exception(userError)importGHC.IO.EncodingimportGHC.NumimportText.ReadimportGHC.Show#endif#ifdef __HUGS__importHugs.IOimportHugs.IOExtsimportHugs.IORefimportSystem.IO.Unsafe(unsafeInterleaveIO)#endif#ifdef __NHC__importIO(Handle(),HandlePosn(),IOMode(ReadMode,WriteMode,AppendMode,ReadWriteMode),BufferMode(NoBuffering,LineBuffering,BlockBuffering),SeekMode(AbsoluteSeek,RelativeSeek,SeekFromEnd),stdin,stdout,stderr,openFile-- :: FilePath -> IOMode -> IO Handle,hClose-- :: Handle -> IO (),hFileSize-- :: Handle -> IO Integer,hIsEOF-- :: Handle -> IO Bool,isEOF-- :: IO Bool,hSetBuffering-- :: Handle -> BufferMode -> IO (),hGetBuffering-- :: Handle -> IO BufferMode,hFlush-- :: Handle -> IO (),hGetPosn-- :: Handle -> IO HandlePosn,hSetPosn-- :: HandlePosn -> IO (),hSeek-- :: Handle -> SeekMode -> Integer -> IO (),hWaitForInput-- :: Handle -> Int -> IO Bool,hGetChar-- :: Handle -> IO Char,hGetLine-- :: Handle -> IO [Char],hLookAhead-- :: Handle -> IO Char,hGetContents-- :: Handle -> IO [Char],hPutChar-- :: Handle -> Char -> IO (),hPutStr-- :: Handle -> [Char] -> IO (),hPutStrLn-- :: Handle -> [Char] -> IO (),hPrint-- :: Handle -> [Char] -> IO (),hReady-- :: Handle -> [Char] -> IO (),hIsOpen,hIsClosed-- :: Handle -> IO Bool,hIsReadable,hIsWritable-- :: Handle -> IO Bool,hIsSeekable-- :: Handle -> IO Bool,bracket,IO(),FilePath-- :: String)importNHC.IOExtras(fixIO,hPutBuf,hGetBuf)importNHC.FFI(Ptr)#endif-- ------------------------------------------------------------------------------- Standard IO#ifdef __GLASGOW_HASKELL__-- | Write a character to the standard output device-- (same as 'hPutChar' 'stdout').putChar::Char->IO()putCharc=hPutCharstdoutc-- | Write a string to the standard output device-- (same as 'hPutStr' 'stdout').putStr::String->IO()putStrs=hPutStrstdouts-- | The same as 'putStr', but adds a newline character.putStrLn::String->IO()putStrLns=hPutStrLnstdouts-- | 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]])print::Showa=>a->IO()printx=putStrLn(showx)-- | Read a character from the standard input device-- (same as 'hGetChar' 'stdin').getChar::IOChargetChar=hGetCharstdin-- | Read a line from the standard input device-- (same as 'hGetLine' 'stdin').getLine::IOStringgetLine=hGetLinestdin-- | The 'getContents' operation returns all user input as a single string,-- which is read lazily as it is needed-- (same as 'hGetContents' 'stdin').getContents::IOStringgetContents=hGetContentsstdin-- | 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.interact::(String->String)->IO()interactf=dos<-getContentsputStr(fs)-- | 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'.readFile::FilePath->IOStringreadFilename=openFilenameReadMode>>=hGetContents-- | The computation 'writeFile' @file str@ function writes the string @str@,-- to the file @file@.writeFile::FilePath->String->IO()writeFileftxt=withFilefWriteMode(\hdl->hPutStrhdltxt)-- | 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]])appendFile::FilePath->String->IO()appendFileftxt=withFilefAppendMode(\hdl->hPutStrhdltxt)-- | The 'readLn' function combines 'getLine' and 'readIO'.readLn::Reada=>IOareadLn=dol<-getLiner<-readIOlreturnr-- | The 'readIO' function is similar to 'read' except that it signals-- parse failure to the 'IO' monad instead of terminating the program.readIO::Reada=>String->IOareadIOs=case(do{(x,t)<-readss;("","")<-lext;returnx})of[x]->returnx[]->ioError(userError"Prelude.readIO: no parse")_->ioError(userError"Prelude.readIO: ambiguous parse")#endif  /* __GLASGOW_HASKELL__ */#ifndef __NHC__-- | Computation 'hReady' @hdl@ indicates whether at least one item is-- available for input from handle @hdl@.---- This operation may fail with:----  * 'System.IO.Error.isEOFError' if the end of file has been reached.hReady::Handle->IOBoolhReadyh=hWaitForInputh0-- | Computation 'hPrint' @hdl t@ writes the string representation of @t@-- given by the 'shows' function to the file or channel managed by @hdl@-- and appends a newline.---- This operation may fail with:----  * 'System.IO.Error.isFullError' if the device is full; or----  * 'System.IO.Error.isPermissionError' if another system resource limit would be exceeded.hPrint::Showa=>Handle->a->IO()hPrinthdl=hPutStrLnhdl.show#endif /* !__NHC__ */-- | @'withFile' name mode act@ opens a file using 'openFile' and passes-- the resulting handle to the computation @act@.  The handle will be-- closed on exit from 'withFile', whether by normal termination or by-- raising an exception.  If closing the handle raises an exception, then-- this exception will be raised by 'withFile' rather than any exception-- raised by 'act'.withFile::FilePath->IOMode->(Handle->IOr)->IOrwithFilenamemode=bracket(openFilenamemode)hClose-- | @'withBinaryFile' name mode act@ opens a file using 'openBinaryFile'-- and passes the resulting handle to the computation @act@.  The handle-- will be closed on exit from 'withBinaryFile', whether by normal-- termination or by raising an exception.withBinaryFile::FilePath->IOMode->(Handle->IOr)->IOrwithBinaryFilenamemode=bracket(openBinaryFilenamemode)hClose-- ----------------------------------------------------------------------------- fixIO#if defined(__GLASGOW_HASKELL__) || defined(__HUGS__)fixIO::(a->IOa)->IOafixIOk=doref<-newIORef(throwNonTermination)ans<-unsafeInterleaveIO(readIORefref)result<-kanswriteIORefrefresultreturnresult-- NOTE: we do our own explicit black holing here, because GHC's lazy-- blackholing isn't enough.  In an infinite loop, GHC may run the IO-- computation a few times before it notices the loop, which is wrong.#endif#if defined(__NHC__)-- Assume a unix platform, where text and binary I/O are identical.openBinaryFile=openFilehSetBinaryMode__=return()typeCMode=Int#endif-- | The function creates a temporary file in ReadWrite mode.-- The created file isn\'t deleted automatically, so you need to delete it manually.---- The file is creates with permissions such that only the current-- user can read\/write it.---- With some exceptions (see below), the file will be created securely-- in the sense that an attacker should not be able to cause-- openTempFile to overwrite another file on the filesystem using your-- credentials, by putting symbolic links (on Unix) in the place where-- the temporary file is to be created.  On Unix the @O_CREAT@ and-- @O_EXCL@ flags are used to prevent this attack, but note that-- @O_EXCL@ is sometimes not supported on NFS filesystems, so if you-- rely on this behaviour it is best to use local filesystems only.--openTempFile::FilePath-- ^ Directory in which to create the file->String-- ^ File name template. If the template is \"foo.ext\" then-- the created file will be \"fooXXX.ext\" where XXX is some-- random number.->IO(FilePath,Handle)openTempFiletmp_dirtemplate=openTempFile'"openTempFile"tmp_dirtemplateFalse0o600-- | Like 'openTempFile', but opens the file in binary mode. See 'openBinaryFile' for more comments.openBinaryTempFile::FilePath->String->IO(FilePath,Handle)openBinaryTempFiletmp_dirtemplate=openTempFile'"openBinaryTempFile"tmp_dirtemplateTrue0o600-- | Like 'openTempFile', but uses the default file permissionsopenTempFileWithDefaultPermissions::FilePath->String->IO(FilePath,Handle)openTempFileWithDefaultPermissionstmp_dirtemplate=openTempFile'"openBinaryTempFile"tmp_dirtemplateFalse0o666-- | Like 'openBinaryTempFile', but uses the default file permissionsopenBinaryTempFileWithDefaultPermissions::FilePath->String->IO(FilePath,Handle)openBinaryTempFileWithDefaultPermissionstmp_dirtemplate=openTempFile'"openBinaryTempFile"tmp_dirtemplateTrue0o666openTempFile'::String->FilePath->String->Bool->CMode->IO(FilePath,Handle)openTempFile'loctmp_dirtemplatebinarymode=dopid<-c_getpidfindTempNamepidwhere-- We split off the last extension, so we can use .foo.ext files-- for temporary files (hidden on Unix OSes). Unfortunately we're-- below filepath in the hierarchy here.(prefix,suffix)=casebreak(=='.')$reversetemplateof-- First case: template contains no '.'s. Just re-reverse it.(rev_suffix,"")->(reverserev_suffix,"")-- Second case: template contains at least one '.'. Strip the-- dot from the prefix and prepend it to the suffix (if we don't-- do this, the unique number will get added after the '.' and-- thus be part of the extension, which is wrong.)(rev_suffix,'.':rest)->(reverserest,'.':reverserev_suffix)-- Otherwise, something is wrong, because (break (== '.')) should-- always return a pair with either the empty string or a string-- beginning with '.' as the second component._->error"bug in System.IO.openTempFile"#ifndef __NHC__oflags1=rw_flags.|.o_EXCLbinary_flags|binary=o_BINARY|otherwise=0oflags=oflags1.|.binary_flags#endif#if defined(__NHC__)findTempNamex=doh<-openFilefilepathReadWriteModereturn(filepath,h)#elif defined(__GLASGOW_HASKELL__)findTempNamex=dofd<-withFilePathfilepath$\f->c_openfoflagsmodeiffd<0thendoerrno<-getErrnoiferrno==eEXISTthenfindTempName(x+1)elseioError(errnoToIOErrorlocerrnoNothing(Justtmp_dir))elsedo(fD,fd_type)<-FD.mkFDfdReadWriteModeNothing{-no stat-}False{-is_socket-}True{-is_nonblock-}h<-mkHandleFromFDfDfd_typefilepathReadWriteModeFalse{-set non-block-}(JustlocaleEncoding)return(filepath,h)#elseh<-fdToHandlefd`onException`c_closefdreturn(filepath,h)#endifwherefilename=prefix++showx++suffixfilepath=tmp_dir`combine`filename-- XXX bits copied from System.FilePath, since that's not available herecombineab|nullb=a|nulla=b|lasta==pathSeparator=a++b|otherwise=a++[pathSeparator]++b#if __HUGS__fdToHandlefd=openFd(fromIntegralfd)FalseReadWriteModebinary#endif-- XXX Should use filepath librarypathSeparator::Char#ifdef mingw32_HOST_OSpathSeparator='\\'#elsepathSeparator='/'#endif#ifndef __NHC__-- XXX Copied from GHC.Handlestd_flags,output_flags,rw_flags::CIntstd_flags=o_NONBLOCK.|.o_NOCTTYoutput_flags=std_flags.|.o_CREATrw_flags=output_flags.|.o_RDWR#endif#ifdef __NHC__foreignimportccall"getpid"c_getpid::IOInt#endif-- $locking-- Implementations should enforce as far as possible, at least locally to the-- Haskell process, multiple-reader single-writer locking on files.-- That is, /there may either be many handles on the same file which manage input, or just one handle on the file which manages output/.  If any-- open or semi-closed handle is managing a file for output, no new-- handle can be allocated for that file.  If any open or semi-closed-- handle is managing a file for input, new handles can only be allocated-- if they do not manage output.  Whether two files are the same is-- implementation-dependent, but they should normally be the same if they-- have the same absolute path name and neither has been renamed, for-- example.---- /Warning/: the 'readFile' operation holds a semi-closed handle on-- the file until the entire contents of the file have been consumed.-- It follows that an attempt to write to a file (using 'writeFile', for-- example) that was earlier opened by 'readFile' will usually result in-- failure with 'System.IO.Error.isAlreadyInUseError'.

[8]ページ先頭

©2009-2025 Movatter.jp