001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.vfs2; 018 019import java.io.Closeable; 020import java.net.URI; 021import java.net.URL; 022import java.nio.file.Path; 023import java.nio.file.Paths; 024import java.util.Comparator; 025import java.util.List; 026 027import org.apache.commons.vfs2.operations.FileOperations; 028 029/** 030 * Represents a file, and is used to access the content and structure of the file. 031 * <p> 032 * Files are arranged in a hierarchy. Each hierarchy forms a <em>file system</em>. A file system represents things like a 033 * local OS file system, a windows share, an HTTP server, or the contents of a Zip file. 034 * </p> 035 * <p> 036 * There are two types of files: <em>Folders</em>, which contain other files, and <em>normal files</em>, which contain data, 037 * or <em>content</em>. A folder may not have any content, and a normal file cannot contain other files. 038 * </p> 039 * 040 * <h2>File Naming</h2> 041 * 042 * <p> 043 * TODO - write this. 044 * </p> 045 * 046 * <h2>Reading and Writing a File</h2> 047 * 048 * <p> 049 * Reading and writing a file, and all other operations on the file's <em>content</em>, is done using the 050 * {@link FileContent} object returned by {@link #getContent}. 051 * </p> 052 * 053 * <h2>Creating and Deleting a File</h2> 054 * 055 * <p> 056 * A file is created using either {@link #createFolder}, {@link #createFile}, or by writing to the file using one of the 057 * {@link FileContent} methods. 058 * </p> 059 * <p> 060 * A file is deleted using {@link #delete}. Recursive deletion can be done using {@link #delete(FileSelector)}. 061 * </p> 062 * 063 * <h2>Finding Files</h2> 064 * 065 * <p> 066 * Other files in the <em>same</em> file system as this file can be found using: 067 * </p> 068 * <ul> 069 * <li>{@link #findFiles} to find a set of matching descendants in the same file system.</li> 070 * <li>{@link #getChildren} and {@link #getChild} to find the children of this file.</li> 071 * <li>{@link #getParent} to find the folder containing this file.</li> 072 * <li>{@link #getFileSystem} to find another file in the same file system.</li> 073 * <li>{@link #resolveFile} to find another file relative to this file.</li> 074 * </ul> 075 * <p> 076 * To find files in another file system, use a {@link FileSystemManager}. 077 * </p> 078 * 079 * <h2>Iterating Files</h2> 080 * 081 * <p> 082 * You can iterate over a FileObject using the Java "foreach" statement, which provides all descendants of a File 083 * Object. 084 * </p> 085 * 086 * <h2>Sorting Files</h2> 087 * 088 * <p> 089 * Files may be sorted using {@link java.util.Arrays#sort(Object[]) Arrays.sort()} and 090 * {@link List#sort(Comparator) List.sort()}. 091 * </p> 092 * 093 * @see FileSystemManager 094 * @see FileContent 095 * @see FileName 096 */ 097public interface FileObject extends Comparable<FileObject>, Iterable<FileObject>, Closeable { 098 099 /** 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}