package edu.washington.escience.myria.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.security.AccessControlException;
/**
* Filesystem util methods.
* */
public final class FSUtils {
/** A short amount of time to sleep waiting for filesystem events. */
public static final int SHORT_SLEEP_MILLIS = 100;
/** Block size for file copying. */
public static final int BLOCK_SIZE_BYTES = 1024;
/**
* Delete the pathToDirectory. Return only if the directory is actually get deleted on the disk.
*
* @param pathToDirectory the directory to be deleted.
*/
public static void blockingDeleteDirectory(final String pathToDirectory) {
final File testBaseFolderF = new File(pathToDirectory);
try {
FSUtils.deleteFileFolder(testBaseFolderF);
} catch (final IOException e) {
e.printStackTrace();
}
boolean finishClean = false;
while (!finishClean) {
finishClean = !testBaseFolderF.exists();
if (!finishClean) {
try {
Thread.sleep(SHORT_SLEEP_MILLIS);
} catch (final InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
}
}
/**
* @param source the source file or folder
* @param dest the dest file or folder
* @param override if to override if the dest exists.
* @throws IOException if any error occurs.
*/
public static void copyFileFolder(final File source, final File dest, final boolean override)
throws IOException {
if (dest.exists()) {
if (!override) {
return;
} else {
deleteFileFolder(dest);
}
}
if (source.isDirectory()) {
dest.mkdirs();
final File[] children = source.listFiles();
for (final File child : children) {
copyFileFolder(child, new File(dest.getAbsolutePath() + "/" + child.getName()), override);
}
} else {
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(source);
out = new FileOutputStream(dest);
// Transfer bytes from in to out
final byte[] buf = new byte[BLOCK_SIZE_BYTES];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}
/**
* @param f the file or folder to be deleted.
* @throws IOException if any error occurs.
* */
public static void deleteFileFolder(final File f) throws IOException {
if (!f.exists()) {
return;
}
if (f.isDirectory()) {
for (final File c : f.listFiles()) {
deleteFileFolder(c);
}
}
if (!f.delete()) {
throw new FileNotFoundException("Failed to delete file: " + f);
}
}
/**
* Write the content to the file.
*
* @param f the file.
* @param content the content.
* @throws IOException if any error occurs.
* */
public static void writeFile(final File f, final String content) throws IOException {
final FileOutputStream o = new FileOutputStream(f);
o.write(content.getBytes());
o.close();
}
/**
* Reset the file length of a file.
*
* @param f the file.
* @param desired the file length desired.
* @throws IOException if any error occurs.
* */
public static void resetFileSize(final File f, final long desired) throws IOException {
boolean ok = f.length() == desired;
if (!ok) {
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile(f, "rws");
raf.setLength(desired);
} finally {
if (raf != null) {
raf.close();
}
}
}
}
/**
* Check whether the specified filepath is a file and is readable.
*
* @param filepath the path to the file.
* @throws FileNotFoundException if the specified filepath does not exist or is not a file.
*/
public static void checkFileReadable(final String filepath) throws FileNotFoundException {
File f = new File(filepath);
if (!f.exists()) {
throw new FileNotFoundException(filepath + " could not be found");
}
if (!f.isFile()) {
throw new FileNotFoundException(filepath + " is not a file");
}
if (!f.canRead()) {
throw new AccessControlException(filepath + " could not be read");
}
}
/**
* util classes are not instantiable.
* */
private FSUtils() {}
}