All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.hasor.utils.io.FileUtils Maven / Gradle / Ivy

There is a newer version: 4.2.5
Show newest version
/*
 * Copyright 2008-2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.hasor.utils.io;
import java.io.*;
import java.util.Collection;
import java.util.List;

/**
 * 文件工具
 * @version : 2011-6-3
 * @author 赵永春 ([email protected])
 */
public abstract class FileUtils {
    /**
     * Reads the contents of a file into a String.
     * The file is always closed.
     *
     * @param file  the file to read, must not be null
     * @param encoding  the encoding to use, null means platform default
     * @return the file contents, never null
     * @throws IOException in case of an I/O error
     * @throws UnsupportedEncodingException if the encoding is not supported by the VM
     */
    public static String readFileToString(File file, String encoding) throws IOException {
        InputStream in = null;
        try {
            in = openInputStream(file);
            return IOUtils.toString(in, encoding);
        } finally {
            IOUtils.closeQuietly(in);
        }
    }

    /**
     * Reads the contents of a file into a String using the default encoding for the VM. 
     * The file is always closed.
     *
     * @param file  the file to read, must not be null
     * @return the file contents, never null
     * @throws IOException in case of an I/O error
     * @since Commons IO 1.3.1
     */
    public static String readFileToString(File file) throws IOException {
        return readFileToString(file, null);
    }

    /**
     * Reads the contents of a file into a byte array.
     * The file is always closed.
     *
     * @param file  the file to read, must not be null
     * @return the file contents, never null
     * @throws IOException in case of an I/O error
     * @since Commons IO 1.1
     */
    public static byte[] readFileToByteArray(File file) throws IOException {
        InputStream in = null;
        try {
            in = openInputStream(file);
            return IOUtils.toByteArray(in, file.length());
        } finally {
            IOUtils.closeQuietly(in);
        }
    }

    /**
     * Reads the contents of a file line by line to a List of Strings.
     * The file is always closed.
     *
     * @param file  the file to read, must not be null
     * @param encoding  the encoding to use, null means platform default
     * @return the list of Strings representing each line in the file, never null
     * @throws IOException in case of an I/O error
     * @throws UnsupportedEncodingException if the encoding is not supported by the VM
     * @since Commons IO 1.1
     */
    public static List readLines(File file, String encoding) throws IOException {
        InputStream in = null;
        try {
            in = openInputStream(file);
            return IOUtils.readLines(in, encoding);
        } finally {
            IOUtils.closeQuietly(in);
        }
    }

    /**
     * Reads the contents of a file line by line to a List of Strings using the default encoding for the VM.
     * The file is always closed.
     *
     * @param file  the file to read, must not be null
     * @return the list of Strings representing each line in the file, never null
     * @throws IOException in case of an I/O error
     * @since Commons IO 1.3
     */
    public static List readLines(File file) throws IOException {
        return readLines(file, null);
    }

