/*
* Copyright 2004-2005 Revolution Systems Inc.
*
* 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 com.revolsys.io;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import com.revolsys.datatype.DataTypes;
import com.revolsys.io.file.FileConnectionManager;
import com.revolsys.io.file.FolderConnection;
import com.revolsys.io.file.FolderConnectionRegistry;
import com.revolsys.io.filter.ExtensionFilenameFilter;
import com.revolsys.io.filter.PatternFilenameFilter;
import com.revolsys.logging.Logs;
import com.revolsys.spring.resource.FileSystemResource;
import com.revolsys.spring.resource.Resource;
import com.revolsys.util.Exceptions;
import com.revolsys.util.Property;
import com.revolsys.util.UrlUtil;
/**
* The TestFileUtil class is a utility class for performing common tasks with
* classes from the java.io package.
*
* @author Paul Austin
*/
public final class FileUtil {
/** Files or directories to be deleted on exit. */
private static final List<File> deleteFilesOnExit = new ArrayList<>();
/** The thread that deletes files on exit. */
private static Thread deleteFilesOnExitThread;
public static final FilenameFilter IMAGE_FILENAME_FILTER = new ExtensionFilenameFilter(
Arrays.asList(new String[] {
"gif", "jpg", "png", "tif", "tiff", "bmp"
}));
/** The file path separator for UNIX based systems. */
public static final char UNIX_FILE_SEPARATOR = '/';
public static final FilenameFilter VIDEO_FILENAME_FILTER = new ExtensionFilenameFilter(
Arrays.asList(new String[] {
"avi", "wmv", "flv", "mpg"
}));
/** The file path separator for Windows based systems. */
public static final char WINDOWS_FILE_SEPARATOR = '\\';
/**
* Close the writer without throwing an I/O exception if the close failed. The
* error will be logged instead.
*
* @param closeables The closables to close.
*/
public static void closeSilent(final AutoCloseable... closeables) {
for (final AutoCloseable closeable : closeables) {
closeSilent(closeable);
}
}
public static void closeSilent(final AutoCloseable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (final IOException e) {
} catch (final Exception e) {
Logs.error(FileUtil.class, e.getMessage(), e);
}
}
}
/**
* Close the writer without throwing an I/O exception if the close failed. The
* error will be logged instead.
*
* @param closeables The closables to close.
*/
public static void closeSilent(final Collection<? extends AutoCloseable> closeables) {
for (final AutoCloseable closeable : closeables) {
closeSilent(closeable);
}
}
/**
* Convert the path containing UNIX or Windows file separators to the local
* {@link File#separator} character.
*
* @param path The path to convert.
* @return The converted path.
*/
public static String convertPath(final String path) {
final char separator = File.separatorChar;
if (separator == WINDOWS_FILE_SEPARATOR) {
return path.replace(UNIX_FILE_SEPARATOR, separator);
} else if (separator == UNIX_FILE_SEPARATOR) {
return path.replace(WINDOWS_FILE_SEPARATOR, separator);
} else {
return path.replace(UNIX_FILE_SEPARATOR, separator).replace(WINDOWS_FILE_SEPARATOR,
separator);
}
}
public static void copy(final File src, final File dest) {
if (src.isDirectory()) {
dest.mkdirs();
final File[] files = src.listFiles();
if (files != null) {
for (final File file : files) {
final String name = getFileName(file);
final File destFile = new File(dest, name);
copy(file, destFile);
}
}
} else {
try {
final FileInputStream in = new FileInputStream(src);
File destFile;
if (dest.isDirectory()) {
final String name = getFileName(src);
destFile = new File(dest, name);
} else {
destFile = dest;
}
copy(in, destFile);
} catch (final FileNotFoundException e) {
Exceptions.throwUncheckedException(e);
}
}
}
/**
* Copy the contents of the file to the output stream. The output stream will
* need to be closed manually after invoking this method.
*
* @param file The file to read the contents from.
* @param out The output stream to write the contents to.
* @throws IOException If an I/O error occurs.
*/
public static long copy(final File file, final OutputStream out) throws IOException {
final FileInputStream in = new FileInputStream(file);
try {
return copy(in, out);
} finally {
in.close();
}
}
/**
* Copy the contents of the file to the writer. The writer will need to be
* closed manually after invoking this method.
*
* @param file The file to read the contents from.
* @param out The writer to write the contents to.
* @throws IOException If an I/O error occurs.
*/
public static long copy(final File file, final Writer out) throws IOException {
final FileReader in = getReader(file);
try {
return copy(in, out);
} finally {
in.close();
}
}
/**
* Copy the contents of the input stream to the file. The input stream will
* need to be closed manually after invoking this method.
*
* @param in The input stream to read the contents from.
* @param file The file to write the contents to.
* @throws IOException If an I/O error occurs.
*/
public static long copy(final InputStream in, final File file) {
try {
file.getParentFile().mkdirs();
try (
final FileOutputStream out = new FileOutputStream(file)) {
return copy(in, out);
}
} catch (final IOException e) {
throw new RuntimeException("Unable to open file: " + file, e);
}
}
/**
* Writes the content of a zip entry to a file using NIO.
*
* @param zin input stream from zip file
* @param file file path where this entry will be saved
* @param sz file size
* @throws IOException if an i/o error
*/
public static void copy(final InputStream zin, final File file, final long sz)
throws IOException {
ReadableByteChannel rc = null;
FileOutputStream out = null;
try {
rc = Channels.newChannel(zin);
out = new FileOutputStream(file);
final FileChannel fc = out.getChannel();
// read into the buffer
long count = 0;
int attempts = 0;
while (count < sz) {
final long written = fc.transferFrom(rc, count, sz);
count += written;
if (written == 0) {
attempts++;
if (attempts > 100) {
throw new IOException("Error writing to file " + file);
}
} else {
attempts = 0;
}
}
out.close();
out = null;
} finally {
if (out != null) {
FileUtil.closeSilent(out);
}
}
}
/**
* Copy the contents of the input stream to the output stream. The input
* stream and output stream will need to be closed manually after invoking
* this method.
*
* @param in The input stream to read the contents from.
* @param out The output stream to write the contents to.
*/
public static long copy(final InputStream in, final OutputStream out) {
if (in == null) {
return 0;
} else {
try {
final byte[] buffer = new byte[4096];
long numBytes = 0;
int count;
while ((count = in.read(buffer)) > -1) {
out.write(buffer, 0, count);
numBytes += count;
}
return numBytes;
} catch (final IOException e) {
return (Long)Exceptions.throwUncheckedException(e);
}
}
}
/**
* Copy the contents of the input stream to the output stream. The input
* stream and output stream will need to be closed manually after invoking
* this method.
*
* @param in The input stream to read the contents from.
* @param out The output stream to write the contents to.
*/
public static long copy(final InputStream in, final OutputStream out, final long length) {
if (in == null) {
return 0;
} else {
try {
final byte[] buffer = new byte[4096];
long totalBytes = 0;
int readBytes;
while (totalBytes < length && (readBytes = in.read(buffer)) > -1) {
if (totalBytes + readBytes > length) {
readBytes = (int)(length - totalBytes);
}
totalBytes += readBytes;
out.write(buffer, 0, readBytes);
}
return totalBytes;
} catch (final IOException e) {
return (Long)Exceptions.throwUncheckedException(e);
}
}
}
/**
* Copy the contents of the reader to the file. The reader will need to be
* closed manually after invoking this method.
*
* @param in The reader to read the contents from.
* @param file The file to write the contents to.
* @throws IOException If an I/O error occurs.
*/
public static void copy(final Reader in, final File file) {
try {
final FileWriter out = new FileWriter(file);
try {
copy(in, out);
} finally {
closeSilent(in);
closeSilent(out);
}
} catch (final IOException e) {
throw new IllegalArgumentException("Unable to write to " + file);
}
}
/**
* Copy the contents of the reader to the writer. The reader and writer will
* need to be closed manually after invoking this method.
*
* @param in The reader to read the contents from.
* @param out The writer to write the contents to.
* @throws IOException If an I/O error occurs.
*/
public static long copy(final Reader in, final Writer out) {
try {
final char[] buffer = new char[4906];
long numBytes = 0;
int count;
while ((count = in.read(buffer)) > -1) {
out.write(buffer, 0, count);
numBytes += count;
}
return numBytes;
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
/**
* Copy the contents of the reader to the writer. The input
* stream and output stream will need to be closed manually after invoking
* this method.
*
* @param in The input stream to read the contents from.
* @param out The output stream to write the contents to.
*/
public static long copy(final Reader in, final Writer out, final long length) {
if (in == null) {
return 0;
} else {
try {
final char[] buffer = new char[4096];
long totalBytes = 0;
int readBytes;
while (totalBytes < length && (readBytes = in.read(buffer)) > -1) {
if (totalBytes + readBytes > length) {
readBytes = (int)(length - totalBytes);
}
totalBytes += readBytes;
out.write(buffer, 0, readBytes);
}
return totalBytes;
} catch (final IOException e) {
return (Long)Exceptions.throwUncheckedException(e);
}
}
}
public static void copy(final String text, final File file) {
copy(new StringReader(text), file);
}
public static void createParentDirectories(final File file) {
final File parentFile = file.getParentFile();
if (parentFile != null && !parentFile.exists()) {
parentFile.mkdirs();
}
}
public static boolean delete(final File file) {
if (file == null) {
return false;
} else {
return file.delete();
}
}
/**
* Delete a directory and all the files and sub directories below the
* directory.
*
* @param directory The directory to delete.
*/
public static boolean deleteDirectory(final File directory) {
return deleteDirectory(directory, true);
}
/**
* Delete all the files and sub directories below the directory. If the
* deleteRoot flag is true the directory will also be deleted.
*
* @param directory The directory to delete.
* @param deleteRoot Flag indicating if the directory should also be deleted.
* @throws IOException If a file or directory could not be deleted.
*/
public static boolean deleteDirectory(final File directory, final boolean deleteRoot) {
boolean deleted = true;
if (directory != null) {
final File[] files = directory.listFiles();
if (files != null) {
for (final File file2 : files) {
final File file = file2;
if (file.exists()) {
if (file.isDirectory()) {
if (!deleteDirectory(file, true)) {
deleted = false;
}
} else {
if (!file.delete() && file.exists()) {
deleted = false;
try {
throw new RuntimeException("Cannot delete file: " + getCanonicalPath(file));
} catch (final Throwable e) {
Logs.error(FileUtil.class, e);
}
}
}
}
}
}
if (deleteRoot) {
if (!directory.delete() && directory.exists()) {
deleted = false;
try {
throw new RuntimeException("Cannot delete directory: " + getCanonicalPath(directory));
} catch (final Throwable e) {
Logs.error(FileUtil.class, e);
}
}
}
}
return deleted;
}
public static void deleteDirectory(final File directory, final FilenameFilter filter) {
final File[] files = directory.listFiles();
if (files != null) {
for (final File file2 : files) {
final File file = file2;
if (file.exists() && filter.accept(directory, getFileName(file))) {
if (file.isDirectory()) {
deleteDirectory(file, true);
} else {
if (!file.delete() && file.exists()) {
try {
throw new RuntimeException("Cannot delete file: " + getCanonicalPath(file));
} catch (final Throwable e) {
Logs.error(FileUtil.class, e);
}
}
}
}
}
}
}
/**
* Add the file to be deleted on exit. If the file is a directory the
* directory and it's contents will be deleted.
*
* DON'T use in web applications
*
* @param file The file or directory to delete.
*/
public static void deleteFileOnExit(final File file) {
synchronized (deleteFilesOnExit) {
if (deleteFilesOnExitThread == null) {
deleteFilesOnExitThread = new Thread(new Runnable() {
@Override
public void run() {
synchronized (deleteFilesOnExit) {
for (final File file : deleteFilesOnExit) {
if (file.exists()) {
if (file.isFile()) {
Logs.debug(FileUtil.class, "Deleting file: " + file.getAbsolutePath());
file.delete();
} else {
Logs.debug(FileUtil.class, "Deleting directory: " + file.getAbsolutePath());
deleteDirectory(file);
}
}
}
}
}
});
Runtime.getRuntime().addShutdownHook(deleteFilesOnExitThread);
}
deleteFilesOnExit.add(file);
}
}
/**
* Delete the files that match the java regular expression.
*
* @param directory The directory.
* @param pattern The regular expression to match
*/
public static void deleteFiles(final File directory, final String pattern) {
final File[] files = directory.listFiles(new PatternFilenameFilter(pattern));
for (final File file : files) {
file.delete();
}
}
public static void deleteFilesOlderThan(final File directory, final Date date) {
final long time = date.getTime();
deleteFilesOlderThan(directory, time);
}
public static void deleteFilesOlderThan(final File directory, final long age) {
if (directory.exists() && directory.isDirectory()) {
for (final File file : directory.listFiles()) {
if (file.isDirectory()) {
deleteFilesOlderThan(file, age);
} else if (file.isFile()) {
if (file.lastModified() < age) {
if (!file.delete()) {
Logs.error(FileUtil.class, "Unable to delete file: " + file);
}
}
}
}
}
}
public static FileFilter filterFilename(final String fileName) {
return (file) -> {
if (file == null || fileName == null) {
return false;
} else {
final String name = file.getName();
return fileName.equals(name);
}
};
}
public static String fromSafeName(final String fileName) {
final int len = fileName.length();
final StringBuilder decoded = new StringBuilder(len);
for (int i = 0; i < len; i++) {
char ch = fileName.charAt(i);
if (ch == '%') {
final String hex = fileName.substring(i + 1, i + 3);
ch = (char)Integer.parseInt(hex, 16);
i += 2;
}
decoded.append(ch);
}
return decoded.toString();
}
public static String getBaseName(final File file) {
final String fileName = getFileName(file);
return getBaseName(fileName);
}
public static String getBaseName(final String name) {
final String fileName = getFileName(name);
final int dotIndex = fileName.lastIndexOf('.');
if (dotIndex != -1) {
return fileName.substring(0, dotIndex);
} else {
return fileName;
}
}
public static String getCanonicalPath(final File file) {
try {
return file.getCanonicalPath();
} catch (final IOException e) {
return file.getAbsolutePath();
}
}
public static String getCanonicalPath(final String fileName) {
final File file = new File(fileName);
return getCanonicalPath(file);
}
public static File getCurrentDirectory() {
return getFile(System.getProperty("user.dir"));
}
public static List<File> getDirectories(final File directory) {
final List<File> directories = new ArrayList<>();
final File[] files = directory.listFiles();
if (files != null) {
for (final File file : files) {
if (file.isDirectory()) {
directories.add(file);
}
}
}
return directories;
}
public static File getDirectory(final File parent, final String path) {
final File file = new File(parent, path);
if (!file.exists()) {
file.mkdirs();
}
return getFile(file);
}
public static File getDirectory(final String path) {
final File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
return file;
}
public static List<String> getDirectoryNames(final File directory) {
final List<String> directories = new ArrayList<>();
final File[] files = directory.listFiles();
if (files != null) {
for (final File file : files) {
if (file.isDirectory()) {
final String fileName = getFileName(file);
directories.add(fileName);
}
}
}
return directories;
}
public static File getFile(final File file) {
try {
return file.getCanonicalFile();
} catch (final IOException e) {
throw new RuntimeException("Unable to get file " + file, e);
}
}
public static File getFile(final File file, final String path) {
final File childFile = new File(file, path);
return getFile(childFile);
}
public static File getFile(final Resource resource) {
if (resource instanceof FileSystemResource) {
final FileSystemResource fileResource = (FileSystemResource)resource;
return fileResource.getFile();
} else {
final String fileName = resource.getFilename();
final String ext = getFileNameExtension(fileName);
final File file = newTempFile(fileName, "." + ext);
copy(resource.getInputStream(), file);
file.deleteOnExit();
return file;
}
}
public static File getFile(final String path) {
if (path == null) {
return null;
} else {
final File file = new File(path);
return getFile(file);
}
}
public static File getFile(URI uri) {
final String scheme = uri.getScheme();
if ("folderconnection".equalsIgnoreCase(scheme)) {
final String authority = uri.getAuthority();
final String connectionName = UrlUtil.percentDecode(authority);
final String path = uri.getPath();
File file = null;
for (final FolderConnectionRegistry registry : FileConnectionManager.get()
.getConnectionRegistries()) {
final FolderConnection connection = registry.getConnection(connectionName);
if (connection != null) {
final File directory = connection.getFile();
file = new File(directory, path);
if (file.exists()) {
return getFile(file);
}
}
}
return file;
} else if ("file".equalsIgnoreCase(scheme)) {
try {
uri = new URI(scheme, uri.getPath(), null);
} catch (final URISyntaxException e) {
}
return getFile(new File(uri));
} else {
throw new IllegalArgumentException("file URL expected: " + uri);
}
}
public static File getFile(final URL url) {
if (url == null) {
return null;
} else {
final URI uri = UrlUtil.getUri(url);
return getFile(uri);
}
}
public static String getFileAsString(final File file) {
final StringWriter out = new StringWriter();
try {
copy(file, out);
} catch (final IOException e) {
throw new RuntimeException("Unable to copy file: " + file);
}
return out.toString();
}
public static String getFileAsString(final String fileName) {
final File file = new File(fileName);
return getFileAsString(file);
}
public static List<String> getFileBaseNamesByExtension(final File directory,
final String extension) {
final List<String> names = new ArrayList<>();
final List<File> files = getFilesByExtension(directory, extension);
for (final File file : files) {
final String baseName = getBaseName(file);
names.add(baseName);
}
return names;
}
public static String getFileName(final File file) {
if (file == null) {
return null;
} else {
String fileName = file.getName();
if (!Property.hasValue(fileName)) {
fileName = file.getPath().replaceAll("\\\\$", "");
}
return fileName;
}
}
public static String getFileName(String fileName) {
fileName = fileName.replaceAll("\\+", "/");
final int slashIndex = fileName.lastIndexOf('/');
if (slashIndex != -1) {
return fileName.substring(slashIndex + 1);
} else {
return fileName;
}
}
public static String getFileNameExtension(final File file) {
final String fileName = getFileName(file);
return getFileNameExtension(fileName);
}
public static String getFileNameExtension(final String fileName) {
final int dotIndex = fileName.lastIndexOf('.');
if (dotIndex != -1) {
return fileName.substring(dotIndex + 1);
} else {
return "";
}
}
public static List<String> getFileNameExtensions(final File file) {
final String fileName = file.getName();
return getFileNameExtensions(fileName);
}
public static List<String> getFileNameExtensions(final String fileName) {
final List<String> extensions = new ArrayList<>();
if (Property.hasValue(fileName)) {
int startIndex = fileName.indexOf("/");
if (startIndex == -1) {
startIndex = 0;
}
for (int dotIndex = fileName.indexOf('.', startIndex); dotIndex > 0; dotIndex = fileName
.indexOf('.', startIndex)) {
dotIndex++;
final String extension = fileName.substring(dotIndex);
extensions.add(extension);
startIndex = dotIndex;
}
}
return extensions;
}
public static String getFileNamePrefix(final File file) {
final String fileName = getFileName(file);
return getBaseName(fileName);
}
public static List<String> getFileNames(final File directory, final FilenameFilter filter) {
final List<String> names = new ArrayList<>();
final File[] files = directory.listFiles(filter);
if (files != null) {
for (final File file : files) {
final String name = getFileName(file);
names.add(name);
}
}
return names;
}
public static List<String> getFileNamesByExtension(final File directory, final String extension) {
final FilenameFilter filter = new ExtensionFilenameFilter(extension);
return getFileNames(directory, filter);
}
public static List<File> getFiles(final File directory, final FilenameFilter filter) {
if (directory.isDirectory()) {
final File[] files = directory.listFiles(filter);
if (files == null) {
return Collections.emptyList();
} else {
return Arrays.asList(files);
}
} else {
return Collections.emptyList();
}
}
public static List<File> getFilesByExtension(final File directory, final String... extensions) {
final ExtensionFilenameFilter filter = new ExtensionFilenameFilter(extensions);
return getFiles(directory, filter);
}
/**
* Get a new file object with the current extension replaced with the new extension.
*
* @param file
* @param extension
* @return
*/
public static File getFileWithExtension(final File file, final String extension) {
final File parentFile = getFile(file).getParentFile();
final String baseName = FileUtil.getFileNamePrefix(file);
final String newFileName = baseName + "." + extension;
if (parentFile == null) {
return getFile(newFileName);
} else {
return new File(parentFile, newFileName);
}
}
public static FileInputStream getInputStream(final File file) {
try {
return new FileInputStream(file);
} catch (final FileNotFoundException e) {
throw new RuntimeException("Unble to open file: " + file, e);
}
}
public static FileReader getReader(final File file) {
try {
return new FileReader(file);
} catch (final FileNotFoundException e) {
throw new IllegalArgumentException("File not found: " + file, e);
}
}
/**
* Return the relative path of the file from the parentDirectory. For example
* the relative path of c:\Data\Files\file1.txt and c:\Data would be
* Files\file1.txt.
*
* @param parentDirectory The parent directory.
* @param file The file to return the relative path for.
* @return The relative path.
* @throws IOException If an I/O error occurs.
*/
public static String getRelativePath(final File parentDirectory, final File file) {
final String parentPath = getCanonicalPath(parentDirectory);
final String filePath = getCanonicalPath(file);
if (filePath.startsWith(parentPath)) {
return filePath.substring(parentPath.length() + 1);
}
return filePath;
}
public static File getSafeFileName(final File directory, final String name) {
final String fileName = getSafeFileName(name);
final File file = new File(directory, fileName);
return file;
}
public static String getSafeFileName(final String name) {
return name.replaceAll("[^a-zA-Z0-9\\-_ \\.]", "_");
}
public static String getString(final File file) {
if (file.exists()) {
final FileReader in = getReader(file);
return getString(in);
} else {
return null;
}
}
public static String getString(final InputStream in) {
final Reader reader = FileUtil.newUtf8Reader(in);
return getString(reader);
}
public static String getString(final Reader reader) {
try {
final StringWriter out = new StringWriter();
copy(reader, out);
return out.toString();
} finally {
closeSilent(reader);
}
}
public static String getString(final Reader reader, final boolean close) {
try {
final StringWriter out = new StringWriter();
copy(reader, out);
return out.toString();
} finally {
if (close) {
closeSilent(reader);
}
}
}
public static String getString(final Reader reader, final int count) {
try {
final StringWriter out = new StringWriter();
copy(reader, out, count);
return out.toString();
} finally {
closeSilent(reader);
}
}
public static File getUrlFile(final String url) {
if (Property.hasValue(url)) {
if (url.startsWith("file:") || url.startsWith("folderconnection:")) {
try {
final URI uri = new URI(url);
return getFile(uri);
} catch (final URISyntaxException e) {
Exceptions.throwUncheckedException(e);
}
} else {
return getFile(url);
}
}
return null;
}
public static File getUserHomeDirectory() {
final String userHome = System.getProperty("user.home");
return new File(userHome);
}
public static Writer getWriter(final File file) {
try {
return new FileWriter(file);
} catch (final IOException e) {
throw new IllegalArgumentException("Unable to open file " + file, e);
}
}
public static boolean isRoot(File file) {
file = getFile(file);
final String name = file.getName();
return "".equals(name);
}
public static List<File> listFilesTree(final File file, final FileFilter filter) {
final List<File> matchingFiles = new ArrayList<>();
listFilesTree(matchingFiles, file, filter);
return matchingFiles;
}
public static void listFilesTree(final List<File> matchingFiles, final File file,
final FileFilter filter) {
if (file != null) {
if (file.isDirectory()) {
final File[] files = file.listFiles();
if (files != null) {
for (final File childFile : files) {
listFilesTree(matchingFiles, childFile, filter);
}
}
} else if (file.isFile()) {
if (filter.accept(file)) {
matchingFiles.add(file);
}
}
}
}
public static List<File> listVisibleFiles(final File file) {
if (file != null && file.isDirectory()) {
final List<File> visibleFiles = new ArrayList<>();
final File[] files = file.listFiles();
if (files != null) {
for (final File childFile : files) {
if (!childFile.exists() || !childFile.isHidden()) {
visibleFiles.add(childFile);
}
}
}
return visibleFiles;
}
return Collections.emptyList();
}
public static List<File> listVisibleFiles(final File file, final FileFilter filter) {
if (file != null && file.isDirectory()) {
final List<File> visibleFiles = new ArrayList<>();
final File[] files = file.listFiles(filter);
if (files != null) {
for (final File childFile : files) {
if (!childFile.exists() || !childFile.isHidden()) {
visibleFiles.add(childFile);
}
}
}
return visibleFiles;
}
return Collections.emptyList();
}
public static File newFile(final Object value) {
if (value == null) {
return null;
} else if (value instanceof File) {
return getFile((File)value);
} else if (value instanceof URL) {
return getFile((URL)value);
} else if (value instanceof URI) {
return getFile((URI)value);
} else if (value instanceof Resource) {
return getFile((Resource)value);
} else {
final String string = DataTypes.toString(value);
return getFile(string);
}
}
public static OutputStream newOutputStream(final File file) {
try {
return new FileOutputStream(file);
} catch (final FileNotFoundException e) {
throw Exceptions.wrap(e);
}
}
/**
* Construct a new new temporary directory.
*
* @param prefix The file name prefix.
* @param suffix The file name suffix.
* @return The temportary directory.
* @throws IOException If there was an exception creating the directory.
*/
public static File newTempDirectory(final String prefix, final String suffix) {
try {
final File file = File.createTempFile(prefix, suffix);
if (!file.delete()) {
throw new IOException("Cannot delete temporary file");
}
if (!file.mkdirs()) {
throw new IOException("Cannot create temporary directory");
}
file.deleteOnExit();
return file;
} catch (final Exception e) {
return Exceptions.throwUncheckedException(e);
}
}
public static File newTempFile(final String prefix, final String suffix) {
try {
final File file = File.createTempFile(prefix, suffix);
return file;
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
public static InputStreamReader newUtf8Reader(final InputStream in) {
return new InputStreamReader(in, StandardCharsets.UTF_8);
}
public static OutputStreamWriter newUtf8Writer(final File file) {
try {
return new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8);
} catch (final FileNotFoundException e) {
return Exceptions.throwUncheckedException(e);
}
}
public static OutputStreamWriter newUtf8Writer(final OutputStream out) {
return new OutputStreamWriter(out, StandardCharsets.UTF_8);
}
public static String readString(final DataInputStream in, final int length) throws IOException {
final char[] characters = new char[length];
for (int i = 0; i < characters.length; i++) {
characters[i] = in.readChar();
}
return new String(characters);
}
public static String toSafeName(final String name) {
if (name == null) {
return "";
} else {
final int len = name.length();
final StringBuilder encoded = new StringBuilder(len);
for (int i = 0; i < len; i++) {
final char ch = name.charAt(i);
if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9' || ch == '-'
|| ch == ',' || ch == '.' || ch == '_' || ch == '~' || ch == ' ') {
encoded.append(ch);
} else {
encoded.append('%');
if (ch < 0x10) {
encoded.append('0');
}
encoded.append(Integer.toHexString(ch));
}
}
return encoded.toString();
}
}
public static URL toUrl(final File file) {
try {
final URI uri = file.toURI();
return uri.toURL();
} catch (final MalformedURLException e) {
throw new IllegalArgumentException("Cannot get file url " + file, e);
}
}
public static String toUrlString(final File file) {
return toUrl(file).toString();
}
public static String toUrlString(final String path) {
final File file = getFile(path);
return toUrlString(file);
}
/**
* Construct a new TestFileUtil.
*/
private FileUtil() {
}
}