1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.vfs2;
18
19 import java.io.Closeable;
20 import java.net.URI;
21 import java.net.URL;
22 import java.nio.file.Path;
23 import java.nio.file.Paths;
24 import java.util.Comparator;
25 import java.util.List;
26
27 import org.apache.commons.vfs2.operations.FileOperations;
28
29 /**
30 * Represents a file, and is used to access the content and structure of the file.
31 * <p>
32 * Files are arranged in a hierarchy. Each hierarchy forms a <em>file system</em>. A file system represents things like a
33 * local OS file system, a windows share, an HTTP server, or the contents of a Zip file.
34 * </p>
35 * <p>
36 * There are two types of files: <em>Folders</em>, which contain other files, and <em>normal files</em>, which contain data,
37 * or <em>content</em>. A folder may not have any content, and a normal file cannot contain other files.
38 * </p>
39 *
40 * <h2>File Naming</h2>
41 *
42 * <p>
43 * TODO - write this.
44 * </p>
45 *
46 * <h2>Reading and Writing a File</h2>
47 *
48 * <p>
49 * Reading and writing a file, and all other operations on the file's <em>content</em>, is done using the
50 * {@link FileContent} object returned by {@link #getContent}.
51 * </p>
52 *
53 * <h2>Creating and Deleting a File</h2>
54 *
55 * <p>
56 * A file is created using either {@link #createFolder}, {@link #createFile}, or by writing to the file using one of the
57 * {@link FileContent} methods.
58 * </p>
59 * <p>
60 * A file is deleted using {@link #delete}. Recursive deletion can be done using {@link #delete(FileSelector)}.
61 * </p>
62 *
63 * <h2>Finding Files</h2>
64 *
65 * <p>
66 * Other files in the <em>same</em> file system as this file can be found using:
67 * </p>
68 * <ul>
69 * <li>{@link #findFiles} to find a set of matching descendants in the same file system.</li>
70 * <li>{@link #getChildren} and {@link #getChild} to find the children of this file.</li>
71 * <li>{@link #getParent} to find the folder containing this file.</li>
72 * <li>{@link #getFileSystem} to find another file in the same file system.</li>
73 * <li>{@link #resolveFile} to find another file relative to this file.</li>
74 * </ul>
75 * <p>
76 * To find files in another file system, use a {@link FileSystemManager}.
77 * </p>
78 *
79 * <h2>Iterating Files</h2>
80 *
81 * <p>
82 * You can iterate over a FileObject using the Java "foreach" statement, which provides all descendants of a File
83 * Object.
84 * </p>
85 *
86 * <h2>Sorting Files</h2>
87 *
88 * <p>
89 * Files may be sorted using {@link java.util.Arrays#sort(Object[]) Arrays.sort()} and
90 * {@link List#sort(Comparator) List.sort()}.
91 * </p>
92 *
93 * @see FileSystemManager
94 * @see FileContent
95 * @see FileName
96 */
97 public interface FileObject extends Comparable<FileObject>, Iterable<FileObject>, Closeable {
98
99 /**
100 * An empty immutable {@code FileObject} array.
101 *
102 * @since 2.8.0
103 */
104 FileObject[] EMPTY_ARRAY = {};
105
106 /**
107 * Closes the given file object.
108 *
109 * @param fileObject a file object, may be null.
110 * @throws FileSystemException See {@link FileObject#close()}.
111 * @since 2.11.0
112 */
113 static void close(final FileObject fileObject) throws FileSystemException {
114 if (fileObject != null) {
115 fileObject.close();
116 }
117 }
118
119 /**
120 * Queries the file if it is possible to rename it to newfile.
121 *
122 * @param newfile the new file(-name)
123 * @return true it this is the case
124 */
125 boolean canRenameTo(FileObject newfile);
126
127 /**
128 * Closes this file, and its content. This method is a hint to the implementation that it can release any resources
129 * associated with the file.
130 * <p>
131 * The file object can continue to be used after this method is called.
132 * </p>
133 *
134 * @throws FileSystemException On error closing the file.
135 * @see FileContent#close
136 */
137 @Override
138 void close() throws FileSystemException;
139
140 /**
141 * Copies another file, and all its descendants, to this file.
142 * <p>
143 * If this file does not exist, it is created. Its parent folder is also created, if necessary. If this file does
144 * exist, it is deleted first.
145 * </p>
146 * <p>
147 * This method is not transactional. If it fails and throws an exception, this file will potentially only be
148 * partially copied.
149 * </p>
150 *
151 * @param srcFile The source file to copy.
152 * @param selector The selector to use to select which files to copy.
153 * @throws FileSystemException If this file is read-only, or if the source file does not exist, or on error copying
154 * the file.
155 */
156 void copyFrom(FileObject srcFile, FileSelector selector) throws FileSystemException;
157
158 /**
159 * Creates this file, if it does not exist. Also creates any ancestor folders which do not exist. This method does
160 * nothing if the file already exists and is a file.
161 *
162 * @throws FileSystemException If the file already exists with the wrong type, or the parent folder is read-only, or
163 * on error creating this file or one of its ancestors.
164 */
165 void createFile() throws FileSystemException;
166
167 /**
168 * Creates this folder, if it does not exist. Also creates any ancestor folders which do not exist. This method does
169 * nothing if the folder already exists.
170 *
171 * @throws FileSystemException If the folder already exists with the wrong type, or the parent folder is read-only,
172 * or on error creating this folder or one of its ancestors.
173 */
174 void createFolder() throws FileSystemException;
175
176 /**
177 * Deletes this file. Does nothing if this file does not exist of if it is a folder that has children. Does not
178 * delete any descendants of this file, use {@link #delete(FileSelector)} or {@link #deleteAll()} for that.
179 *
180 * @return true if this object has been deleted
181 * @throws FileSystemException If this file is a non-empty folder, or if this file is read-only, or on error
182 * deleteing this file.
183 */
184 boolean delete() throws FileSystemException;
185
186 /**
187 * Deletes all descendants of this file that match a selector. Does nothing if this file does not exist.
188 *
189 * <p>
190 * This method is not transactional. If it fails and throws an exception, this file will potentially only be
191 * partially deleted.
192 * </p>
193 *
194 * @param selector The selector to use to select which files to delete.
195 * @return the number of deleted objects
196 * @throws FileSystemException If this file or one of its descendants is read-only, or on error deleting this file
197 * or one of its descendants.
198 */
199 int delete(FileSelector selector) throws FileSystemException;
200
201 /**
202 * Deletes this file and all children.
203 *
204 * @return the number of deleted files.
205 * @throws FileSystemException if an error occurs.
206 * @see #delete(FileSelector)
207 * @see Selectors#SELECT_ALL
208 */
209 int deleteAll() throws FileSystemException;
210
211 /**
212 * Determines if this file exists.
213 *
214 * @return {@code true} if this file exists, {@code false} if not.
215 * @throws FileSystemException On error determining if this file exists.
216 */
217 boolean exists() throws FileSystemException;
218
219 /**
220 * Finds the set of matching descendants of this file, in depthwise order.
221 *
222 * @param selector The selector to use to select matching files.
223 * @return The matching files. The files are returned in depthwise order (that is, a child appears in the list
224 * before its parent).
225 * @throws FileSystemException if an error occurs.
226 */
227 FileObject[] findFiles(FileSelector selector) throws FileSystemException;
228
229 /**
230 * Finds the set of matching descendants of this file.
231 *
232 * @param selector the selector used to determine if the file should be selected
233 * @param depthwise controls the ordering in the list. e.g. deepest first
234 * @param selected container for selected files. list needs not to be empty.
235 * @throws FileSystemException if an error occurs.
236 */
237 void findFiles(FileSelector selector, boolean depthwise, List<FileObject> selected) throws FileSystemException;
238
239 /**
240 * Gets a child of this file. Note that this method returns {@code null} when the child does not exist. This
241 * differs from {@link #resolveFile(String, NameScope)} which never returns null.
242 *
243 * @param name The name of the child.
244 * @return The child, or null if there is no such child.
245 * @throws FileSystemException If this file does not exist, or is not a folder, or on error determining this file's
246 * children.
247 */
248 FileObject getChild(String name) throws FileSystemException;
249
250 /**
251 * Gets a lists of children of this file.
252 *
253 * @return An array containing the children of this file. The array is unordered. If the file does not have any
254 * children, a zero-length array is returned. This method never returns null.
255 * @throws FileSystemException If this file does not exist, or is not a folder, or on error listing this file's
256 * children.
257 */
258 FileObject[] getChildren() throws FileSystemException;
259
260 /**
261 * Gets this file's content. The {@link FileContent} returned by this method can be used to read and write the
262 * content of the file.
263 *
264 * <p>
265 * This method can be called if the file does not exist, and the returned {@link FileContent} can be used to create
266 * the file by writing its content.
267 * </p>
268 *
269 * @return This file's content.
270 * @throws FileSystemException On error getting this file's content.
271 */
272 FileContent getContent() throws FileSystemException;
273
274 /**
275 * Gets this instance's FileOperations.
276 *
277 * @return FileOperations interface that provides access to the operations API.
278 * @throws FileSystemException if an error occurs.
279 */
280 FileOperations getFileOperations() throws FileSystemException;
281
282 /**
283 * Gets the file system that contains this file.
284 *
285 * @return The file system.
286 */
287 FileSystem getFileSystem();
288
289 /**
290 * Gets the name of this file.
291 *
292 * @return the FileName, not {@code null}.
293 */
294 FileName getName();
295
296 /**
297 * Gets the folder that contains this file.
298 *
299 * @return The folder that contains this file. Returns null if this file is the root of a file system.
300 * @throws FileSystemException On error finding the file's parent.
301 */
302 FileObject getParent() throws FileSystemException;
303
304 /**
305 * Gets a Path representing this file.
306 *
307 * @return the Path for the file.
308 * @since 2.7.0
309 */
310 default Path getPath() {
311 return Paths.get(getURI());
312 }
313
314 /**
315 * Gets the receiver as a URI String for public display, like, without a password.
316 *
317 * @return A URI String without a password, never {@code null}.
318 */
319 String getPublicURIString();
320
321 /**
322 * Gets this file's type.
323 *
324 * @return One of the {@link FileType} constants. Never returns null.
325 * @throws FileSystemException On error determining the file's type.
326 */
327 FileType getType() throws FileSystemException;
328
329 /**
330 * Gets a URI representing this file.
331 *
332 * @return the URI for the file, not {@code null}.
333 * @since 2.7.0
334 */
335 default URI getURI() {
336 return URI.create(URI.create(getName().getURI()).toASCIIString());
337 }
338
339 /**
340 * Gets a URL representing this file.
341 *
342 * @return the URL for the file.
343 * @throws FileSystemException if an error occurs.
344 */
345 URL getURL() throws FileSystemException;
346
347 /**
348 * Tests whether the fileObject is attached.
349 *
350 * @return true if the FileObject is attached.
351 */
352 boolean isAttached();
353
354 /**
355 * Tests whether someone reads/write to this file.
356 *
357 * @return true if the file content is open.
358 */
359 boolean isContentOpen();
360
361 /**
362 * Tests whether this file is executable.
363 *
364 * @return {@code true} if this file is executable, {@code false} if not.
365 * @throws FileSystemException On error determining if this file exists.
366 */
367 boolean isExecutable() throws FileSystemException;
368
369 /**
370 * Tests whether this file is a regular file.
371 *
372 * @return true if this file is a regular file.
373 * @throws FileSystemException if an error occurs.
374 * @see #getType()
375 * @see FileType#FILE
376 * @since 2.1
377 */
378 boolean isFile() throws FileSystemException;
379
380 /**
381 * Tests whether this file is a folder.
382 *
383 * @return true if this file is a folder.
384 * @throws FileSystemException if an error occurs.
385 * @see #getType()
386 * @see FileType#FOLDER
387 * @since 2.1
388 */
389 boolean isFolder() throws FileSystemException;
390
391 /**
392 * Tests whether this file is hidden.
393 *
394 * @return {@code true} if this file is hidden, {@code false} if not.
395 * @throws FileSystemException On error determining if this file exists.
396 */
397 boolean isHidden() throws FileSystemException;
398
399 /**
400 * Tests whether this file can be read.
401 *
402 * @return {@code true} if this file is readable, {@code false} if not.
403 * @throws FileSystemException On error determining if this file exists.
404 */
405 boolean isReadable() throws FileSystemException;
406
407 /**
408 * Tests whether this file is a symbolic link.
409 *
410 * @return {@code true} if this file is a symbolic link, {@code false} if not.
411 * @throws FileSystemException On error determining if this file exists.
412 * @since 2.4
413 */
414 @SuppressWarnings("unused") // FileSystemException actually thrown in implementations.
415 default boolean isSymbolicLink() throws FileSystemException {
416 return false;
417 }
418
419 /**
420 * Tests whether this file can be written to.
421 *
422 * @return {@code true} if this file is writable, {@code false} if not.
423 * @throws FileSystemException On error determining if this file exists.
424 */
425 boolean isWriteable() throws FileSystemException;
426
427 /**
428 * Move this file.
429 *
430 * <p>
431 * If the destFile exists, it is deleted first.
432 * </p>
433 *
434 * @param destFile the New file name.
435 * @throws FileSystemException If this file is read-only, or if the source file does not exist, or on error copying
436 * the file.
437 */
438 void moveTo(FileObject destFile) throws FileSystemException;
439
440 /**
441 * This will prepare the fileObject to get resynchronized with the underlying file system if required.
442 *
443 * @throws FileSystemException if an error occurs.
444 */
445 void refresh() throws FileSystemException;
446
447 /**
448 * Finds a file, relative to this file. Equivalent to calling {@code resolveFile( path, NameScope.FILE_SYSTEM )}.
449 *
450 * @param path The path of the file to locate. Can either be a relative path or an absolute path.
451 * @return The file.
452 * @throws FileSystemException On error parsing the path, or on error finding the file.
453 */
454 FileObject resolveFile(String path) throws FileSystemException;
455
456 /**
457 * Finds a file relative to this file.
458 *
459 * Refer to {@link NameScope} for a description of how names are resolved in the different scopes.
460 *
461 * @param name The name to resolve.
462 * @param scope the NameScope for the file.
463 * @return The file.
464 * @throws FileSystemException On error parsing the path, or on error finding the file.
465 */
466 FileObject resolveFile(String name, NameScope scope) throws FileSystemException;
467
468 /**
469 * Sets the owner's (or everybody's) write permission.
470 *
471 * @param executable True to allow read access, false to disallow.
472 * @param ownerOnly If {@code true}, the permission applies only to the owner; otherwise, it applies to everybody.
473 * @return true if the operation succeeded.
474 * @throws FileSystemException On error determining if this file exists.
475 * @since 2.1
476 */
477 boolean setExecutable(boolean executable, boolean ownerOnly) throws FileSystemException;
478
479 /**
480 * Sets the owner's (or everybody's) read permission.
481 *
482 * @param readable True to allow read access, false to disallow
483 * @param ownerOnly If {@code true}, the permission applies only to the owner; otherwise, it applies to everybody.
484 * @return true if the operation succeeded
485 * @throws FileSystemException On error determining if this file exists.
486 * @since 2.1
487 */
488 boolean setReadable(boolean readable, boolean ownerOnly) throws FileSystemException;
489
490 /**
491 * Sets the owner's (or everybody's) write permission.
492 *
493 * @param writable True to allow read access, false to disallow
494 * @param ownerOnly If {@code true}, the permission applies only to the owner; otherwise, it applies to everybody.
495 * @return true if the operation succeeded
496 * @throws FileSystemException On error determining if this file exists.
497 * @since 2.1
498 */
499 boolean setWritable(boolean writable, boolean ownerOnly) throws FileSystemException;
500 }