    /**
     * Returns an Iterator for the lines in a File.
     * 

* This method opens an InputStream for the file. * When you have finished with the iterator you should close the stream * to free internal resources. This can be done by calling the * {@link LineIterator#close()} or * {@link LineIterator#closeQuietly(LineIterator)} method. *

* The recommended usage pattern is: *

     * LineIterator it = FileUtils.lineIterator(file, "UTF-8");
     * try {
     *   while (it.hasNext()) {
     *     String line = it.nextLine();
     *     /// do something with line
     *   }
     * } finally {
     *   LineIterator.closeQuietly(iterator);
     * }
     * 
*

* If an exception occurs during the creation of the iterator, the * underlying stream is closed. * * @param file the file to open for input, must not be null * @param encoding the encoding to use, null means platform default * @return an Iterator of the lines in the file, never null * @throws IOException in case of an I/O error (file closed) * @since Commons IO 1.2 */ public static LineIterator lineIterator(File file, String encoding) throws IOException { InputStream in = null; try { in = openInputStream(file); return IOUtils.lineIterator(in, encoding); } catch (IOException ex) { IOUtils.closeQuietly(in); throw ex; } catch (RuntimeException ex) { IOUtils.closeQuietly(in); throw ex; } } /** * Returns an Iterator for the lines in a File using the default encoding for the VM. * * @param file the file to open for input, must not be null * @return an Iterator of the lines in the file, never null * @throws IOException in case of an I/O error (file closed) * @since Commons IO 1.3 * @see #lineIterator(File, String) */ public static LineIterator lineIterator(File file) throws IOException { return lineIterator(file, null); } //----------------------------------------------------------------------- /** * Writes a String to a file creating the file if it does not exist. * * NOTE: As from v1.3, the parent directories of the file will be created * if they do not exist. * * @param file the file to write * @param data the content to write to the file * @param encoding the encoding to use, null means platform default * @throws IOException in case of an I/O error * @throws UnsupportedEncodingException if the encoding is not supported by the VM */ public static void writeStringToFile(File file, String data, String encoding) throws IOException { writeStringToFile(file, data, encoding, false); } /** * Writes a String to a file creating the file if it does not exist. * * @param file the file to write * @param data the content to write to the file * @param encoding the encoding to use, null means platform default * @param append if true, then the String will be added to the * end of the file rather than overwriting * @throws IOException in case of an I/O error * @throws UnsupportedEncodingException if the encoding is not supported by the VM * @since Commons IO 2.1 */ public static void writeStringToFile(File file, String data, String encoding, boolean append) throws IOException { OutputStream out = null; try { out = openOutputStream(file, append); IOUtils.write(data, out, encoding); } finally { IOUtils.closeQuietly(out); } } /** * Writes a String to a file creating the file if it does not exist using the default encoding for the VM. * * @param file the file to write * @param data the content to write to the file * @throws IOException in case of an I/O error */ public static void writeStringToFile(File file, String data) throws IOException { writeStringToFile(file, data, null, false); } /** * Writes a String to a file creating the file if it does not exist using the default encoding for the VM. * * @param file the file to write * @param data the content to write to the file * @param append if true, then the String will be added to the * end of the file rather than overwriting * @throws IOException in case of an I/O error * @since Commons IO 2.1 */ public static void writeStringToFile(File file, String data, boolean append) throws IOException { writeStringToFile(file, data, null, append); } /** * Writes a CharSequence to a file creating the file if it does not exist using the default encoding for the VM. * * @param file the file to write * @param data the content to write to the file * @throws IOException in case of an I/O error * @since Commons IO 2.0 */ public static void write(File file, CharSequence data) throws IOException { write(file, data, null, false); } /** * Writes a CharSequence to a file creating the file if it does not exist using the default encoding for the VM. * * @param file the file to write * @param data the content to write to the file * @param append if true, then the data will be added to the * end of the file rather than overwriting * @throws IOException in case of an I/O error * @since Commons IO 2.1 */ public static void write(File file, CharSequence data, boolean append) throws IOException { write(file, data, null, append); } /** * Writes a CharSequence to a file creating the file if it does not exist. * * @param file the file to write * @param data the content to write to the file * @param encoding the encoding to use, null means platform default * @throws IOException in case of an I/O error * @throws UnsupportedEncodingException if the encoding is not supported by the VM * @since Commons IO 2.0 */ public static void write(File file, CharSequence data, String encoding) throws IOException { write(file, data, encoding, false); } /** * Writes a CharSequence to a file creating the file if it does not exist. * * @param file the file to write * @param data the content to write to the file * @param encoding the encoding to use, null means platform default * @param append if true, then the data will be added to the * end of the file rather than overwriting * @throws IOException in case of an I/O error * @throws UnsupportedEncodingException if the encoding is not supported by the VM * @since IO 2.1 */ public static void write(File file, CharSequence data, String encoding, boolean append) throws IOException { String str = data == null ? null : data.toString(); writeStringToFile(file, str, encoding, append); } /** * Writes a byte array to a file creating the file if it does not exist. *

* NOTE: As from v1.3, the parent directories of the file will be created * if they do not exist. * * @param file the file to write to * @param data the content to write to the file * @throws IOException in case of an I/O error * @since Commons IO 1.1 */ public static void writeByteArrayToFile(File file, byte[] data) throws IOException { writeByteArrayToFile(file, data, false); } /** * Writes a byte array to a file creating the file if it does not exist. * * @param file the file to write to * @param data the content to write to the file * @param append if true, then bytes will be added to the * end of the file rather than overwriting * @throws IOException in case of an I/O error * @since IO 2.1 */ public static void writeByteArrayToFile(File file, byte[] data, boolean append) throws IOException { OutputStream out = null; try { out = openOutputStream(file, append); out.write(data); } finally { IOUtils.closeQuietly(out); } } /** * Writes the toString() value of each item in a collection to * the specified File line by line. * The specified character encoding and the default line ending will be used. *

* NOTE: As from v1.3, the parent directories of the file will be created * if they do not exist. * * @param file the file to write to * @param encoding the encoding to use, null means platform default * @param lines the lines to write, null entries produce blank lines * @throws IOException in case of an I/O error * @throws UnsupportedEncodingException if the encoding is not supported by the VM * @since Commons IO 1.1 */ public static void writeLines(File file, String encoding, Collection lines) throws IOException { writeLines(file, encoding, lines, null, false); } /** * Writes the toString() value of each item in a collection to * the specified File line by line, optionally appending. * The specified character encoding and the default line ending will be used. * * @param file the file to write to * @param encoding the encoding to use, null means platform default * @param lines the lines to write, null entries produce blank lines * @param append if true, then the lines will be added to the * end of the file rather than overwriting * @throws IOException in case of an I/O error * @throws UnsupportedEncodingException if the encoding is not supported by the VM * @since Commons IO 2.1 */ public static void writeLines(File file, String encoding, Collection lines, boolean append) throws IOException { writeLines(file, encoding, lines, null, append); } /** * Writes the toString() value of each item in a collection to * the specified File line by line. * The default VM encoding and the default line ending will be used. * * @param file the file to write to * @param lines the lines to write, null entries produce blank lines * @throws IOException in case of an I/O error * @since Commons IO 1.3 */ public static void writeLines(File file, Collection lines) throws IOException { writeLines(file, null, lines, null, false); } /** * Writes the toString() value of each item in a collection to * the specified File line by line. * The default VM encoding and the default line ending will be used. * * @param file the file to write to * @param lines the lines to write, null entries produce blank lines * @param append if true, then the lines will be added to the * end of the file rather than overwriting * @throws IOException in case of an I/O error * @since Commons IO 2.1 */ public static void writeLines(File file, Collection lines, boolean append) throws IOException { writeLines(file, null, lines, null, append); } /** * Writes the toString() value of each item in a collection to * the specified File line by line. * The specified character encoding and the line ending will be used. *

* NOTE: As from v1.3, the parent directories of the file will be created * if they do not exist. * * @param file the file to write to * @param encoding the encoding to use, null means platform default * @param lines the lines to write, null entries produce blank lines * @param lineEnding the line separator to use, null is system default * @throws IOException in case of an I/O error * @throws UnsupportedEncodingException if the encoding is not supported by the VM * @since Commons IO 1.1 */ public static void writeLines(File file, String encoding, Collection lines, String lineEnding) throws IOException { writeLines(file, encoding, lines, lineEnding, false); } /** * Writes the toString() value of each item in a collection to * the specified File line by line. * The specified character encoding and the line ending will be used. * * @param file the file to write to * @param encoding the encoding to use, null means platform default * @param lines the lines to write, null entries produce blank lines * @param lineEnding the line separator to use, null is system default * @param append if true, then the lines will be added to the * end of the file rather than overwriting * @throws IOException in case of an I/O error * @throws UnsupportedEncodingException if the encoding is not supported by the VM * @since Commons IO 2.1 */ public static void writeLines(File file, String encoding, Collection lines, String lineEnding, boolean append) throws IOException { OutputStream out = null; try { out = openOutputStream(file, append); IOUtils.writeLines(lines, lineEnding, out, encoding); } finally { IOUtils.closeQuietly(out); } } /** * Writes the toString() value of each item in a collection to * the specified File line by line. * The default VM encoding and the specified line ending will be used. * * @param file the file to write to * @param lines the lines to write, null entries produce blank lines * @param lineEnding the line separator to use, null is system default * @throws IOException in case of an I/O error * @since Commons IO 1.3 */ public static void writeLines(File file, Collection lines, String lineEnding) throws IOException { writeLines(file, null, lines, lineEnding, false); } /** * Writes the toString() value of each item in a collection to * the specified File line by line. * The default VM encoding and the specified line ending will be used. * * @param file the file to write to * @param lines the lines to write, null entries produce blank lines * @param lineEnding the line separator to use, null is system default * @param append if true, then the lines will be added to the * end of the file rather than overwriting * @throws IOException in case of an I/O error * @since Commons IO 2.1 */ public static void writeLines(File file, Collection lines, String lineEnding, boolean append) throws IOException { writeLines(file, null, lines, lineEnding, append); } //----------------------------------------------------------------------- /** * Opens a {@link FileInputStream} for the specified file, providing better * error messages than simply calling new FileInputStream(file). *

* At the end of the method either the stream will be successfully opened, * or an exception will have been thrown. *

* An exception is thrown if the file does not exist. * An exception is thrown if the file object exists but is a directory. * An exception is thrown if the file exists but cannot be read. * * @param file the file to open for input, must not be null * @return a new {@link FileInputStream} for the specified file * @throws FileNotFoundException if the file does not exist * @throws IOException if the file object is a directory * @throws IOException if the file cannot be read * @since Commons IO 1.3 */ public static FileInputStream openInputStream(File file) throws IOException { if (file.exists()) { if (file.isDirectory()) { throw new IOException("File '" + file + "' exists but is a directory"); } if (file.canRead() == false) { throw new IOException("File '" + file + "' cannot be read"); } } else { throw new FileNotFoundException("File '" + file + "' does not exist"); } return new FileInputStream(file); } //----------------------------------------------------------------------- /** * Opens a {@link FileOutputStream} for the specified file, checking and * creating the parent directory if it does not exist. *

* At the end of the method either the stream will be successfully opened, * or an exception will have been thrown. *

* The parent directory will be created if it does not exist. * The file will be created if it does not exist. * An exception is thrown if the file object exists but is a directory. * An exception is thrown if the file exists but cannot be written to. * An exception is thrown if the parent directory cannot be created. * * @param file the file to open for output, must not be null * @return a new {@link FileOutputStream} for the specified file * @throws IOException if the file object is a directory * @throws IOException if the file cannot be written to * @throws IOException if a parent directory needs creating but that fails * @since Commons IO 1.3 */ public static FileOutputStream openOutputStream(File file) throws IOException { return openOutputStream(file, false); } /** * Opens a {@link FileOutputStream} for the specified file, checking and * creating the parent directory if it does not exist. *

* At the end of the method either the stream will be successfully opened, * or an exception will have been thrown. *

* The parent directory will be created if it does not exist. * The file will be created if it does not exist. * An exception is thrown if the file object exists but is a directory. * An exception is thrown if the file exists but cannot be written to. * An exception is thrown if the parent directory cannot be created. * * @param file the file to open for output, must not be null * @param append if true, then bytes will be added to the * end of the file rather than overwriting * @return a new {@link FileOutputStream} for the specified file * @throws IOException if the file object is a directory * @throws IOException if the file cannot be written to * @throws IOException if a parent directory needs creating but that fails * @since Commons IO 2.1 */ public static FileOutputStream openOutputStream(File file, boolean append) throws IOException { if (file.exists()) { if (file.isDirectory()) { throw new IOException("File '" + file + "' exists but is a directory"); } if (file.canWrite() == false) { throw new IOException("File '" + file + "' cannot be written to"); } } else { File parent = file.getParentFile(); if (parent != null) { if (!parent.mkdirs() && !parent.isDirectory()) { throw new IOException("Directory '" + parent + "' could not be created"); } } } return new FileOutputStream(file, append); } //----------------------------------------------------------------------- /** * Deletes a directory recursively. * * @param directory directory to delete * @throws IOException in case deletion is unsuccessful */ public static void deleteDirectory(File directory) throws IOException { if (!directory.exists()) { return; } if (!isSymlink(directory)) { cleanDirectory(directory); } if (!directory.delete()) { String message = "Unable to delete directory " + directory + "."; throw new IOException(message); } } /** * Cleans a directory without deleting it. * * @param directory directory to clean * @throws IOException in case cleaning is unsuccessful */ public static void cleanDirectory(File directory) throws IOException { if (!directory.exists()) { String message = directory + " does not exist"; throw new IllegalArgumentException(message); } if (!directory.isDirectory()) { String message = directory + " is not a directory"; throw new IllegalArgumentException(message); } File[] files = directory.listFiles(); if (files == null) { // null if security restricted throw new IOException("Failed to list contents of " + directory); } IOException exception = null; for (File file : files) { try { forceDelete(file); } catch (IOException ioe) { exception = ioe; } } if (null != exception) { throw exception; } } /** * Deletes a file, never throwing an exception. If file is a directory, delete it and all sub-directories. *

* The difference between File.delete() and this method are: *

