Copyright | (C) XT et al. 2017 |
---|---|
License | BSD-style (see the file LICENSE) |
Maintainer | e@xtendo.org |
Stability | stable |
Portability | POSIX |
Safe Haskell | None |
Language | Haskell2010 |
Welcome to RawFilePath
, a small part of the Haskell community's effort to
purge String
for the Greater Good.
With this package, you can interact with the Unix system without the file
path encoding issue or the String
↔ ByteString
conversion overhead.
Rationale
Traditional String
is notorious:
- 24 bytes (three words) required for one character (the List constructor, the actual Char value, and the pointer to the next List constructor). 24x memory consumption.
- Heap fragmentation causing malloc/free overhead
- A lot of pointer chasing for reading, devastating the cache hit rate
- A lot of pointer chasing plus a lot of heap object allocation for manipulation (appending, slicing, etc.)
- Completely unnecessary but mandatory conversions and memory allocation when the data is sent to or received from the outside world
FilePath
is a type synonym of String
. This is a bigger problem than what String
already has, because it's not just a performance issue anymore; it's a correctness issue as there is no encoding information.
A syscall would give you (or expect from you) a series of bytes, but String
is a series of characters. But how do you know the system's encoding? NTFS is UTF-16, and FAT32 uses the OEM character set. On Linux, there is no filesystem-level encoding. Would Haskell somehow magically figure out the system's encoding information and encode/decode accordingly? Well, there is no magic. FilePath
has completely no guarantee of correct behavior at all, especially when there are non-ASCII letters.
With this library, you use RawFilePath
which is a sequence of bytes (instead of characters). You have the full control of decoding from (or encoding to) these bytes. This lets you do the job properly.
Usage
This is the top-level module that re-exports the sub-modules. Therefore, you can
import RawFilePath
to import all functions. For documentation, see:
For process-related functions, see RawFilePath.Process for a brief introduction and an example code.
Synopsis
- doesPathExist :: RawFilePath -> IO Bool
- doesDirectoryExist :: RawFilePath -> IO Bool
- doesFileExist :: RawFilePath -> IO Bool
- getHomeDirectory :: IO (Maybe RawFilePath)
- getTemporaryDirectory :: IO ByteString
- listDirectory :: RawFilePath -> IO [RawFilePath]
- getDirectoryFiles :: RawFilePath -> IO [RawFilePath]
- getDirectoryFilesRecursive :: RawFilePath -> IO [RawFilePath]
- createDirectory :: RawFilePath -> IO ()
- createDirectoryIfMissing :: Bool -> RawFilePath -> IO ()
- removeFile :: RawFilePath -> IO ()
- tryRemoveFile :: RawFilePath -> IO ()
- removeDirectory :: RawFilePath -> IO ()
- removeDirectoryRecursive :: RawFilePath -> IO ()
- class StreamType c
- data UseHandle = UseHandle Handle
- data NoStream = NoStream
- data Inherit = Inherit
- data CreatePipe = CreatePipe
- data Process stdin stdout stderr
- data ProcessConf stdin stdout stderr
- proc :: RawFilePath -> [ByteString] -> ProcessConf Inherit Inherit Inherit
- setStdin :: StreamType newStdin => ProcessConf oldStdin stdout stderr -> newStdin -> ProcessConf newStdin stdout stderr
- setStdout :: StreamType newStdout => ProcessConf stdin oldStdout stderr -> newStdout -> ProcessConf stdin newStdout stderr
- setStderr :: StreamType newStderr => ProcessConf stdin stdout oldStderr -> newStderr -> ProcessConf stdin stdout newStderr
- processStdin :: Process CreatePipe stdout stderr -> Handle
- processStdout :: Process stdin CreatePipe stderr -> Handle
- processStderr :: Process stdin stdout CreatePipe -> Handle
- startProcess :: (StreamType stdin, StreamType stdout, StreamType stderr) => ProcessConf stdin stdout stderr -> IO (Process stdin stdout stderr)
- stopProcess :: Process stdin stdout stderr -> IO ExitCode
- waitForProcess :: Process stdin stdout stderr -> IO ExitCode
- terminateProcess :: Process stdin stdout stderr -> IO ()
- callProcess :: ProcessConf stdin stdout stderr -> IO ExitCode
- readProcessWithExitCode :: ProcessConf stdin stdout stderr -> IO (ExitCode, ByteString, ByteString)
- type RawFilePath = ByteString
Documentation
doesPathExist :: RawFilePath -> IO Bool Source #
Test whether the given path points to an existing filesystem object. If the user lacks necessary permissions to search the parent directories, this function may return false even if the file does actually exist.
doesDirectoryExist :: RawFilePath -> IO Bool Source #
doesFileExist :: RawFilePath -> IO Bool Source #
getHomeDirectory :: IO (Maybe RawFilePath) Source #
Returns the current user's home directory. More specifically, the value
of the HOME
environment variable.
The directory returned is expected to be writable by the current user, but
note that it isn't generally considered good practice to store
application-specific data here; use getXdgDirectory
or
getAppUserDataDirectory
instead.
The operation may fail with:
UnsupportedOperation
The operating system has no notion of home directory.isDoesNotExistError
The home directory for the current user does not exist, or cannot be found.
getTemporaryDirectory :: IO ByteString Source #
Return the current directory for temporary files. It first returns the
value of the TMPDIR
environment variable or "/tmp" if the variable
isn't defined.
:: RawFilePath | The path of directory to inspect |
-> IO [RawFilePath] | A list of files in the directory |
Get a list of files in the specified directory, excluding "." and ".."
ghci> listDirectory "/" ["home","sys","var","opt","lib64","sbin","usr","srv","dev","lost+found","bin","tmp","run","root","boot","proc","etc","lib"]
:: RawFilePath | The path of directory to inspect |
-> IO [RawFilePath] | A list of files in the directory |
Get a list of files in the specified directory, including "." and ".."
ghci> getDirectoryFiles "/" ["home","sys","var","opt","..","lib64","sbin","usr","srv","dev","lost+found","mnt","bin","tmp","run","root","boot",".","proc","etc","lib"]
getDirectoryFilesRecursive Source #
:: RawFilePath | The path of directory to inspect |
-> IO [RawFilePath] | A list of relative paths |
Recursively get all files in all subdirectories of the specified directory.
*System.RawFilePath> getDirectoryFilesRecursive "src" ["src/System/RawFilePath.hs"]
createDirectory :: RawFilePath -> IO () Source #
Create a new directory.
ghci> createDirectory "/tmp/mydir" ghci> getDirectoryFiles "/tmp/mydir" [".",".."] ghci> createDirectory "/tmp/mydir/anotherdir" ghci> getDirectoryFiles "/tmp/mydir" [".","..","anotherdir"]
createDirectoryIfMissing Source #
:: Bool | Create parent directories or not |
-> RawFilePath | The path of the directory to create |
-> IO () |
Create a new directory if it does not already exist. If the first
argument is True
the function will also create all parent directories
when they are missing.
removeFile :: RawFilePath -> IO () Source #
Remove a file. This function internally calls unlink
. If the file does
not exist, an exception is thrown.
tryRemoveFile :: RawFilePath -> IO () Source #
A function that "tries" to remove a file. If the file does not exist, nothing happens.
removeDirectory :: RawFilePath -> IO () Source #
Remove a directory. The target directory needs to be empty; Otherwise an exception will be thrown.
removeDirectoryRecursive :: RawFilePath -> IO () Source #
Remove an existing directory dir together with its contents and subdirectories. Within this directory, symbolic links are removed without affecting their targets.
class StreamType c Source #
The class of types that determine the standard stream of a sub-process. You can decide how to initialize the standard streams (stdin, stdout, and stderr) of a sub-process with the instances of this class.
Instances
StreamType UseHandle Source # | |
Defined in RawFilePath.Process.Common | |
StreamType NoStream Source # | |
Defined in RawFilePath.Process.Common | |
StreamType Inherit Source # | |
Defined in RawFilePath.Process.Common | |
StreamType CreatePipe Source # | |
Defined in RawFilePath.Process.Common mbFd :: FD -> CreatePipe -> IO FD willCreateHandle :: CreatePipe -> Bool |
Use the supplied Handle
.
Instances
Show UseHandle Source # | |
StreamType UseHandle Source # | |
Defined in RawFilePath.Process.Common |
No stream handle will be passed. Use when you don't want to communicate with a stream. For example, to run something silently.
Instances
Inherit the parent (current) process handle. The child will share the stream. For example, if the child writes anything to stdout, it will all go to the parent's stdout.
data CreatePipe Source #
Create a new pipe for the stream. You get a new Handle
.
Instances
Show CreatePipe Source # | |
Defined in RawFilePath.Process.Common showsPrec :: Int -> CreatePipe -> ShowS # show :: CreatePipe -> String # showList :: [CreatePipe] -> ShowS # | |
StreamType CreatePipe Source # | |
Defined in RawFilePath.Process.Common mbFd :: FD -> CreatePipe -> IO FD willCreateHandle :: CreatePipe -> Bool |
data Process stdin stdout stderr Source #
The process type. The three type variables denote how its standard streams were initialized.
data ProcessConf stdin stdout stderr Source #
The process configuration that is needed for creating new processes. Use
proc
to make one.
:: RawFilePath | Command to run |
-> [ByteString] | Arguments to the command |
-> ProcessConf Inherit Inherit Inherit |
Create a process configuration with the default settings.
setStdin :: StreamType newStdin => ProcessConf oldStdin stdout stderr -> newStdin -> ProcessConf newStdin stdout stderr infixl 4 Source #
Control how the standard input of the process will be initialized.
setStdout :: StreamType newStdout => ProcessConf stdin oldStdout stderr -> newStdout -> ProcessConf stdin newStdout stderr infixl 4 Source #
Control how the standard output of the process will be initialized.
setStderr :: StreamType newStderr => ProcessConf stdin stdout oldStderr -> newStderr -> ProcessConf stdin stdout newStderr infixl 4 Source #
Control how the standard error of the process will be initialized.
processStdin :: Process CreatePipe stdout stderr -> Handle Source #
Take a process and return its standard input handle.
processStdout :: Process stdin CreatePipe stderr -> Handle Source #
Take a process and return its standard output handle.
processStderr :: Process stdin stdout CreatePipe -> Handle Source #
Take a process and return its standard error handle.
startProcess :: (StreamType stdin, StreamType stdout, StreamType stderr) => ProcessConf stdin stdout stderr -> IO (Process stdin stdout stderr) Source #
Start a new sub-process with the given configuration.
stopProcess :: Process stdin stdout stderr -> IO ExitCode Source #
Stop a sub-process. For now it simply calls terminateProcess
and then
waitForProcess
.
waitForProcess :: Process stdin stdout stderr -> IO ExitCode Source #
Wait (block) for a sub-process to exit and obtain its exit code.
terminateProcess :: Process stdin stdout stderr -> IO () Source #
Terminate a sub-process by sending SIGTERM to it.
callProcess :: ProcessConf stdin stdout stderr -> IO ExitCode Source #
Create a new process with the given configuration, and wait for it to finish.
readProcessWithExitCode :: ProcessConf stdin stdout stderr -> IO (ExitCode, ByteString, ByteString) Source #
Fork an external process, read its standard output and standard error strictly, blocking until the process terminates, and return them with the process exit code.
type RawFilePath = ByteString #
A literal POSIX file path