forked from apple/swift-nio
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge commit 'fc79798d5a150d61361a27ce0c51169b889e23de'
* commit 'fc79798d5a150d61361a27ce0c51169b889e23de': NIOSendableBox: allow off-loop initialisation iff Value is Sendable (apple#2753) Throw an appropriate error from the writer when the channel closed (apple#2744) put snippet code inside @available function (apple#2750) fix link to NIOFileSystem from NIO index page (apple#2747) convert the NIOFileSystem example code to a Snippet (apple#2746) Silence warning about missing include in macOS builds (apple#2741) Correctly mark 304 as not having a response body (apple#2737) Update availability guard (apple#2739) Add API for setting last accessed and last modified file times (apple#2735) Add a fallback path if renameat2 fails (apple#2733) Release file handles back to caller on failure to take ownership (apple#2715) Add a version of 'write' for 'ByteBuffer' (apple#2730) Imrprove rename error (apple#2731) Remove storage indirection for FileSystemError (apple#2726) testSimpleMPTCP should not fail for ENOPROTOOPT (apple#2725) Fix race in TCPThroughputBenchmark (apple#2724)
- Loading branch information
Showing
30 changed files
with
962 additions
and
310 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
// snippet.hide | ||
import _NIOFileSystem | ||
import NIOCore | ||
|
||
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) | ||
func main() async throws | ||
{ | ||
// snippet.show | ||
|
||
// NIOFileSystem provides access to the local file system via the FileSystem | ||
// type which is available as a global shared instance. | ||
let fileSystem = FileSystem.shared | ||
|
||
// Files can be inspected by using 'info': | ||
if let info = try await fileSystem.info(forFileAt: "/Users/hal9000/demise-of-dave.txt") { | ||
print("demise-of-dave.txt has type '\(info.type)'") | ||
} else { | ||
print("demise-of-dave.txt doesn't exist") | ||
} | ||
|
||
// Let's find out what's in that file. | ||
do { | ||
// Reading a whole file requires a limit. If the file is larger than the limit | ||
// then an error is thrown. This avoids accidentally consuming too much memory | ||
// if the file is larger than expected. | ||
let plan = try await ByteBuffer( | ||
contentsOf: "/Users/hal9000/demise-of-dave.txt", | ||
maximumSizeAllowed: .mebibytes(1) | ||
) | ||
print("Plan for Dave's demise:", String(decoding: plan.readableBytesView, as: UTF8.self)) | ||
} catch let error as FileSystemError where error.code == .notFound { | ||
// All errors thrown by the module have type FileSystemError (or | ||
// Swift.CancellationError). It looks like the file doesn't exist. Let's | ||
// create it now. | ||
// | ||
// The code above for reading the file is shorthand for opening the file in | ||
// read-only mode and then reading its contents. The FileSystemProtocol | ||
// has a few different 'withFileHandle' methods for opening a file in different | ||
// modes. Let's open a file for writing, creating it at the same time. | ||
try await fileSystem.withFileHandle( | ||
forWritingAt: "/Users/hal9000/demise-of-dave.txt", | ||
options: .newFile(replaceExisting: false) | ||
) { file in | ||
let plan = ByteBuffer(string: "TODO...") | ||
try await file.write(contentsOf: plan.readableBytesView, toAbsoluteOffset: 0) | ||
} | ||
} | ||
|
||
// Directories can be opened like regular files but they cannot be read from or | ||
// written to. However, their contents can be listed: | ||
let path: FilePath? = try await fileSystem.withDirectoryHandle(atPath: "/Users/hal9000/Music") { directory in | ||
for try await entry in directory.listContents() { | ||
if entry.name.extension == "mp3", entry.name.stem.contains("daisy") { | ||
// Found it! | ||
return entry.path | ||
} | ||
} | ||
// No luck. | ||
return nil | ||
} | ||
|
||
if let path = path { | ||
print("Found file at '\(path)'") | ||
} | ||
|
||
// The file system can also be used to perform the following operations on files | ||
// and directories: | ||
// - copy, | ||
// - remove, | ||
// - rename, and | ||
// - replace. | ||
// | ||
// Here's an example of copying a directory: | ||
try await fileSystem.copyItem(at: "/Users/hal9000/Music", to: "/Volumes/Tardis/Music") | ||
|
||
// Symbolic links can also be created (and read with 'destinationOfSymbolicLink(at:)'). | ||
try await fileSystem.createSymbolicLink(at: "/Users/hal9000/Backup", withDestination: "/Volumes/Tardis") | ||
|
||
// Opening a symbolic link opens its destination so in most cases there's no | ||
// need to read the destination of a symbolic link: | ||
try await fileSystem.withDirectoryHandle(atPath: "/Users/hal9000/Backup") { directory in | ||
// Beyond listing the contents of a directory, the directory handle provides a | ||
// number of other functions, many of which are also available on regular file | ||
// handles. | ||
// | ||
// This includes getting information about a file, such as its permissions, last access time, | ||
// and last modification time: | ||
let info = try await directory.info() | ||
print("The directory has permissions '\(info.permissions)'") | ||
|
||
// Where supported, the extended attributes of a file can also be accessed, read, and modified: | ||
for attribute in try await directory.attributeNames() { | ||
let value = try await directory.valueForAttribute(attribute) | ||
print("Extended attribute '\(attribute)' has value '\(value)'") | ||
} | ||
|
||
// Once this closure returns the file system will close the directory handle freeing | ||
// any resources required to access it such as file descriptors. Handles can also be opened | ||
// with the 'openFile' and 'openDirectory' APIs but that places the onus you to close the | ||
// handle at an appropriate time to avoid leaking resources. | ||
} | ||
// snippet.end | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.