ml.shifu.guagua.util.FileUtils Maven / Gradle / Ivy
/*
* Copyright [2013-2014] PayPal Software Foundation
*
* 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 ml.shifu.guagua.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
/**
* Copied from apache common-io source code.
*/
public final class FileUtils {
/**
* Instances should NOT be constructed in standard programming.
*/
private FileUtils() {
}
/**
* The Unix separator character.
*/
public static final char UNIX_SEPARATOR = '/';
/**
* The Windows separator character.
*/
public static final char WINDOWS_SEPARATOR = '\\';
/**
* The system separator character.
*/
public static final char SYSTEM_SEPARATOR = File.separatorChar;
/**
* Returns the path to the system temporary directory.
*
* @return the path to the system temporary directory.
*
* @since Commons IO 2.0
*/
public static String getTempDirectoryPath() {
return System.getProperty("java.io.tmpdir");
}
/**
* Returns a {@link File} representing the system temporary directory.
*
* @return the system temporary directory.
*
* @since Commons IO 2.0
*/
public static File getTempDirectory() {
return new File(getTempDirectoryPath());
}
/**
* Returns the path to the user's home directory.
*
* @return the path to the user's home directory.
*
* @since Commons IO 2.0
*/
public static String getUserDirectoryPath() {
return System.getProperty("user.home");
}
/**
* Returns a {@link File} representing the user's home directory.
*
* @return the user's home directory.
*
* @since Commons IO 2.0
*/
public static File getUserDirectory() {
return new File(getUserDirectoryPath());
}
// -----------------------------------------------------------------------
/**
* 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);
}
}
/**
* 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 null
* @return true
if the file or directory was deleted, otherwise false
*
* @since Commons IO 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;
}
}
/**
* 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. 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 null
* @throws NullPointerException
* if the directory is 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 null
* @throws NullPointerException
* if the file is null
* @throws IOException
* in case deletion is unsuccessful
*/
public static void forceDeleteOnExit(File file) throws IOException {
if(file.isDirectory()) {
deleteDirectoryOnExit(file);
} else {
file.deleteOnExit();
}
}
/**
* Schedules a directory recursively for deletion on JVM exit.
*
* @param directory
* directory to delete, must not be null
* @throws NullPointerException
* if the directory is null
* @throws IOException
* in case deletion is unsuccessful
*/
private static void deleteDirectoryOnExit(File directory) throws IOException {
if(!directory.exists()) {
return;
}
if(!isSymlink(directory)) {
cleanDirectoryOnExit(directory);
}
directory.deleteOnExit();
}
/**
* Cleans a directory without deleting it.
*
* @param directory
* directory to clean, must not be null
* @throws NullPointerException
* if the directory is 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.
*
* @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 Commons IO 2.0
*/
public static boolean isSymlink(File file) throws IOException {
if(file == null) {
throw new NullPointerException("File must not be null");
}
if(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;
}
}
/**
* Determines if Windows file system is in use.
*
* @return true if the system is Windows
*/
static boolean isSystemWindows() {
return SYSTEM_SEPARATOR == WINDOWS_SEPARATOR;
}
/**
* 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 java.io.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 readLines(in, encoding);
} finally {
if(in != null) {
in.close();
}
}
}
/**
* 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);
}
/**
* Get the contents of an InputStream
as a list of Strings,
* one entry per line, using the default character encoding of the platform.
*
* This method buffers the input internally, so there is no need to use a BufferedInputStream
.
*
* @param input
* the InputStream
to read from, not null
* @return the list of Strings, never null
* @throws NullPointerException
* if the input is null
* @throws IOException
* if an I/O error occurs
* @since Commons IO 1.1
*/
public static List readLines(InputStream input) throws IOException {
InputStreamReader reader = new InputStreamReader(input);
return readLines(reader);
}
/**
* Get the contents of an InputStream
as a list of Strings,
* one entry per line, using the specified character encoding.
*
* Character encoding names can be found at IANA.
*
* This method buffers the input internally, so there is no need to use a BufferedInputStream
.
*
* @param input
* the InputStream
to read from, not null
* @param encoding
* the encoding to use, null means platform default
* @return the list of Strings, never null
* @throws NullPointerException
* if the input is null
* @throws IOException
* if an I/O error occurs
* @since Commons IO 1.1
*/
public static List readLines(InputStream input, String encoding) throws IOException {
if(encoding == null) {
return readLines(input);
} else {
InputStreamReader reader = new InputStreamReader(input, encoding);
return readLines(reader);
}
}
/**
* Get the contents of a Reader
as a list of Strings,
* one entry per line.
*
* This method buffers the input internally, so there is no need to use a BufferedReader
.
*
* @param input
* the Reader
to read from, not null
* @return the list of Strings, never null
* @throws NullPointerException
* if the input is null
* @throws IOException
* if an I/O error occurs
* @since Commons IO 1.1
*/
public static List readLines(Reader input) throws IOException {
BufferedReader reader = new BufferedReader(input);
List list = new ArrayList();
String line = reader.readLine();
while(line != null) {
list.add(line);
line = reader.readLine();
}
return list;
}
/**
* 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);
}
}