Coverage Summary for Class: Files (com.google.common.io)

Class Method, % Line, %
Files 0% (0/36) 0% (0/112)
Files$1 0% (0/3) 0% (0/5)
Files$2 0% (0/2) 0% (0/6)
Files$FileByteSink 0% (0/4) 0% (0/6)
Files$FileByteSource 0% (0/7) 0% (0/18)
Files$FilePredicate 0% (0/1) 0% (0/3)
Files$FilePredicate$1 0% (0/3) 0% (0/3)
Files$FilePredicate$2 0% (0/3) 0% (0/3)
Total 0% (0/59) 0% (0/156)


1 /* 2  * Copyright (C) 2007 The Guava Authors 3  * 4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5  * in compliance with the License. You may obtain a copy of the License at 6  * 7  * http://www.apache.org/licenses/LICENSE-2.0 8  * 9  * Unless required by applicable law or agreed to in writing, software distributed under the License 10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11  * or implied. See the License for the specific language governing permissions and limitations under 12  * the License. 13  */ 14  15 package com.google.common.io; 16  17 import static com.google.common.base.Preconditions.checkArgument; 18 import static com.google.common.base.Preconditions.checkNotNull; 19 import static com.google.common.io.FileWriteMode.APPEND; 20  21 import com.google.common.annotations.Beta; 22 import com.google.common.annotations.GwtIncompatible; 23 import com.google.common.base.Joiner; 24 import com.google.common.base.Optional; 25 import com.google.common.base.Predicate; 26 import com.google.common.base.Splitter; 27 import com.google.common.collect.ImmutableList; 28 import com.google.common.collect.ImmutableSet; 29 import com.google.common.collect.Lists; 30 import com.google.common.graph.SuccessorsFunction; 31 import com.google.common.graph.Traverser; 32 import com.google.common.hash.HashCode; 33 import com.google.common.hash.HashFunction; 34 import com.google.errorprone.annotations.CanIgnoreReturnValue; 35 import java.io.BufferedReader; 36 import java.io.BufferedWriter; 37 import java.io.File; 38 import java.io.FileInputStream; 39 import java.io.FileNotFoundException; 40 import java.io.FileOutputStream; 41 import java.io.IOException; 42 import java.io.InputStreamReader; 43 import java.io.OutputStream; 44 import java.io.OutputStreamWriter; 45 import java.io.RandomAccessFile; 46 import java.nio.MappedByteBuffer; 47 import java.nio.channels.FileChannel; 48 import java.nio.channels.FileChannel.MapMode; 49 import java.nio.charset.Charset; 50 import java.nio.charset.StandardCharsets; 51 import java.util.ArrayList; 52 import java.util.Arrays; 53 import java.util.Collections; 54 import java.util.List; 55 import javax.annotation.CheckForNull; 56 import org.checkerframework.checker.nullness.qual.Nullable; 57  58 /** 59  * Provides utility methods for working with {@linkplain File files}. 60  * 61  * <p>{@link java.nio.file.Path} users will find similar utilities in {@link MoreFiles} and the 62  * JDK's {@link java.nio.file.Files} class. 63  * 64  * @author Chris Nokleberg 65  * @author Colin Decker 66  * @since 1.0 67  */ 68 @GwtIncompatible 69 @ElementTypesAreNonnullByDefault 70 public final class Files { 71  72  /** Maximum loop count when creating temp directories. */ 73  private static final int TEMP_DIR_ATTEMPTS = 10000; 74  75  private Files() {} 76  77  /** 78  * Returns a buffered reader that reads from a file using the given character set. 79  * 80  * <p><b>{@link java.nio.file.Path} equivalent:</b> {@link 81  * java.nio.file.Files#newBufferedReader(java.nio.file.Path, Charset)}. 82  * 83  * @param file the file to read from 84  * @param charset the charset used to decode the input stream; see {@link StandardCharsets} for 85  * helpful predefined constants 86  * @return the buffered reader 87  */ 88  @Beta 89  public static BufferedReader newReader(File file, Charset charset) throws FileNotFoundException { 90  checkNotNull(file); 91  checkNotNull(charset); 92  return new BufferedReader(new InputStreamReader(new FileInputStream(file), charset)); 93  } 94  95  /** 96  * Returns a buffered writer that writes to a file using the given character set. 97  * 98  * <p><b>{@link java.nio.file.Path} equivalent:</b> {@link 99  * java.nio.file.Files#newBufferedWriter(java.nio.file.Path, Charset, 100  * java.nio.file.OpenOption...)}. 101  * 102  * @param file the file to write to 103  * @param charset the charset used to encode the output stream; see {@link StandardCharsets} for 104  * helpful predefined constants 105  * @return the buffered writer 106  */ 107  @Beta 108  public static BufferedWriter newWriter(File file, Charset charset) throws FileNotFoundException { 109  checkNotNull(file); 110  checkNotNull(charset); 111  return new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), charset)); 112  } 113  114  /** 115  * Returns a new {@link ByteSource} for reading bytes from the given file. 116  * 117  * @since 14.0 118  */ 119  public static ByteSource asByteSource(File file) { 120  return new FileByteSource(file); 121  } 122  123  private static final class FileByteSource extends ByteSource { 124  125  private final File file; 126  127  private FileByteSource(File file) { 128  this.file = checkNotNull(file); 129  } 130  131  @Override 132  public FileInputStream openStream() throws IOException { 133  return new FileInputStream(file); 134  } 135  136  @Override 137  public Optional<Long> sizeIfKnown() { 138  if (file.isFile()) { 139  return Optional.of(file.length()); 140  } else { 141  return Optional.absent(); 142  } 143  } 144  145  @Override 146  public long size() throws IOException { 147  if (!file.isFile()) { 148  throw new FileNotFoundException(file.toString()); 149  } 150  return file.length(); 151  } 152  153  @Override 154  public byte[] read() throws IOException { 155  Closer closer = Closer.create(); 156  try { 157  FileInputStream in = closer.register(openStream()); 158  return ByteStreams.toByteArray(in, in.getChannel().size()); 159  } catch (Throwable e) { 160  throw closer.rethrow(e); 161  } finally { 162  closer.close(); 163  } 164  } 165  166  @Override 167  public String toString() { 168  return "Files.asByteSource(" + file + ")"; 169  } 170  } 171  172  /** 173  * Returns a new {@link ByteSink} for writing bytes to the given file. The given {@code modes} 174  * control how the file is opened for writing. When no mode is provided, the file will be 175  * truncated before writing. When the {@link FileWriteMode#APPEND APPEND} mode is provided, writes 176  * will append to the end of the file without truncating it. 177  * 178  * @since 14.0 179  */ 180  public static ByteSink asByteSink(File file, FileWriteMode... modes) { 181  return new FileByteSink(file, modes); 182  } 183  184  private static final class FileByteSink extends ByteSink { 185  186  private final File file; 187  private final ImmutableSet<FileWriteMode> modes; 188  189  private FileByteSink(File file, FileWriteMode... modes) { 190  this.file = checkNotNull(file); 191  this.modes = ImmutableSet.copyOf(modes); 192  } 193  194  @Override 195  public FileOutputStream openStream() throws IOException { 196  return new FileOutputStream(file, modes.contains(APPEND)); 197  } 198  199  @Override 200  public String toString() { 201  return "Files.asByteSink(" + file + ", " + modes + ")"; 202  } 203  } 204  205  /** 206  * Returns a new {@link CharSource} for reading character data from the given file using the given 207  * character set. 208  * 209  * @since 14.0 210  */ 211  public static CharSource asCharSource(File file, Charset charset) { 212  return asByteSource(file).asCharSource(charset); 213  } 214  215  /** 216  * Returns a new {@link CharSink} for writing character data to the given file using the given 217  * character set. The given {@code modes} control how the file is opened for writing. When no mode 218  * is provided, the file will be truncated before writing. When the {@link FileWriteMode#APPEND 219  * APPEND} mode is provided, writes will append to the end of the file without truncating it. 220  * 221  * @since 14.0 222  */ 223  public static CharSink asCharSink(File file, Charset charset, FileWriteMode... modes) { 224  return asByteSink(file, modes).asCharSink(charset); 225  } 226  227  /** 228  * Reads all bytes from a file into a byte array. 229  * 230  * <p><b>{@link java.nio.file.Path} equivalent:</b> {@link java.nio.file.Files#readAllBytes}. 231  * 232  * @param file the file to read from 233  * @return a byte array containing all the bytes from file 234  * @throws IllegalArgumentException if the file is bigger than the largest possible byte array 235  * (2^31 - 1) 236  * @throws IOException if an I/O error occurs 237  */ 238  @Beta 239  public static byte[] toByteArray(File file) throws IOException { 240  return asByteSource(file).read(); 241  } 242  243  /** 244  * Reads all characters from a file into a {@link String}, using the given character set. 245  * 246  * @param file the file to read from 247  * @param charset the charset used to decode the input stream; see {@link StandardCharsets} for 248  * helpful predefined constants 249  * @return a string containing all the characters from the file 250  * @throws IOException if an I/O error occurs 251  * @deprecated Prefer {@code asCharSource(file, charset).read()}. This method is scheduled to be 252  * removed in October 2019. 253  */ 254  @Beta 255  @Deprecated 256  public static String toString(File file, Charset charset) throws IOException { 257  return asCharSource(file, charset).read(); 258  } 259  260  /** 261  * Overwrites a file with the contents of a byte array. 262  * 263  * <p><b>{@link java.nio.file.Path} equivalent:</b> {@link 264  * java.nio.file.Files#write(java.nio.file.Path, byte[], java.nio.file.OpenOption...)}. 265  * 266  * @param from the bytes to write 267  * @param to the destination file 268  * @throws IOException if an I/O error occurs 269  */ 270  @Beta 271  public static void write(byte[] from, File to) throws IOException { 272  asByteSink(to).write(from); 273  } 274  275  /** 276  * Writes a character sequence (such as a string) to a file using the given character set. 277  * 278  * @param from the character sequence to write 279  * @param to the destination file 280  * @param charset the charset used to encode the output stream; see {@link StandardCharsets} for 281  * helpful predefined constants 282  * @throws IOException if an I/O error occurs 283  * @deprecated Prefer {@code asCharSink(to, charset).write(from)}. This method is scheduled to be 284  * removed in October 2019. 285  */ 286  @Beta 287  @Deprecated 288  public static void write(CharSequence from, File to, Charset charset) throws IOException { 289  asCharSink(to, charset).write(from); 290  } 291  292  /** 293  * Copies all bytes from a file to an output stream. 294  * 295  * <p><b>{@link java.nio.file.Path} equivalent:</b> {@link 296  * java.nio.file.Files#copy(java.nio.file.Path, OutputStream)}. 297  * 298  * @param from the source file 299  * @param to the output stream 300  * @throws IOException if an I/O error occurs 301  */ 302  @Beta 303  public static void copy(File from, OutputStream to) throws IOException { 304  asByteSource(from).copyTo(to); 305  } 306  307  /** 308  * Copies all the bytes from one file to another. 309  * 310  * <p>Copying is not an atomic operation - in the case of an I/O error, power loss, process 311  * termination, or other problems, {@code to} may not be a complete copy of {@code from}. If you 312  * need to guard against those conditions, you should employ other file-level synchronization. 313  * 314  * <p><b>Warning:</b> If {@code to} represents an existing file, that file will be overwritten 315  * with the contents of {@code from}. If {@code to} and {@code from} refer to the <i>same</i> 316  * file, the contents of that file will be deleted. 317  * 318  * <p><b>{@link java.nio.file.Path} equivalent:</b> {@link 319  * java.nio.file.Files#copy(java.nio.file.Path, java.nio.file.Path, java.nio.file.CopyOption...)}. 320  * 321  * @param from the source file 322  * @param to the destination file 323  * @throws IOException if an I/O error occurs 324  * @throws IllegalArgumentException if {@code from.equals(to)} 325  */ 326  @Beta 327  public static void copy(File from, File to) throws IOException { 328  checkArgument(!from.equals(to), "Source %s and destination %s must be different", from, to); 329  asByteSource(from).copyTo(asByteSink(to)); 330  } 331  332  /** 333  * Copies all characters from a file to an appendable object, using the given character set. 334  * 335  * @param from the source file 336  * @param charset the charset used to decode the input stream; see {@link StandardCharsets} for 337  * helpful predefined constants 338  * @param to the appendable object 339  * @throws IOException if an I/O error occurs 340  * @deprecated Prefer {@code asCharSource(from, charset).copyTo(to)}. This method is scheduled to 341  * be removed in October 2019. 342  */ 343  @Beta 344  @Deprecated 345  public 346  static void copy(File from, Charset charset, Appendable to) throws IOException { 347  asCharSource(from, charset).copyTo(to); 348  } 349  350  /** 351  * Appends a character sequence (such as a string) to a file using the given character set. 352  * 353  * @param from the character sequence to append 354  * @param to the destination file 355  * @param charset the charset used to encode the output stream; see {@link StandardCharsets} for 356  * helpful predefined constants 357  * @throws IOException if an I/O error occurs 358  * @deprecated Prefer {@code asCharSink(to, charset, FileWriteMode.APPEND).write(from)}. This 359  * method is scheduled to be removed in October 2019. 360  */ 361  @Beta 362  @Deprecated 363  public 364  static void append(CharSequence from, File to, Charset charset) throws IOException { 365  asCharSink(to, charset, FileWriteMode.APPEND).write(from); 366  } 367  368  /** 369  * Returns true if the given files exist, are not directories, and contain the same bytes. 370  * 371  * @throws IOException if an I/O error occurs 372  */ 373  @Beta 374  public static boolean equal(File file1, File file2) throws IOException { 375  checkNotNull(file1); 376  checkNotNull(file2); 377  if (file1 == file2 || file1.equals(file2)) { 378  return true; 379  } 380  381  /* 382  * Some operating systems may return zero as the length for files denoting system-dependent 383  * entities such as devices or pipes, in which case we must fall back on comparing the bytes 384  * directly. 385  */ 386  long len1 = file1.length(); 387  long len2 = file2.length(); 388  if (len1 != 0 && len2 != 0 && len1 != len2) { 389  return false; 390  } 391  return asByteSource(file1).contentEquals(asByteSource(file2)); 392  } 393  394  /** 395  * Atomically creates a new directory somewhere beneath the system's temporary directory (as 396  * defined by the {@code java.io.tmpdir} system property), and returns its name. 397  * 398  * <p>Use this method instead of {@link File#createTempFile(String, String)} when you wish to 399  * create a directory, not a regular file. A common pitfall is to call {@code createTempFile}, 400  * delete the file and create a directory in its place, but this leads a race condition which can 401  * be exploited to create security vulnerabilities, especially when executable files are to be 402  * written into the directory. 403  * 404  * <p>Depending on the environmment that this code is run in, the system temporary directory (and 405  * thus the directory this method creates) may be more visible that a program would like - files 406  * written to this directory may be read or overwritten by hostile programs running on the same 407  * machine. 408  * 409  * <p>This method assumes that the temporary volume is writable, has free inodes and free blocks, 410  * and that it will not be called thousands of times per second. 411  * 412  * <p><b>{@link java.nio.file.Path} equivalent:</b> {@link 413  * java.nio.file.Files#createTempDirectory}. 414  * 415  * @return the newly-created directory 416  * @throws IllegalStateException if the directory could not be created 417  * @deprecated For Android users, see the <a 418  * href="https://developer.android.com/training/data-storage" target="_blank">Data and File 419  * Storage overview</a> to select an appropriate temporary directory (perhaps {@code 420  * context.getCacheDir()}). For developers on Java 7 or later, use {@link 421  * java.nio.file.Files#createTempDirectory}, transforming it to a {@link File} using {@link 422  * java.nio.file.Path#toFile() toFile()} if needed. 423  */ 424  @Beta 425  @Deprecated 426  public static File createTempDir() { 427  File baseDir = new File(System.getProperty("java.io.tmpdir")); 428  @SuppressWarnings("GoodTime") // reading system time without TimeSource 429  String baseName = System.currentTimeMillis() + "-"; 430  431  for (int counter = 0; counter < TEMP_DIR_ATTEMPTS; counter++) { 432  File tempDir = new File(baseDir, baseName + counter); 433  if (tempDir.mkdir()) { 434  return tempDir; 435  } 436  } 437  throw new IllegalStateException( 438  "Failed to create directory within " 439  + TEMP_DIR_ATTEMPTS 440  + " attempts (tried " 441  + baseName 442  + "0 to " 443  + baseName 444  + (TEMP_DIR_ATTEMPTS - 1) 445  + ')'); 446  } 447  448  /** 449  * Creates an empty file or updates the last updated timestamp on the same as the unix command of 450  * the same name. 451  * 452  * @param file the file to create or update 453  * @throws IOException if an I/O error occurs 454  */ 455  @Beta 456  @SuppressWarnings("GoodTime") // reading system time without TimeSource 457  public static void touch(File file) throws IOException { 458  checkNotNull(file); 459  if (!file.createNewFile() && !file.setLastModified(System.currentTimeMillis())) { 460  throw new IOException("Unable to update modification time of " + file); 461  } 462  } 463  464  /** 465  * Creates any necessary but nonexistent parent directories of the specified file. Note that if 466  * this operation fails it may have succeeded in creating some (but not all) of the necessary 467  * parent directories. 468  * 469  * @throws IOException if an I/O error occurs, or if any necessary but nonexistent parent 470  * directories of the specified file could not be created. 471  * @since 4.0 472  */ 473  @Beta 474  public static void createParentDirs(File file) throws IOException { 475  checkNotNull(file); 476  File parent = file.getCanonicalFile().getParentFile(); 477  if (parent == null) { 478  /* 479  * The given directory is a filesystem root. All zero of its ancestors exist. This doesn't 480  * mean that the root itself exists -- consider x:\ on a Windows machine without such a drive 481  * -- or even that the caller can create it, but this method makes no such guarantees even for 482  * non-root files. 483  */ 484  return; 485  } 486  parent.mkdirs(); 487  if (!parent.isDirectory()) { 488  throw new IOException("Unable to create parent directories of " + file); 489  } 490  } 491  492  /** 493  * Moves a file from one path to another. This method can rename a file and/or move it to a 494  * different directory. In either case {@code to} must be the target path for the file itself; not 495  * just the new name for the file or the path to the new parent directory. 496  * 497  * <p><b>{@link java.nio.file.Path} equivalent:</b> {@link java.nio.file.Files#move}. 498  * 499  * @param from the source file 500  * @param to the destination file 501  * @throws IOException if an I/O error occurs 502  * @throws IllegalArgumentException if {@code from.equals(to)} 503  */ 504  @Beta 505  public static void move(File from, File to) throws IOException { 506  checkNotNull(from); 507  checkNotNull(to); 508  checkArgument(!from.equals(to), "Source %s and destination %s must be different", from, to); 509  510  if (!from.renameTo(to)) { 511  copy(from, to); 512  if (!from.delete()) { 513  if (!to.delete()) { 514  throw new IOException("Unable to delete " + to); 515  } 516  throw new IOException("Unable to delete " + from); 517  } 518  } 519  } 520  521  /** 522  * Reads the first line from a file. The line does not include line-termination characters, but 523  * does include other leading and trailing whitespace. 524  * 525  * @param file the file to read from 526  * @param charset the charset used to decode the input stream; see {@link StandardCharsets} for 527  * helpful predefined constants 528  * @return the first line, or null if the file is empty 529  * @throws IOException if an I/O error occurs 530  * @deprecated Prefer {@code asCharSource(file, charset).readFirstLine()}. This method is 531  * scheduled to be removed in October 2019. 532  */ 533  @Beta 534  @Deprecated 535  @CheckForNull 536  public 537  static String readFirstLine(File file, Charset charset) throws IOException { 538  return asCharSource(file, charset).readFirstLine(); 539  } 540  541  /** 542  * Reads all of the lines from a file. The lines do not include line-termination characters, but 543  * do include other leading and trailing whitespace. 544  * 545  * <p>This method returns a mutable {@code List}. For an {@code ImmutableList}, use {@code 546  * Files.asCharSource(file, charset).readLines()}. 547  * 548  * <p><b>{@link java.nio.file.Path} equivalent:</b> {@link 549  * java.nio.file.Files#readAllLines(java.nio.file.Path, Charset)}. 550  * 551  * @param file the file to read from 552  * @param charset the charset used to decode the input stream; see {@link StandardCharsets} for 553  * helpful predefined constants 554  * @return a mutable {@link List} containing all the lines 555  * @throws IOException if an I/O error occurs 556  */ 557  @Beta 558  public static List<String> readLines(File file, Charset charset) throws IOException { 559  // don't use asCharSource(file, charset).readLines() because that returns 560  // an immutable list, which would change the behavior of this method 561  return asCharSource(file, charset) 562  .readLines( 563  new LineProcessor<List<String>>() { 564  final List<String> result = Lists.newArrayList(); 565  566  @Override 567  public boolean processLine(String line) { 568  result.add(line); 569  return true; 570  } 571  572  @Override 573  public List<String> getResult() { 574  return result; 575  } 576  }); 577  } 578  579  /** 580  * Streams lines from a {@link File}, stopping when our callback returns false, or we have read 581  * all of the lines. 582  * 583  * @param file the file to read from 584  * @param charset the charset used to decode the input stream; see {@link StandardCharsets} for 585  * helpful predefined constants 586  * @param callback the {@link LineProcessor} to use to handle the lines 587  * @return the output of processing the lines 588  * @throws IOException if an I/O error occurs 589  * @deprecated Prefer {@code asCharSource(file, charset).readLines(callback)}. This method is 590  * scheduled to be removed in October 2019. 591  */ 592  @Beta 593  @Deprecated 594  @CanIgnoreReturnValue // some processors won't return a useful result 595  @ParametricNullness 596  public 597  static <T extends @Nullable Object> T readLines( 598  File file, Charset charset, LineProcessor<T> callback) throws IOException { 599  return asCharSource(file, charset).readLines(callback); 600  } 601  602  /** 603  * Process the bytes of a file. 604  * 605  * <p>(If this seems too complicated, maybe you're looking for {@link #toByteArray}.) 606  * 607  * @param file the file to read 608  * @param processor the object to which the bytes of the file are passed. 609  * @return the result of the byte processor 610  * @throws IOException if an I/O error occurs 611  * @deprecated Prefer {@code asByteSource(file).read(processor)}. This method is scheduled to be 612  * removed in October 2019. 613  */ 614  @Beta 615  @Deprecated 616  @CanIgnoreReturnValue // some processors won't return a useful result 617  @ParametricNullness 618  public 619  static <T extends @Nullable Object> T readBytes(File file, ByteProcessor<T> processor) 620  throws IOException { 621  return asByteSource(file).read(processor); 622  } 623  624  /** 625  * Computes the hash code of the {@code file} using {@code hashFunction}. 626  * 627  * @param file the file to read 628  * @param hashFunction the hash function to use to hash the data 629  * @return the {@link HashCode} of all of the bytes in the file 630  * @throws IOException if an I/O error occurs 631  * @since 12.0 632  * @deprecated Prefer {@code asByteSource(file).hash(hashFunction)}. This method is scheduled to 633  * be removed in October 2019. 634  */ 635  @Beta 636  @Deprecated 637  public 638  static HashCode hash(File file, HashFunction hashFunction) throws IOException { 639  return asByteSource(file).hash(hashFunction); 640  } 641  642  /** 643  * Fully maps a file read-only in to memory as per {@link 644  * FileChannel#map(java.nio.channels.FileChannel.MapMode, long, long)}. 645  * 646  * <p>Files are mapped from offset 0 to its length. 647  * 648  * <p>This only works for files ? {@link Integer#MAX_VALUE} bytes. 649  * 650  * @param file the file to map 651  * @return a read-only buffer reflecting {@code file} 652  * @throws FileNotFoundException if the {@code file} does not exist 653  * @throws IOException if an I/O error occurs 654  * @see FileChannel#map(MapMode, long, long) 655  * @since 2.0 656  */ 657  @Beta 658  public static MappedByteBuffer map(File file) throws IOException { 659  checkNotNull(file); 660  return map(file, MapMode.READ_ONLY); 661  } 662  663  /** 664  * Fully maps a file in to memory as per {@link 665  * FileChannel#map(java.nio.channels.FileChannel.MapMode, long, long)} using the requested {@link 666  * MapMode}. 667  * 668  * <p>Files are mapped from offset 0 to its length. 669  * 670  * <p>This only works for files ? {@link Integer#MAX_VALUE} bytes. 671  * 672  * @param file the file to map 673  * @param mode the mode to use when mapping {@code file} 674  * @return a buffer reflecting {@code file} 675  * @throws FileNotFoundException if the {@code file} does not exist 676  * @throws IOException if an I/O error occurs 677  * @see FileChannel#map(MapMode, long, long) 678  * @since 2.0 679  */ 680  @Beta 681  public static MappedByteBuffer map(File file, MapMode mode) throws IOException { 682  return mapInternal(file, mode, -1); 683  } 684  685  /** 686  * Maps a file in to memory as per {@link FileChannel#map(java.nio.channels.FileChannel.MapMode, 687  * long, long)} using the requested {@link MapMode}. 688  * 689  * <p>Files are mapped from offset 0 to {@code size}. 690  * 691  * <p>If the mode is {@link MapMode#READ_WRITE} and the file does not exist, it will be created 692  * with the requested {@code size}. Thus this method is useful for creating memory mapped files 693  * which do not yet exist. 694  * 695  * <p>This only works for files ? {@link Integer#MAX_VALUE} bytes. 696  * 697  * @param file the file to map 698  * @param mode the mode to use when mapping {@code file} 699  * @return a buffer reflecting {@code file} 700  * @throws IOException if an I/O error occurs 701  * @see FileChannel#map(MapMode, long, long) 702  * @since 2.0 703  */ 704  @Beta 705  public static MappedByteBuffer map(File file, MapMode mode, long size) throws IOException { 706  checkArgument(size >= 0, "size (%s) may not be negative", size); 707  return mapInternal(file, mode, size); 708  } 709  710  private static MappedByteBuffer mapInternal(File file, MapMode mode, long size) 711  throws IOException { 712  checkNotNull(file); 713  checkNotNull(mode); 714  715  Closer closer = Closer.create(); 716  try { 717  RandomAccessFile raf = 718  closer.register(new RandomAccessFile(file, mode == MapMode.READ_ONLY ? "r" : "rw")); 719  FileChannel channel = closer.register(raf.getChannel()); 720  return channel.map(mode, 0, size == -1 ? channel.size() : size); 721  } catch (Throwable e) { 722  throw closer.rethrow(e); 723  } finally { 724  closer.close(); 725  } 726  } 727  728  /** 729  * Returns the lexically cleaned form of the path name, <i>usually</i> (but not always) equivalent 730  * to the original. The following heuristics are used: 731  * 732  * <ul> 733  * <li>empty string becomes . 734  * <li>. stays as . 735  * <li>fold out ./ 736  * <li>fold out ../ when possible 737  * <li>collapse multiple slashes 738  * <li>delete trailing slashes (unless the path is just "/") 739  * </ul> 740  * 741  * <p>These heuristics do not always match the behavior of the filesystem. In particular, consider 742  * the path {@code a/../b}, which {@code simplifyPath} will change to {@code b}. If {@code a} is a 743  * symlink to {@code x}, {@code a/../b} may refer to a sibling of {@code x}, rather than the 744  * sibling of {@code a} referred to by {@code b}. 745  * 746  * @since 11.0 747  */ 748  @Beta 749  public static String simplifyPath(String pathname) { 750  checkNotNull(pathname); 751  if (pathname.length() == 0) { 752  return "."; 753  } 754  755  // split the path apart 756  Iterable<String> components = Splitter.on('/').omitEmptyStrings().split(pathname); 757  List<String> path = new ArrayList<>(); 758  759  // resolve ., .., and // 760  for (String component : components) { 761  switch (component) { 762  case ".": 763  continue; 764  case "..": 765  if (path.size() > 0 && !path.get(path.size() - 1).equals("..")) { 766  path.remove(path.size() - 1); 767  } else { 768  path.add(".."); 769  } 770  break; 771  default: 772  path.add(component); 773  break; 774  } 775  } 776  777  // put it back together 778  String result = Joiner.on('/').join(path); 779  if (pathname.charAt(0) == '/') { 780  result = "/" + result; 781  } 782  783  while (result.startsWith("/../")) { 784  result = result.substring(3); 785  } 786  if (result.equals("/..")) { 787  result = "/"; 788  } else if ("".equals(result)) { 789  result = "."; 790  } 791  792  return result; 793  } 794  795  /** 796  * Returns the <a href="http://en.wikipedia.org/wiki/Filename_extension">file extension</a> for 797  * the given file name, or the empty string if the file has no extension. The result does not 798  * include the '{@code .}'. 799  * 800  * <p><b>Note:</b> This method simply returns everything after the last '{@code .}' in the file's 801  * name as determined by {@link File#getName}. It does not account for any filesystem-specific 802  * behavior that the {@link File} API does not already account for. For example, on NTFS it will 803  * report {@code "txt"} as the extension for the filename {@code "foo.exe:.txt"} even though NTFS 804  * will drop the {@code ":.txt"} part of the name when the file is actually created on the 805  * filesystem due to NTFS's <a href="https://goo.gl/vTpJi4">Alternate Data Streams</a>. 806  * 807  * @since 11.0 808  */ 809  @Beta 810  public static String getFileExtension(String fullName) { 811  checkNotNull(fullName); 812  String fileName = new File(fullName).getName(); 813  int dotIndex = fileName.lastIndexOf('.'); 814  return (dotIndex == -1) ? "" : fileName.substring(dotIndex + 1); 815  } 816  817  /** 818  * Returns the file name without its <a 819  * href="http://en.wikipedia.org/wiki/Filename_extension">file extension</a> or path. This is 820  * similar to the {@code basename} unix command. The result does not include the '{@code .}'. 821  * 822  * @param file The name of the file to trim the extension from. This can be either a fully 823  * qualified file name (including a path) or just a file name. 824  * @return The file name without its path or extension. 825  * @since 14.0 826  */ 827  @Beta 828  public static String getNameWithoutExtension(String file) { 829  checkNotNull(file); 830  String fileName = new File(file).getName(); 831  int dotIndex = fileName.lastIndexOf('.'); 832  return (dotIndex == -1) ? fileName : fileName.substring(0, dotIndex); 833  } 834  835  /** 836  * Returns a {@link Traverser} instance for the file and directory tree. The returned traverser 837  * starts from a {@link File} and will return all files and directories it encounters. 838  * 839  * <p><b>Warning:</b> {@code File} provides no support for symbolic links, and as such there is no 840  * way to ensure that a symbolic link to a directory is not followed when traversing the tree. In 841  * this case, iterables created by this traverser could contain files that are outside of the 842  * given directory or even be infinite if there is a symbolic link loop. 843  * 844  * <p>If available, consider using {@link MoreFiles#fileTraverser()} instead. It behaves the same 845  * except that it doesn't follow symbolic links and returns {@code Path} instances. 846  * 847  * <p>If the {@link File} passed to one of the {@link Traverser} methods does not exist or is not 848  * a directory, no exception will be thrown and the returned {@link Iterable} will contain a 849  * single element: that file. 850  * 851  * <p>Example: {@code Files.fileTraverser().depthFirstPreOrder(new File("/"))} may return files 852  * with the following paths: {@code ["/", "/etc", "/etc/config.txt", "/etc/fonts", "/home", 853  * "/home/alice", ...]} 854  * 855  * @since 23.5 856  */ 857  @Beta 858  public static Traverser<File> fileTraverser() { 859  return Traverser.forTree(FILE_TREE); 860  } 861  862  private static final SuccessorsFunction<File> FILE_TREE = 863  new SuccessorsFunction<File>() { 864  @Override 865  public Iterable<File> successors(File file) { 866  // check isDirectory() just because it may be faster than listFiles() on a non-directory 867  if (file.isDirectory()) { 868  File[] files = file.listFiles(); 869  if (files != null) { 870  return Collections.unmodifiableList(Arrays.asList(files)); 871  } 872  } 873  874  return ImmutableList.of(); 875  } 876  }; 877  878  /** 879  * Returns a predicate that returns the result of {@link File#isDirectory} on input files. 880  * 881  * @since 15.0 882  */ 883  @Beta 884  public static Predicate<File> isDirectory() { 885  return FilePredicate.IS_DIRECTORY; 886  } 887  888  /** 889  * Returns a predicate that returns the result of {@link File#isFile} on input files. 890  * 891  * @since 15.0 892  */ 893  @Beta 894  public static Predicate<File> isFile() { 895  return FilePredicate.IS_FILE; 896  } 897  898  private enum FilePredicate implements Predicate<File> { 899  IS_DIRECTORY { 900  @Override 901  public boolean apply(File file) { 902  return file.isDirectory(); 903  } 904  905  @Override 906  public String toString() { 907  return "Files.isDirectory()"; 908  } 909  }, 910  911  IS_FILE { 912  @Override 913  public boolean apply(File file) { 914  return file.isFile(); 915  } 916  917  @Override 918  public String toString() { 919  return "Files.isFile()"; 920  } 921  } 922  } 923 }