0
# Features and Monitoring
1
2
Jimfs provides optional features for enhanced file system functionality and configurable directory monitoring through watch services.
3
4
## Core Imports
5
6
```java
7
import com.google.common.jimfs.Feature;
8
import com.google.common.jimfs.WatchServiceConfiguration;
9
import com.google.common.jimfs.FileTimeSource;
10
import java.util.concurrent.TimeUnit;
11
import java.nio.file.attribute.FileTime;
12
```
13
14
## Optional Features
15
16
The `Feature` enum defines optional capabilities that can be enabled or disabled for a file system.
17
18
```java { .api }
19
public enum Feature {
20
LINKS, SYMBOLIC_LINKS, SECURE_DIRECTORY_STREAM, FILE_CHANNEL
21
}
22
```
23
24
### Hard Links Support
25
26
```java { .api }
27
LINKS
28
```
29
30
Enables support for hard links to regular files.
31
32
**Affected APIs:**
33
- `Files.createLink(Path, Path)`
34
35
**Behavior:**
36
- When enabled: Hard links can be created between regular files
37
- When disabled: `Files.createLink()` throws `UnsupportedOperationException`
38
39
**Usage Example:**
40
```java
41
Configuration config = Configuration.unix()
42
.toBuilder()
43
.setSupportedFeatures(Feature.LINKS)
44
.build();
45
46
FileSystem fs = Jimfs.newFileSystem(config);
47
Path original = fs.getPath("/data.txt");
48
Path hardLink = fs.getPath("/link-to-data.txt");
49
50
Files.write(original, "content".getBytes());
51
Files.createLink(hardLink, original); // Creates hard link
52
```
53
54
### Symbolic Links Support
55
56
```java { .api }
57
SYMBOLIC_LINKS
58
```
59
60
Enables support for symbolic links.
61
62
**Affected APIs:**
63
- `Files.createSymbolicLink(Path, Path, FileAttribute...)`
64
- `Files.readSymbolicLink(Path)`
65
66
**Behavior:**
67
- When enabled: Symbolic links can be created and read
68
- When disabled: These methods throw `UnsupportedOperationException`
69
70
**Usage Example:**
71
```java
72
Configuration config = Configuration.unix()
73
.toBuilder()
74
.setSupportedFeatures(Feature.SYMBOLIC_LINKS)
75
.build();
76
77
FileSystem fs = Jimfs.newFileSystem(config);
78
Path target = fs.getPath("/target.txt");
79
Path symlink = fs.getPath("/link.txt");
80
81
Files.write(target, "content".getBytes());
82
Files.createSymbolicLink(symlink, target);
83
Path resolved = Files.readSymbolicLink(symlink);
84
```
85
86
### Secure Directory Stream Support
87
88
```java { .api }
89
SECURE_DIRECTORY_STREAM
90
```
91
92
Enables `SecureDirectoryStream` support for directory operations.
93
94
**Affected APIs:**
95
- `Files.newDirectoryStream(Path)`
96
- `Files.newDirectoryStream(Path, DirectoryStream.Filter)`
97
- `Files.newDirectoryStream(Path, String)`
98
99
**Behavior:**
100
- When enabled: `DirectoryStream` instances also implement `SecureDirectoryStream`
101
- When disabled: Directory streams are basic implementations without secure operations
102
103
**Usage Example:**
104
```java
105
Configuration config = Configuration.unix()
106
.toBuilder()
107
.setSupportedFeatures(Feature.SECURE_DIRECTORY_STREAM)
108
.build();
109
110
FileSystem fs = Jimfs.newFileSystem(config);
111
Path dir = fs.getPath("/secure-dir");
112
Files.createDirectory(dir);
113
114
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
115
if (stream instanceof SecureDirectoryStream) {
116
SecureDirectoryStream<Path> secureStream = (SecureDirectoryStream<Path>) stream;
117
// Use secure operations relative to the open directory
118
}
119
}
120
```
121
122
### File Channel Support
123
124
```java { .api }
125
FILE_CHANNEL
126
```
127
128
Enables `FileChannel` and `AsynchronousFileChannel` support.
129
130
**Affected APIs:**
131
- `Files.newByteChannel(Path, OpenOption...)`
132
- `Files.newByteChannel(Path, Set, FileAttribute...)`
133
- `FileChannel.open(Path, OpenOption...)`
134
- `FileChannel.open(Path, Set, FileAttribute...)`
135
- `AsynchronousFileChannel.open(Path, OpenOption...)`
136
- `AsynchronousFileChannel.open(Path, Set, ExecutorService, FileAttribute...)`
137
138
**Behavior:**
139
- When enabled: Byte channels are `FileChannel` instances, and `FileChannel.open()` works
140
- When disabled: Byte channels are basic `SeekableByteChannel` instances, `FileChannel.open()` throws `UnsupportedOperationException`
141
142
**Usage Example:**
143
```java
144
Configuration config = Configuration.unix()
145
.toBuilder()
146
.setSupportedFeatures(Feature.FILE_CHANNEL)
147
.build();
148
149
FileSystem fs = Jimfs.newFileSystem(config);
150
Path file = fs.getPath("/data.txt");
151
152
try (FileChannel channel = FileChannel.open(file, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
153
ByteBuffer buffer = ByteBuffer.wrap("Hello World".getBytes());
154
channel.write(buffer);
155
}
156
```
157
158
## Watch Service Configuration
159
160
The `WatchServiceConfiguration` class configures directory monitoring behavior.
161
162
### Polling Configuration
163
164
Create a polling-based watch service configuration.
165
166
```java { .api }
167
public static WatchServiceConfiguration polling(long interval, TimeUnit timeUnit);
168
```
169
170
**Parameters:**
171
- `interval` - Polling interval (must be positive)
172
- `timeUnit` - Time unit for the interval
173
174
**Usage Example:**
175
```java
176
// Poll every 2 seconds
177
WatchServiceConfiguration watchConfig = WatchServiceConfiguration.polling(2, TimeUnit.SECONDS);
178
179
Configuration config = Configuration.unix()
180
.toBuilder()
181
.setWatchServiceConfiguration(watchConfig)
182
.build();
183
184
FileSystem fs = Jimfs.newFileSystem(config);
185
try (WatchService watchService = fs.newWatchService()) {
186
Path dir = fs.getPath("/watched-dir");
187
Files.createDirectory(dir);
188
189
WatchKey key = dir.register(watchService,
190
StandardWatchEventKinds.ENTRY_CREATE,
191
StandardWatchEventKinds.ENTRY_DELETE,
192
StandardWatchEventKinds.ENTRY_MODIFY);
193
194
// Watch service will poll every 2 seconds for changes
195
}
196
```
197
198
### Default Configuration
199
200
The default watch service configuration uses 5-second polling:
201
202
```java
203
// Equivalent to WatchServiceConfiguration.polling(5, TimeUnit.SECONDS)
204
Configuration config = Configuration.unix(); // Uses default watch config
205
```
206
207
## File Time Source
208
209
The `FileTimeSource` interface allows customization of file timestamp generation.
210
211
### Interface Definition
212
213
```java { .api }
214
public interface FileTimeSource {
215
FileTime now();
216
}
217
```
218
219
### Custom Time Source
220
221
Implement custom time sources for testing or specialized behavior.
222
223
**Usage Example:**
224
```java
225
// Custom time source for testing
226
FileTimeSource fixedTimeSource = new FileTimeSource() {
227
private final FileTime fixedTime = FileTime.fromMillis(1609459200000L); // 2021-01-01
228
229
@Override
230
public FileTime now() {
231
return fixedTime;
232
}
233
};
234
235
Configuration config = Configuration.unix()
236
.toBuilder()
237
.setFileTimeSource(fixedTimeSource)
238
.build();
239
240
FileSystem fs = Jimfs.newFileSystem(config);
241
Path file = fs.getPath("/test.txt");
242
Files.write(file, "content".getBytes());
243
244
// File timestamps will use the fixed time
245
BasicFileAttributes attrs = Files.readAttributes(file, BasicFileAttributes.class);
246
System.out.println("Created: " + attrs.creationTime());
247
```
248
249
## Feature Combinations
250
251
### Typical Combinations
252
253
**Full-featured Unix-like:**
254
```java
255
Configuration config = Configuration.unix()
256
.toBuilder()
257
.setSupportedFeatures(
258
Feature.LINKS,
259
Feature.SYMBOLIC_LINKS,
260
Feature.SECURE_DIRECTORY_STREAM,
261
Feature.FILE_CHANNEL
262
)
263
.build();
264
```
265
266
**Basic file system:**
267
```java
268
Configuration config = Configuration.unix()
269
.toBuilder()
270
.setSupportedFeatures() // No optional features
271
.build();
272
```
273
274
**Testing-focused:**
275
```java
276
Configuration config = Configuration.unix()
277
.toBuilder()
278
.setSupportedFeatures(Feature.FILE_CHANNEL) // File channels for testing I/O
279
.setWatchServiceConfiguration(WatchServiceConfiguration.polling(100, TimeUnit.MILLISECONDS)) // Fast polling
280
.build();
281
```
282
283
## Performance Considerations
284
285
### Watch Service Performance
286
- Polling frequency affects CPU usage and responsiveness
287
- More frequent polling = higher CPU usage but faster change detection
288
- Less frequent polling = lower CPU usage but slower change detection
289
290
### Feature Overhead
291
- Each enabled feature adds minimal memory overhead
292
- `FILE_CHANNEL` feature enables more complex I/O operations
293
- `SECURE_DIRECTORY_STREAM` adds additional security checks
294
- Features can be disabled to minimize overhead in resource-constrained environments
295
296
## Thread Safety
297
298
- `WatchServiceConfiguration` objects are immutable and thread-safe
299
- `FileTimeSource` implementations should be thread-safe
300
- Watch services support concurrent access from multiple threads
301
- Feature configuration is immutable once the file system is created