package de.skuzzle.polly.tools;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
public class FileUtil {
public static interface FileActionFilter {
public abstract boolean ignore(String fileName);
}
public final static FileFilter ALL_FILES = new FileFilter() {
@Override
public boolean accept(File pathname) {
return true;
}
};
public final static FileFilter BACKUP_FILES = new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.isDirectory() || pathname.getName().endsWith(".bak");
}
};
private FileUtil() {}
/**
* Reads all data from the provided {@link InputStream} into a String.
* @param in The stream to read the data from.
* @param cs The charset in which the input is encoded.
* @return The input as String.
* @throws IOException If an I/O error occurrs.
*/
public static String readIntoString(InputStream in, String cs) throws IOException {
try (final BufferedReader r = new BufferedReader(new InputStreamReader(in, cs))) {
final StringBuilder b = new StringBuilder();
String line = r.readLine();
if (line != null) {
b.append(line);
}
line = r.readLine();
while (line != null) {
b.append("\n");
b.append(line);
line = r.readLine();
}
return b.toString();
}
}
/**
* Extracts a zip file into a given folder.
*
* @param zip
* The zip file to extract.
* @param to
* The destination. This must be a directory.
* @return
* A list of all extracted files.
* @throws ZipException
* If extracting fails.
* @throws IOException
* If destination is no directory or an IO error occurs during extraction.
*/
public static List<File> unzip (File zip, File to) throws ZipException, IOException {
return unzip(zip, to, null);
}
public static List<File> unzip(File zip, File to, FileActionFilter filter) throws
ZipException, IOException {
if (to.exists() && !to.isDirectory()) {
throw new IOException("destination must be a directory");
} else if (!to.exists()) {
to.mkdirs();
}
List<File> result = new LinkedList<File>();
ZipFile zipFile = new ZipFile(zip);
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
BufferedInputStream in = new BufferedInputStream(
zipFile.getInputStream(entry));
if (filter != null && filter.ignore(entry.getName())) {
continue;
}
File next = new File(to, entry.getName());
result.add(next);
if (!next.isDirectory()) {
next.getParentFile().mkdirs();
}
if (entry.isDirectory()) {
next.mkdirs();
continue;
}
BufferedOutputStream o = new BufferedOutputStream(
new FileOutputStream(next));
byte[] buffer = new byte[2048];
int bytes = in.read(buffer);
while (bytes != -1) {
o.write(buffer, 0, bytes);
bytes = in.read(buffer);
}
o.flush();
o.close();
in.close();
}
zipFile.close();
return result;
}
public static void zip(List<File> files, File destination) throws IOException {
if (destination.isDirectory()) {
throw new IOException("destination must not be a directory");
}
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(destination));
for (File file : files) {
FileUtil.zip(file, out);
}
out.flush();
out.close();
}
public static void zip(File source, File destination) throws IOException {
if (!source.exists()) {
throw new FileNotFoundException(source.getAbsolutePath());
} else if (!source.isDirectory()) {
throw new IOException("source must be a directory");
}
FileUtil.zip(Arrays.asList(source.listFiles()), destination);
}
private static void zip(File source, ZipOutputStream out) throws IOException {
if (source.isDirectory()) {
for (File file : source.listFiles()) {
FileUtil.zip(file, out);
}
} else {
byte[] buffer = new byte[1024];
FileInputStream in = new FileInputStream(source);
out.putNextEntry(new ZipEntry(source.getName()));
int len;
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
out.closeEntry();
in.close();
}
}
public static void deleteFilesRecursive(File destination, FileFilter filter, boolean backup) {
if (destination.isDirectory()) {
for (File f : destination.listFiles(filter)) {
FileUtil.deleteFilesRecursive(f, filter, backup);
}
} else {
destination.delete();
}
}
public static void deleteRecursive(File destination) {
FileUtil.deleteRecursive(destination, FileUtil.ALL_FILES);
}
public static void deleteRecursive(File destination, FileFilter filter) {
if (destination.isDirectory()) {
for (File f : destination.listFiles(filter)) {
FileUtil.deleteRecursive(f, filter);
}
}
destination.delete();
}
public static List<File> copyContent(File source, File destination) throws IOException {
if (!source.isDirectory()) {
throw new IOException("source must be a directory");
}
List<File> sources = Arrays.asList(source.listFiles());
return FileUtil.copy(sources, destination);
}
public static List<File> copy(List<File> sources, File destination)
throws IOException {
if (destination.exists() && !destination.isDirectory()) {
throw new IOException("destination must be a directory");
}
List<File> result = new LinkedList<File>();
for (File file : sources) {
result.addAll(FileUtil.copy(file, destination));
}
return result;
}
public static List<File> copy(File source, File destination) throws IOException {
return FileUtil.copy(source, destination, FileUtil.ALL_FILES);
}
public static List<File> copy(File source, File destination, FileFilter filter)
throws IOException {
if (source.isDirectory() && destination.exists() && !destination.isDirectory()) {
throw new IOException("Can not move a directory into a file");
} else if (!source.isDirectory() && destination.isDirectory()) {
destination = new File(destination, source.getName());
} /*else if (!source.isDirectory() && !destination.isDirectory()) {
String path = destination.getAbsolutePath();
path = path.substring(0, path.length() - destination.getName().length());
destination = new File(path);
}*/
List<File> copiedFiles = new LinkedList<File>();
FileUtil.copy(source, destination, filter, copiedFiles);
return copiedFiles;
}
private static void copy(File source, File destination, FileFilter filter,
List<File> copied) throws IOException {
if (source.isDirectory()) {
//if directory not exists, create it
if(!destination.exists()) {
destination.mkdir();
}
//list all the directory contents
File[] files = source.listFiles(filter);
for (File file : files) {
//construct the src and dest file structure
File srcFile = new File(source, file.getName());
File destFile = new File(destination, file.getName());
//recursive copy
FileUtil.copy(srcFile, destFile, filter, copied);
}
} else {
//if file, then copy it
//Use bytes stream to support all file types
InputStream in = new FileInputStream(source);
OutputStream o = new FileOutputStream(destination);
byte[] buffer = new byte[1024];
int length;
//copy the file content in bytes
while ((length = in.read(buffer)) > 0){
o.write(buffer, 0, length);
}
o.flush();
in.close();
o.close();
}
copied.add(destination);
}
public static boolean waitFor(String file) {
return FileUtil.waitFor(new File(file), 4);
}
public static boolean waitFor(File file, int attempts) {
int i = 0;
while (file.exists() && !file.canWrite() && i++ < attempts) {
try {
Thread.sleep(250);
} catch (InterruptedException ignore) {}
}
return !file.exists() || file.canWrite();
}
public static File createTempDirectory(String prefix, String suffix)
throws IOException {
final File temp = File.createTempFile(prefix, suffix);
if(!(temp.delete())) {
throw new IOException("Could not delete temp file: " +
temp.getAbsolutePath());
}
if(!(temp.mkdir())) {
throw new IOException("Could not create temp directory: " +
temp.getAbsolutePath());
}
return temp;
}
public static File createTempDirectory() throws IOException {
return FileUtil.createTempDirectory("polly_update_",
Long.toString(System.nanoTime()));
}
public static void deleteList(List<File> files) {
for (File file : files) {
if (!file.isDirectory()) {
file.delete();
}
}
for (File file : files) {
if (file.isDirectory()) {
file.delete();
}
}
}
public static File getDirectory(File file) {
if (file.isDirectory()) {
return file;
} else {
String path = file.getAbsolutePath();
path = path.substring(0, path.length() - file.getName().length());
return new File(path);
}
}
}