File: NIOFileSystem.md

package info (click to toggle)
swiftlang 6.1.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,791,532 kB
  • sloc: cpp: 9,901,743; ansic: 2,201,431; asm: 1,091,827; python: 308,252; objc: 82,166; f90: 80,126; lisp: 38,358; pascal: 25,559; sh: 20,429; ml: 5,058; perl: 4,745; makefile: 4,484; awk: 3,535; javascript: 3,018; xml: 918; fortran: 664; cs: 573; ruby: 396
file content (174 lines) | stat: -rw-r--r-- 6,216 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# ``_NIOFileSystem``

A file system library for Swift.

## Overview

This module implements a file system library for Swift, providing ways to interact with and manage
files. It provides a concrete ``FileSystem`` for interacting with the local file system in addition
to a set of protocols for creating other file system implementations.

``_NIOFileSystem`` is cross-platform with the following caveats:
- _Platforms don't have feature parity or system-level API parity._ Where this is the case these
  implementation details are documented. One example is copying files, on Apple platforms files are
  cloned if possible.
- _Features may be disabled on some systems._ One example is extended attributes.
- _Some types have platform specific representations._ These include the following:
  - File paths on Apple platforms and Linux (e.g. `"/Users/hal9000/"`) are different to paths on
    Windows (`"C:\Users\hal9000"`).
  - Information about files is different on different platforms. See ``FileInfo`` for further
    details.

## A Brief Tour

The following sample code demonstrates a number of the APIs offered by this module:

```swift
import _NIOFileSystem

// 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, 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.
}
```

In depth documentation can be found in the following sections.

## Topics

### Interacting with the Local File System

- ``FileSystem``
- ``FileHandle``
- ``ReadFileHandle``
- ``WriteFileHandle``
- ``ReadWriteFileHandle``
- ``DirectoryFileHandle``
- ``withFileSystem(numberOfThreads:_:)``

### File and Directory Information

- ``FileInfo``
- ``FileType``

### Reading Files

- ``FileChunks``
- ``BufferedReader``

### Writing Files

- ``BufferedWriter``

### Listing Directories

- ``DirectoryEntry``
- ``DirectoryEntries``

### Errors

``FileSystemError`` is the only top-level error type thrown by the package (apart from Swift's
`CancellationError`).

- ``FileSystemError``
- ``FileSystemError/SystemCallError``

### Creating a File System

Custom file system's can be created by implementing ``FileSystemProtocol`` which depends on a number
of other protocols. These include the following:

- ``FileSystemProtocol``
- ``FileHandleProtocol``
- ``ReadableFileHandleProtocol``
- ``WritableFileHandleProtocol``
- ``ReadableAndWritableFileHandleProtocol``
- ``DirectoryFileHandleProtocol``