Copyright | (c) Dong Han 2017-2020 |
---|---|
License | BSD |
Maintainer | winterland1989@gmail.com |
Stability | experimental |
Portability | non-portable |
Safe Haskell | None |
Language | Haskell2010 |
This module provides filesystem API exactly same with Base
,
operations(except seek
) are implemented using libuv's threadpool to achieve
non-block behavior (non-block here meaning won't block other haskell threads),
which would be prefered when the operations' estimated time is long(>1ms) or
running with a non-threaded haskell runtime, such as accessing network filesystem
or scan a very large directory. Otherwise you may block RTS's capability thus
all the other haskell threads live on it.
The threadpool version operations have overheads similar to safe FFI, but provide same adventages:
- The libuv's threadpool have a limit on concurrent threads number (4 by default), which can reduce disk contention.
- The threadpool version works with non-threaded runtime, which doesn't have safe FFI available.
- The threadpool version won't relinquish current HEC (Haskell Execution Context) a.k.a. capability.
Most of the time you don't need this module though, since modern hardware(SSD) are sufficiently fast.
Synopsis
- data File
- initFile :: CBytes -> FileFlag -> FileMode -> Resource File
- readFileP :: HasCallStack => File -> Ptr Word8 -> Int -> Int64 -> IO Int
- writeFileP :: HasCallStack => File -> Ptr Word8 -> Int -> Int64 -> IO ()
- getFileFD :: File -> IO FD
- seek :: HasCallStack => File -> Int64 -> Whence -> IO Int64
- readFile :: HasCallStack => CBytes -> IO Bytes
- readTextFile :: HasCallStack => CBytes -> IO Text
- writeFile :: HasCallStack => CBytes -> Bytes -> IO ()
- writeTextFile :: HasCallStack => CBytes -> Text -> IO ()
- readJSONFile :: (HasCallStack, JSON a) => CBytes -> IO a
- writeJSONFile :: (HasCallStack, JSON a) => CBytes -> a -> IO ()
- data FilePtr
- newFilePtr :: File -> Int64 -> IO FilePtr
- getFilePtrOffset :: FilePtr -> IO Int64
- setFilePtrOffset :: FilePtr -> Int64 -> IO ()
- mkdir :: HasCallStack => CBytes -> FileMode -> IO ()
- mkdirp :: HasCallStack => CBytes -> FileMode -> IO ()
- unlink :: HasCallStack => CBytes -> IO ()
- mkdtemp :: HasCallStack => CBytes -> IO CBytes
- mkstemp :: HasCallStack => CBytes -> IO CBytes
- initTempFile :: CBytes -> Resource File
- initTempDir :: CBytes -> Resource CBytes
- rmdir :: HasCallStack => CBytes -> IO ()
- rmrf :: HasCallStack => CBytes -> IO ()
- data DirEntType
- scandir :: HasCallStack => CBytes -> IO [(CBytes, DirEntType)]
- scandirRecursively :: HasCallStack => CBytes -> (CBytes -> DirEntType -> IO Bool) -> IO [CBytes]
- data FStat = FStat {}
- data UVTimeSpec = UVTimeSpec {
- uvtSecond :: !CLong
- uvtNanoSecond :: !CLong
- doesPathExist :: CBytes -> IO Bool
- doesFileExist :: CBytes -> IO Bool
- doesDirExist :: CBytes -> IO Bool
- isLink :: HasCallStack => CBytes -> IO Bool
- isDir :: HasCallStack => CBytes -> IO Bool
- isFile :: HasCallStack => CBytes -> IO Bool
- isLinkSt :: FStat -> Bool
- isDirSt :: FStat -> Bool
- isFileSt :: FStat -> Bool
- stat :: HasCallStack => CBytes -> IO FStat
- lstat :: HasCallStack => CBytes -> IO FStat
- fstat :: HasCallStack => File -> IO FStat
- stat' :: HasCallStack => CBytes -> IO (Maybe FStat)
- lstat' :: HasCallStack => CBytes -> IO (Maybe FStat)
- rename :: HasCallStack => CBytes -> CBytes -> IO ()
- fsync :: HasCallStack => File -> IO ()
- fdatasync :: HasCallStack => File -> IO ()
- ftruncate :: HasCallStack => File -> Int64 -> IO ()
- copyfile :: HasCallStack => CBytes -> CBytes -> CopyFileFlag -> IO ()
- data AccessResult
- access :: HasCallStack => CBytes -> AccessMode -> IO AccessResult
- chmod :: HasCallStack => CBytes -> FileMode -> IO ()
- fchmod :: HasCallStack => File -> FileMode -> IO ()
- utime :: HasCallStack => CBytes -> Double -> Double -> IO ()
- futime :: HasCallStack => File -> Double -> Double -> IO ()
- lutime :: HasCallStack => CBytes -> Double -> Double -> IO ()
- link :: HasCallStack => CBytes -> CBytes -> IO ()
- symlink :: HasCallStack => CBytes -> CBytes -> SymlinkFlag -> IO ()
- readlink :: HasCallStack => CBytes -> IO CBytes
- realpath :: HasCallStack => CBytes -> IO CBytes
- chown :: HasCallStack => CBytes -> UID -> GID -> IO ()
- fchown :: HasCallStack => FD -> UID -> GID -> IO ()
- lchown :: HasCallStack => CBytes -> UID -> GID -> IO ()
- type AccessMode = CInt
- pattern F_OK :: AccessMode
- pattern R_OK :: AccessMode
- pattern W_OK :: AccessMode
- pattern X_OK :: AccessMode
- type FileMode = CInt
- pattern DEFAULT_FILE_MODE :: FileMode
- pattern DEFAULT_DIR_MODE :: FileMode
- pattern S_IRWXU :: FileMode
- pattern S_IRUSR :: FileMode
- pattern S_IWUSR :: FileMode
- pattern S_IXUSR :: FileMode
- pattern S_IRWXG :: FileMode
- pattern S_IRGRP :: FileMode
- pattern S_IWGRP :: FileMode
- pattern S_IXGRP :: FileMode
- pattern S_IRWXO :: FileMode
- pattern S_IROTH :: FileMode
- pattern S_IFMT :: FileMode
- pattern S_IFLNK :: FileMode
- pattern S_IFDIR :: FileMode
- pattern S_IFREG :: FileMode
- type FileFlag = CInt
- pattern O_APPEND :: FileFlag
- pattern O_CREAT :: FileFlag
- pattern O_DIRECT :: FileFlag
- pattern O_DSYNC :: FileFlag
- pattern O_EXCL :: FileFlag
- pattern O_EXLOCK :: FileFlag
- pattern O_NOATIME :: FileFlag
- pattern O_NOFOLLOW :: FileFlag
- pattern O_RDONLY :: FileFlag
- pattern O_RDWR :: FileFlag
- pattern O_SYMLINK :: FileFlag
- pattern O_SYNC :: FileFlag
- pattern O_TRUNC :: FileFlag
- pattern O_WRONLY :: FileFlag
- pattern O_RANDOM :: FileFlag
- pattern O_SHORT_LIVED :: FileFlag
- pattern O_SEQUENTIAL :: FileFlag
- pattern O_TEMPORARY :: FileFlag
- type CopyFileFlag = CInt
- pattern COPYFILE_DEFAULT :: CopyFileFlag
- pattern COPYFILE_EXCL :: CopyFileFlag
- pattern COPYFILE_FICLONE :: CopyFileFlag
- pattern COPYFILE_FICLONE_FORCE :: CopyFileFlag
- type SymlinkFlag = CInt
- pattern SYMLINK_DEFAULT :: SymlinkFlag
- pattern SYMLINK_DIR :: SymlinkFlag
- pattern SYMLINK_JUNCTION :: SymlinkFlag
Regular file devices
File
and its operations are NOT thread safe, use MVar
File
in multiple threads.
Note this is a differet data type from Z.IO.FileSystem 's one, the Input
and Output
instance use thread pool version functions.
libuv implements read and write method with both implict and explict offset capable.
Implict offset interface is provided by Input
/ Output
instances.
Explict offset interface is provided by readFileP
/ writeFileP
.
:: CBytes | |
-> FileFlag | |
-> FileMode | Sets the file mode (permission and sticky bits),
but only if the file was created, see |
-> Resource File |
init a file Resource
, which open a file when used.
Resource closing will wait for the referencing counter goes down to zero (no reading or writing is in process), which can be a problem if you are using multiple readers or writers in multiple threads. In that case you have to stop all reading or writing thread if you don't want to block the resource thread.
:: HasCallStack | |
=> File | |
-> Ptr Word8 | buffer |
-> Int | buffer size |
-> Int64 | file offset, pass -1 to use default(system) offset |
-> IO Int | read length |
Read file with given offset
Read length may be smaller than buffer size.
:: HasCallStack | |
=> File | |
-> Ptr Word8 | buffer |
-> Int | buffer size |
-> Int64 | file offset, pass -1 to use default(system) offset |
-> IO () |
Write buffer to file
This function will loop until all bytes are written.
Note on linux files opened with O_APPEND
behave differently since this function use pwrite
:
POSIX requires that opening a file with the O_APPEND flag should have no effect on the location at which pwrite() writes data. However, on Linux, if a file is opened with O_APPEND, pwrite() appends data to the end of the file, regardless of the value of offset.
seek :: HasCallStack => File -> Int64 -> Whence -> IO Int64 Source #
Set file's system offset.
Equivalent to lseek64(3).
readTextFile :: HasCallStack => CBytes -> IO Text Source #
Quickly open a file and read its content as UTF8 text.
writeFile :: HasCallStack => CBytes -> Bytes -> IO () Source #
Quickly open a file and write some content.
writeTextFile :: HasCallStack => CBytes -> Text -> IO () Source #
Quickly open a file and write some content as UTF8 text.
readJSONFile :: (HasCallStack, JSON a) => CBytes -> IO a Source #
Quickly open a file and read its content as a JSON value.
Throw OtherError
with name EPARSE
if JSON value is not parsed.
writeJSONFile :: (HasCallStack, JSON a) => CBytes -> a -> IO () Source #
Quickly open a file and write a JSON Value.
File offset bundle
Create a file offset bundle from an File
.
Filesystem operations
mkdir :: HasCallStack => CBytes -> FileMode -> IO () Source #
Equivalent to mkdir(2).
Note mode is currently not implemented on Windows. On unix you should set execute bit if you want the directory is accessable, e.g. 0o777.
mkdirp :: HasCallStack => CBytes -> FileMode -> IO () Source #
Recursive directory creation function. Like mkdir
, but makes all
intermediate-level directories needed to contain the leaf directory.
Equivalent to mkdir -p
,
Note mode is currently not implemented on Windows. On unix you should set
execute bit if you want the directory is accessable(so that child folder
can be created), e.g. DEFAULT_DIR_MODE
.
mkdtemp :: HasCallStack => CBytes -> IO CBytes Source #
Equivalent to http://linux.die.net/man/3/mkdtemp
Creates a temporary directory in the most secure manner possible. There are no race conditions in the directory’s creation. The directory is readable, writable, and searchable only by the creating user ID. The user of mkdtemp() is responsible for deleting the temporary directory and its contents when done with it.
Note: the argument is the prefix of the temporary directory, so no need to add XXXXXX ending.
mkstemp :: HasCallStack => CBytes -> IO CBytes Source #
Equivalent to https://man7.org/linux/man-pages/man3/mkstemp.3.html
initTempFile :: CBytes -> Resource File Source #
Make a temporary file under system getTempDir
and automatically clean after used.
>>>
withResource (initTempFile "foo") $ printStd
File 13
initTempDir :: CBytes -> Resource CBytes Source #
Make a temporary directory under system getTempDir
and automatically clean after used.
>>>
withResource (initTempDir "foo") $ printStd
"/tmp/fooxfWR0L"
rmdir :: HasCallStack => CBytes -> IO () Source #
Equivalent to rmdir(2).
Note this function may inherent OS limitations such as argument must be an empty folder.
rmrf :: HasCallStack => CBytes -> IO () Source #
Removes a file or directory at path together with its contents and subdirectories. Symbolic links are removed without affecting their targets. If the path does not exist, nothing happens.
data DirEntType Source #
Instances
scandir :: HasCallStack => CBytes -> IO [(CBytes, DirEntType)] Source #
Equivalent to scandir(3).
Note Unlike scandir(3), this function does not return the “.” and “..” entries.
Note On Linux, getting the type of an entry is only supported by some file systems (btrfs, ext2, ext3 and ext4 at the time of this writing), check the getdents(2) man page.
scandirRecursively :: HasCallStack => CBytes -> (CBytes -> DirEntType -> IO Bool) -> IO [CBytes] Source #
Find all files and directories within a given directory with a predicator.
import Z.IO.FileSystem.FilePath (splitExtension) -- find all haskell source file within current dir scandirRecursively "." (\ p _ -> (== ".hs") . snd <$> splitExtension p)
File stats
FStat | |
|
Instances
data UVTimeSpec Source #
UVTimeSpec | |
|
Instances
isDir :: HasCallStack => CBytes -> IO Bool Source #
If given path is a directory or a symbolic link to a directory?
isFile :: HasCallStack => CBytes -> IO Bool Source #
If given path is a file or a symbolic link to a file?
isLinkSt :: FStat -> Bool Source #
Shortcut to \ st -> stMode st .&. S_IFMT == S_IFLNK
Note you should use lstat
to get the link's stat.
stat' :: HasCallStack => CBytes -> IO (Maybe FStat) Source #
Equivalent to stat(2)
Return Nothing
instead of throwing NoSuchThing
if the file doesn't exist.
lstat' :: HasCallStack => CBytes -> IO (Maybe FStat) Source #
Equivalent to lstat(2)
Return Nothing
instead of throwing NoSuchThing
if the link doesn't exist.
rename :: HasCallStack => CBytes -> CBytes -> IO () Source #
Equivalent to rename(2).
Note On Windows if this function fails with UV_EBUSY, UV_EPERM or UV_EACCES, it will retry to rename the file up to four times with 250ms wait between attempts before giving up. If both path and new_path are existing directories this function will work only if target directory is empty.
fdatasync :: HasCallStack => File -> IO () Source #
Equivalent to fdatasync(2).
ftruncate :: HasCallStack => File -> Int64 -> IO () Source #
Equivalent to ftruncate(2).
copyfile :: HasCallStack => CBytes -> CBytes -> CopyFileFlag -> IO () Source #
Copies a file from path to new_path.
Warning: If the destination path is created, but an error occurs while copying the data, then the destination path is removed. There is a brief window of time between closing and removing the file where another process could access the file.
data AccessResult Source #
Instances
access :: HasCallStack => CBytes -> AccessMode -> IO AccessResult Source #
Equivalent to access(2) on Unix. Windows uses GetFileAttributesW().
:: HasCallStack | |
=> CBytes | |
-> Double | atime, i.e. access time |
-> Double | mtime, i.e. modify time |
-> IO () |
:: HasCallStack | |
=> CBytes | |
-> Double | atime, i.e. access time |
-> Double | mtime, i.e. modify time |
-> IO () |
symlink :: HasCallStack => CBytes -> CBytes -> SymlinkFlag -> IO () Source #
Equivalent to symlink(2).
| Note On Windows the flags parameter can be specified to control how the symlink will be created.
SYMLINK_DIR
: indicates that path points to a directory.SYMLINK_JUNCTION
: request that the symlink is created using junction points.
On other platforms these flags are ignored.
readlink :: HasCallStack => CBytes -> IO CBytes Source #
Equivalent to readlink(2).
realpath :: HasCallStack => CBytes -> IO CBytes Source #
Equivalent to realpath(3) on Unix. Windows uses GetFinalPathNameByHandle.
Warning This function has certain platform-specific caveats that were discovered when used in Node.
- macOS and other BSDs: this function will fail with UV_ELOOP if more than 32 symlinks are found while resolving the given path. This limit is hardcoded and cannot be sidestepped.
Windows: while this function works in the common case, there are a number of corner cases where it doesn’t:
- Paths in ramdisk volumes created by tools which sidestep the Volume Manager (such as ImDisk) cannot be resolved.
- Inconsistent casing when using drive letters.
- Resolved path bypasses subst’d drives.
While this function can still be used, it’s not recommended if scenarios such as the above need to be supported. The background story and some more details on these issues can be checked here.
Note This function is not implemented on Windows XP and Windows Server 2003. On these systems, UV_ENOSYS is returned.
opening constant
AccessMode
type AccessMode = CInt Source #
pattern F_OK :: AccessMode Source #
pattern R_OK :: AccessMode Source #
pattern W_OK :: AccessMode Source #
pattern X_OK :: AccessMode Source #
FileMode
pattern DEFAULT_FILE_MODE :: FileMode Source #
Default mode for file open, 0x666(readable and writable).
pattern DEFAULT_DIR_MODE :: FileMode Source #
Default mode for open, 0x755.
file type constant
FileFlag
pattern O_APPEND :: FileFlag Source #
The file is opened in append mode. Before each write, the file offset is positioned at the end of the file.
pattern O_DIRECT :: FileFlag Source #
File IO is done directly to and from user-space buffers, which must be aligned. Buffer size and address should be a multiple of the physical sector size of the block device, (DO NOT USE WITH Z-IO's BufferedIO
)
pattern O_DSYNC :: FileFlag Source #
The file is opened for synchronous IO. Write operations will complete once all data and a minimum of metadata are flushed to disk.
Note O_DSYNC
is supported on Windows via FILE_FLAG_WRITE_THROUGH
.
pattern O_EXCL :: FileFlag Source #
If the O_CREAT
flag is set and the file already exists, fail the open.
Note In general, the behavior of O_EXCL
is undefined if it is used without O_CREAT
. There is one exception: on
Linux 2.6 and later, O_EXCL
can be used without O_CREAT
if pathname refers to a block device. If the block
device is in use by the system (e.g., mounted), the open will fail with the error EBUSY
.
pattern O_EXLOCK :: FileFlag Source #
Atomically obtain an exclusive lock.
Note UV_FS_O_EXLOCK is only supported on macOS and Windows. (libuv: Changed in version 1.17.0: support is added for Windows.)
pattern O_NOATIME :: FileFlag Source #
Do not update the file access time when the file is read.
Note O_NOATIME
is not supported on Windows.
pattern O_NOFOLLOW :: FileFlag Source #
If the path is a symbolic link, fail the open.
Note O_NOFOLLOW
is not supported on Windows.
pattern O_SYMLINK :: FileFlag Source #
Open the symbolic link itself rather than the resource it points to.
pattern O_SYNC :: FileFlag Source #
The file is opened for synchronous IO. Write operations will complete once all data and all metadata are flushed to disk.
Note O_SYNC
is supported on Windows via FILE_FLAG_WRITE_THROUGH
.
pattern O_TRUNC :: FileFlag Source #
If the file exists and is a regular file, and the file is opened successfully for write access, its length shall be truncated to zero.
pattern O_RANDOM :: FileFlag Source #
Access is intended to be random. The system can use this as a hint to optimize file caching.
Note O_RANDOM
is only supported on Windows via FILE_FLAG_RANDOM_ACCESS
.
pattern O_SHORT_LIVED :: FileFlag Source #
The file is temporary and should not be flushed to disk if possible.
Note O_SHORT_LIVED
is only supported on Windows via FILE_ATTRIBUTE_TEMPORARY
.
pattern O_SEQUENTIAL :: FileFlag Source #
Access is intended to be sequential from beginning to end. The system can use this as a hint to optimize file caching.
Note O_SEQUENTIAL
is only supported on Windows via FILE_FLAG_SEQUENTIAL_SCAN
.
pattern O_TEMPORARY :: FileFlag Source #
The file is temporary and should not be flushed to disk if possible.
Note O_TEMPORARY
is only supported on Windows via FILE_ATTRIBUTE_TEMPORARY
.
CopyFileFlag
type CopyFileFlag = CInt Source #
Flags control copying.
COPYFILE_EXCL
: If present, uv_fs_copyfile() will fail with UV_EEXIST if the destination path already exists. The default behavior is to overwrite the destination if it exists.COPYFILE_FICLONE
: If present, uv_fs_copyfile() will attempt to create a copy-on-write reflink. If the underlying platform does not support copy-on-write, then a fallback copy mechanism is used.COPYFILE_FICLONE_FORCE
: If present, uv_fs_copyfile() will attempt to create a copy-on-write reflink. If the underlying platform does not support copy-on-write, or an error occurs while attempting to use copy-on-write, then an error is returned.
pattern COPYFILE_DEFAULT :: CopyFileFlag Source #
pattern COPYFILE_EXCL :: CopyFileFlag Source #
pattern COPYFILE_FICLONE :: CopyFileFlag Source #
pattern COPYFILE_FICLONE_FORCE :: CopyFileFlag Source #
SymlinkFlag
type SymlinkFlag = CInt Source #
On Windows the flags parameter can be specified to control how the symlink will be created:
SYMLINK_DIR
: indicates that path points to a directory.SYMLINK_JUNCTION
: request that the symlink is created using junction points.
pattern SYMLINK_DEFAULT :: SymlinkFlag Source #
pattern SYMLINK_DIR :: SymlinkFlag Source #
pattern SYMLINK_JUNCTION :: SymlinkFlag Source #