-
Notifications
You must be signed in to change notification settings - Fork 653
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
convert the NIOFileSystem example code to a Snippet (#2746)
* convert the NIOFileSystem example code to a Snippet * fix compilation error * add missing license header * exclude snippets from soundness.sh
- Loading branch information
1 parent
e5a216b
commit 38f6b98
Showing
3 changed files
with
99 additions
and
97 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,97 @@ | ||
// snippet.hide | ||
import _NIOFileSystem | ||
import NIOCore | ||
// 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. | ||
} |
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