    *
  • A directory to be deleted does not have to be empty.
  • *
  • No exceptions are thrown when a file or directory cannot be deleted.
  • *
* * @param file file or directory to delete, can be {@code null} * @return {@code true} if the file or directory was deleted, otherwise * {@code false} * * @since 1.4 */ public static boolean deleteQuietly(File file) { if (file == null) { return false; } try { if (file.isDirectory()) { cleanDirectory(file); } } catch (Exception ignored) { } try { return file.delete(); } catch (Exception ignored) { return false; } } /** * Schedules a directory recursively for deletion on JVM exit. * * @param directory directory to delete, must not be {@code null} * @throws NullPointerException if the directory is {@code null} * @throws IOException in case deletion is unsuccessful */ private static void deleteDirectoryOnExit(File directory) throws IOException { if (!directory.exists()) { return; } directory.deleteOnExit(); if (!isSymlink(directory)) { cleanDirectoryOnExit(directory); } } /** * Cleans a directory without deleting it. * * @param directory directory to clean, must not be {@code null} * @throws NullPointerException if the directory is {@code null} * @throws IOException in case cleaning is unsuccessful */ private static void cleanDirectoryOnExit(File directory) throws IOException { if (!directory.exists()) { String message = directory + " does not exist"; throw new IllegalArgumentException(message); } if (!directory.isDirectory()) { String message = directory + " is not a directory"; throw new IllegalArgumentException(message); } File[] files = directory.listFiles(); if (files == null) { // null if security restricted throw new IOException("Failed to list contents of " + directory); } IOException exception = null; for (File file : files) { try { forceDeleteOnExit(file); } catch (IOException ioe) { exception = ioe; } } if (null != exception) { throw exception; } } /** * Determines whether the specified file is a Symbolic Link rather than an actual file. *

* Will not return true if there is a Symbolic Link anywhere in the path, * only if the specific file is. *

* Note: the current implementation always returns {@code false} if the system * is detected as Windows using {@link FilenameUtils#isSystemWindows()} * * @param file the file to check * @return true if the file is a Symbolic Link * @throws IOException if an IO error occurs while checking the file * @since 2.0 */ public static boolean isSymlink(File file) throws IOException { if (file == null) { throw new NullPointerException("File must not be null"); } if (FilenameUtils.isSystemWindows()) { return false; } File fileInCanonicalDir = null; if (file.getParent() == null) { fileInCanonicalDir = file; } else { File canonicalDir = file.getParentFile().getCanonicalFile(); fileInCanonicalDir = new File(canonicalDir, file.getName()); } if (fileInCanonicalDir.getCanonicalFile().equals(fileInCanonicalDir.getAbsoluteFile())) { return false; } else { return true; } } /** * Deletes a file. If file is a directory, delete it and all sub-directories. *

* The difference between File.delete() and this method are: *

    *
  • A directory to be deleted does not have to be empty.
  • *
  • You get exceptions when a file or directory cannot be deleted. * (java.io.File methods returns a boolean)
  • *
* * @param file file or directory to delete, must not be {@code null} * @throws NullPointerException if the directory is {@code null} * @throws FileNotFoundException if the file was not found * @throws IOException in case deletion is unsuccessful */ public static void forceDelete(File file) throws IOException { if (file.isDirectory()) { deleteDirectory(file); } else { boolean filePresent = file.exists(); if (!file.delete()) { if (!filePresent) { throw new FileNotFoundException("File does not exist: " + file); } String message = "Unable to delete file: " + file; throw new IOException(message); } } } /** * Schedules a file to be deleted when JVM exits. * If file is directory delete it and all sub-directories. * * @param file file or directory to delete, must not be {@code null} * @throws NullPointerException if the file is {@code null} * @throws IOException in case deletion is unsuccessful */ public static void forceDeleteOnExit(File file) throws IOException { if (file.isDirectory()) { deleteDirectoryOnExit(file); } else { file.deleteOnExit(); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy