Add ability to open a file for writing (#975)
* Add ability to open a file for writing Motivation: Users can use NonBlockingFileIO for reading files, but if one wants to write a file, there is no way to achieve that, apart from opening file manually. I think having to inits to open files for reading and writing would be convinient. Modifications: Allow to open files for writing. Result: Users can now open files for writing and reading in the same way.
This commit is contained in:
parent
12654afd21
commit
93b8807c5d
|
@ -81,12 +81,57 @@ public final class NIOFileHandle: FileDescriptor {
|
|||
}
|
||||
|
||||
extension NIOFileHandle {
|
||||
/// `Mode` represents file access modes.
|
||||
public struct Mode: OptionSet {
|
||||
public let rawValue: UInt8
|
||||
|
||||
public init(rawValue: UInt8) {
|
||||
self.rawValue = rawValue
|
||||
}
|
||||
|
||||
internal var posixFlags: CInt {
|
||||
switch self {
|
||||
case [.read, .write]:
|
||||
return O_RDWR
|
||||
case .read:
|
||||
return O_RDONLY
|
||||
case .write:
|
||||
return O_WRONLY
|
||||
default:
|
||||
preconditionFailure("Unsupported mode value")
|
||||
}
|
||||
}
|
||||
|
||||
/// Opens file for reading
|
||||
public static let read = Mode(rawValue: 1 << 0)
|
||||
/// Opens file for writing
|
||||
public static let write = Mode(rawValue: 1 << 1)
|
||||
}
|
||||
|
||||
/// `Flags` allows to specify additional flags to `Mode`, such as permission for file creation.
|
||||
public struct Flags {
|
||||
internal var posixMode: mode_t
|
||||
internal var posixFlags: CInt
|
||||
|
||||
public static let `default` = Flags(posixMode: 0, posixFlags: 0)
|
||||
|
||||
/// Allows file creation when opening file for writing. File owner is set to the effective user ID of the process.
|
||||
///
|
||||
/// - parameters:
|
||||
/// - posixMode: `file mode` applied when file is created. Default permissions are: read and write for file owner, read for owners group and others.
|
||||
public static func allowFileCreation(posixMode: mode_t = S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH) -> Flags {
|
||||
return Flags(posixMode: posixMode, posixFlags: O_CREAT)
|
||||
}
|
||||
}
|
||||
|
||||
/// Open a new `NIOFileHandle`.
|
||||
///
|
||||
/// - parameters:
|
||||
/// - path: the path of the file to open. The ownership of the file descriptor is transferred to this `NIOFileHandle` and so it will be closed once `close` is called.
|
||||
public convenience init(path: String) throws {
|
||||
let fd = try Posix.open(file: path, oFlag: O_RDONLY | O_CLOEXEC)
|
||||
/// - path: The path of the file to open. The ownership of the file descriptor is transferred to this `NIOFileHandle` and so it will be closed once `close` is called.
|
||||
/// - mode: Access mode. Default mode is `.read`.
|
||||
/// - flags: Additional POSIX flags.
|
||||
public convenience init(path: String, mode: Mode = .read, flags: Flags = .default) throws {
|
||||
let fd = try Posix.open(file: path, oFlag: mode.posixFlags | O_CLOEXEC | flags.posixFlags, mode: flags.posixMode)
|
||||
self.init(descriptor: fd)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -253,7 +253,7 @@ public struct NonBlockingFileIO {
|
|||
}
|
||||
}
|
||||
|
||||
/// Open the file at `path` on a private thread pool which is separate from any `EventLoop` thread.
|
||||
/// Open the file at `path` for reading on a private thread pool which is separate from any `EventLoop` thread.
|
||||
///
|
||||
/// This function will return (a future) of the `NIOFileHandle` associated with the file opened and a `FileRegion`
|
||||
/// comprising of the whole file. The caller must close the returned `NIOFileHandle` when it's no longer needed.
|
||||
|
@ -261,7 +261,7 @@ public struct NonBlockingFileIO {
|
|||
/// - note: The reason this returns the `NIOFileHandle` and the `FileRegion` is that both the opening of a file as well as the querying of its size are blocking.
|
||||
///
|
||||
/// - parameters:
|
||||
/// - path: The path of the file to be opened.
|
||||
/// - path: The path of the file to be opened for reading.
|
||||
/// - eventLoop: The `EventLoop` on which the returned `EventLoopFuture` will fire.
|
||||
/// - returns: An `EventLoopFuture` containing the `NIOFileHandle` and the `FileRegion` comprising the whole file.
|
||||
public func openFile(path: String, eventLoop: EventLoop) -> EventLoopFuture<(NIOFileHandle, FileRegion)> {
|
||||
|
@ -277,4 +277,21 @@ public struct NonBlockingFileIO {
|
|||
}
|
||||
}
|
||||
|
||||
/// Open the file at `path` with specified access mode and POSIX flags on a private thread pool which is separate from any `EventLoop` thread.
|
||||
///
|
||||
/// This function will return (a future) of the `NIOFileHandle` associated with the file opened.
|
||||
/// The caller must close the returned `NIOFileHandle` when it's no longer needed.
|
||||
///
|
||||
/// - parameters:
|
||||
/// - path: The path of the file to be opened for writing.
|
||||
/// - mode: File access mode.
|
||||
/// - flags: Additional POSIX flags.
|
||||
/// - eventLoop: The `EventLoop` on which the returned `EventLoopFuture` will fire.
|
||||
/// - returns: An `EventLoopFuture` containing the `NIOFileHandle` and the `FileRegion` comprising the whole file.
|
||||
public func openFile(path: String, mode: NIOFileHandle.Mode, flags: NIOFileHandle.Flags = .default, eventLoop: EventLoop) -> EventLoopFuture<NIOFileHandle> {
|
||||
return self.threadPool.runIfActive(eventLoop: eventLoop) {
|
||||
return try NIOFileHandle(path: path, mode: mode, flags: flags)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue