package com.idega.util;
/**
* Title: idega Framework
* Description:
* Copyright: Copyright (c) 2001
* Company: idega
* @author <a href=mailto:"tryggvi@idega.is">Tryggvi Larusson</a>
* @version 1.0
*/
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
public class FileUtil {
public static final char UNIX_FILE_SEPARATOR = '/';
public static final char WINDOWS_FILE_SEPARATOR = '\\';
public static final String BACKUP_SUFFIX = "backup~";
private static String systemSeparatorString = "file.separator";
private FileUtil() {
// empty
}
public static void createFileAndFolder(String path,String fileNameWithoutFullPath){
createFolder(path);
String filePath = getFileNameWithPath(path,fileNameWithoutFullPath);
createFile(filePath);
}
/**
* Creates a folder if it does not exists. Returns true if creation successful, false otherwise
*/
public static boolean createFolder(String path){
File folder = new File(path);
if(!folder.exists()){
folder.mkdirs();
return true;
}
return false;
}
public static boolean createFile(String fileNameWithFullPath){
File file = new File(fileNameWithFullPath);
try{
return file.createNewFile();
}
catch(IOException ex){
return false;
}
}
/**
* Creates a file or folder if not existent.
* If true is returned the file exists else something went wrong.
*
* @param file
* @return true if everything is fine else false
* @author thomas
*/
public static boolean createFileIfNotExistent(File file) {
if (file.exists()) {
// nothing to do
return true;
}
// create parent directories (or the folder itself) if necessary
boolean isDirectory = file.isDirectory();
File parentFile = (isDirectory) ? file : file.getParentFile();
if (! parentFile.exists()) {
if (! parentFile.mkdirs()) {
return false;
}
}
// create file (if it is not a directory)
if (! isDirectory) {
try {
file.createNewFile();
}
catch (IOException ex) {
return false;
}
}
if (file.isDirectory()) {
System.out.println("Weser");
}
// everything is okay
return true;
}
/**
* Gets the System wide path separator
*/
public static String getFileSeparator(){
return System.getProperty(systemSeparatorString);
}
public static String getFileNameWithPath(String path,String fileNameWithoutFullPath){
return path+getFileSeparator()+fileNameWithoutFullPath;
}
/**
* Returns a File Object. Creates the File and parent folders if they do not exist.
*/
public static File getFileAndCreateIfNotExists(String path,String fileNameWithoutFullPath)throws IOException{
createFolder(path);
String fullPath = getFileNameWithPath(path,fileNameWithoutFullPath);
return getFileAndCreateIfNotExists(fullPath);
}
/**
* Returns a File Object. Creates the File if it does not exist.
*/
public static File getFileAndCreateIfNotExists(String fileNameWithFullPath)throws IOException{
File file = new File(fileNameWithFullPath);
file.createNewFile();
return file;
}
/**
* Returns a File Object. Creates the File and recursively all the directory structure prefixing the file
* if it does not exist.
*/
public static File getFileAndCreateRecursiveIfNotExists(String fileNameWithFullPath)throws IOException{
String separator = File.separator;
int index = fileNameWithFullPath.lastIndexOf(separator);
String path = fileNameWithFullPath.substring(0,index);
String name = fileNameWithFullPath.substring(index+1);
File dirs = null;
try{
dirs = new File(path);
dirs.mkdirs();
}
catch(Exception e){
e.printStackTrace();
}
File file = null;
if(dirs!=null) {
file = new File(dirs,name);
}
else {
file = new File(name);
}
file.createNewFile();
return file;
}
/**
* Deletes a File Object.
*/
public static File delete(File file){
file.delete();
return file;
}
/**
* Deletes a File from an url.
*/
public static boolean delete(String fileNameWithFullPath){
File file = new File(fileNameWithFullPath);
return file.delete();
}
/*
* streams an inputstream to a file
*/
public static File streamToFile( InputStream input, String filePath, String fileName){
File file = null;
try{
if(input!=null){
input.available();//this casts an ioexception if the stream is null
file = getFileAndCreateIfNotExists(filePath,fileName);
FileOutputStream fileOut = new FileOutputStream(file);
byte buffer[]= new byte[1024];
int noRead = 0;
noRead = input.read( buffer, 0, 1024 );
//Write out the stream to the file
while ( noRead != -1 ){
fileOut.write( buffer, 0, noRead );
noRead = input.read( buffer, 0, 1024 );
}
fileOut.flush();
fileOut.close();
}
}
catch(IOException e){
//e.printStackTrace(System.err);
System.err.println("FileUtil : Error or skipping (for folders) writing to file");
}
finally{
try{
if(input!=null) {
input.close();
}
}
catch(IOException e){
//e.printStackTrace(System.err);
System.err.println("FileUtil : Error closing the inputstream");
}
}
return file;
}
/**
* Deletes content of folder.
* !! Be careful !!
* Returns also false if the specified path doesn't exist.
* @author thomas
*/
public static boolean deleteContentOfFolder(String path) {
return FileUtil.deleteContentOfFolder(new File(path));
}
/**
* Deletes content of folder.
* !! Be careful !!
* Returns also false if the specified path doesn't exist.
* @author thomas
*/
public static boolean deleteContentOfFolder(File folder) {
boolean result = true;
boolean successful = true;
if (folder.exists() && folder.isDirectory()) {
File children[] = folder.listFiles();
for (int i = 0; i < children.length; i++) {
successful = FileUtil.deleteFileAndChildren(children[i]);
if (! successful) {
result = false;
}
}
return result;
}
return false;
}
/** Deletes all files and folders in the specified folder that are older than the
* specified time in milliseconds. Only the time of the files and folders in the specified folder
* are checked not the time of files or folders that belong to subfolders.
* !! Be careful !!
* @param folderPath
* @param timeInMillis
* @author thomas
*/
public static void deleteAllFilesAndFolderInFolderOlderThan(String folderPath, long timeInMillis) {
FileUtil.deleteAllFilesAndFolderInFolderOlderThan(new File(folderPath), timeInMillis);
}
/** Deletes all files and folders in the specified folder that are older than the
* specified time in milliseconds. Only the time of the files and folders in the specified folder
* are checked not the time of files or folders that belong to subfolders.
* !! Be careful !!
* @param folderPath
* @param timeInMillis
* @author thomas
*/
public static void deleteAllFilesAndFolderInFolderOlderThan(File folder, long timeInMillis) {
if (! folder.exists()) {
return;
}
File[] files = folder.listFiles();
if(files!=null){
long currentTime = System.currentTimeMillis();
for (int i = 0; i < files.length; i++) {
File file = files[i];
long modifiedFile = file.lastModified();
if (currentTime - modifiedFile > timeInMillis) {
FileUtil.deleteFileAndChildren(file);
}
}
}
}
/**
* Deletes file and children.
* !! Be careful !!
* @author thomas
*/
public static boolean deleteFileAndChildren(File file) {
boolean successful = true;
if (file.exists()) {
if (file.isDirectory()) {
File children[] = file.listFiles();
for (int i = 0; i < children.length; i++) {
successful = FileUtil.deleteFileAndChildren(children[i]);
if (! successful) {
return false;
}
}
// folder is now empty
}
return file.delete();
}
return true;
}
/**
* deletes entire contents of a folder. Returns true if deletion successful, false otherwise
*
* comment added by thomas:
* doesn't delete folders that contain nonempty folders
*/
public static boolean deleteAllFilesInDirectory(String path){
File folder = new File(path);
if(folder!=null && folder.exists() && folder.isDirectory()){
File[] files = folder.listFiles();
if(files!=null){
for (int i = 0; i < files.length; i++) {
files[i].delete();
}
}
return true;
}
return false;
}
/**
* Returns the entire contents of a folder. Returns NULL if no files exist.
*/
public static File[] getAllFilesInDirectory(String path){
File folder = new File(path);
if(folder.exists()){
return folder.listFiles();
}
return null;
}
/**
* Returns only files of a folder but not folder inside the folder. Returns null if no folder exist.
* @param path
* @return
* @author thomas
*/
public static List getFilesInDirectory(File folder) {
if (folder.exists()) {
FileFilter filter = new FileFilter() {
public boolean accept(File file) {
return file.isFile();
}
};
File[] folders = folder.listFiles(filter);
return Arrays.asList(folders);
}
return null;
}
/**
* Returns folders of a folder. Returns null if no folders exist.
* @param path
* @return
* @author thomas
*/
public static List getDirectoriesInDirectory(File folder) {
if (folder.exists()) {
FileFilter filter = new FileFilter() {
public boolean accept(File file) {
return file.isDirectory();
}
};
File[] folders = folder.listFiles(filter);
return Arrays.asList(folders);
}
return null;
}
public static List getLinesFromFile(File fromFile) throws IOException{
List strings = new ArrayList();
FileReader reader;
LineNumberReader lineReader = null;
reader = new FileReader(fromFile);
lineReader = new LineNumberReader(reader);
lineReader.mark(1);
while (lineReader.read() != -1) {
lineReader.reset();
strings.add(lineReader.readLine());
lineReader.mark(1);
}
return strings;
}
/** Gets the lines from a file and return the as a vector of strings **/
public static List getLinesFromFile(String pathAndFile) throws IOException{
File f = new File(pathAndFile);
return getLinesFromFile(f);
}
/** Uses getLinesFromFile and returns them in a string with "\n" between them **/
public static String getStringFromFile(String pathAndFile) throws IOException{
StringBuffer buffer = new StringBuffer();
List list = getLinesFromFile(pathAndFile);
if ( list != null ) {
Iterator iter = list.iterator();
while (iter.hasNext()) {
buffer.append((String) iter.next());
buffer.append('\n');
}
}
return buffer.toString();
}
/** Gets a file relative to the specified file according the specified path.
* Note: Works with windows or unix separators.
* E.g.
* file = "/a/b/c.txt" (is a file)
* path = "../d/e.txt"
* returns file = "/a/d/e.txt"
* E.g.
* file = "/a/b/c" (is a folder)
* path = "../d/e.txt"
* returns file = "/a/b/d/e.txt"
* @param file
* @param relativePath
* @return
* @author thomas
*/
public static File getFileRelativeToFile(File file, String relativePath) {
char[] separatorsChar = {UNIX_FILE_SEPARATOR , WINDOWS_FILE_SEPARATOR};
String separators = new String(separatorsChar);
File result = file;
if (result.isFile()) {
result = result.getParentFile();
}
StringTokenizer tokenizer = new StringTokenizer(relativePath, separators);
while (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
if (".".equals(token)) {
// do nothing
}
else if ("..".equals(token)) {
// go to parent
result = result.getParentFile();
}
else {
// go to child
result = new File(result, token);
}
}
return result;
}
/** Creates a file plus folders relative to the specified (existing) file according the specified path.
* Note: Works with windows or unix separators.
* + returns the specified file if the path is null or empty
* + returns a folder if the specified path ends with a separator
* E.g.
* file = "/a/b/c.txt" (is a file)
* path = "../d/e.txt"
* returns file = "/a/d/e.txt"
* E.g.
* file = "/a/b/c" (is a folder)
* path = "../d/e.txt"
* returns file = "/a/b/d/e.txt"
* @param file
* @param relativePath
* @return
* @author thomas
*/
public static File createFileRelativeToFile(File file, String relativePath) throws IOException {
char[] separatorsChar = {UNIX_FILE_SEPARATOR ,WINDOWS_FILE_SEPARATOR};
String separators = new String(separatorsChar);
if (! file.exists()) {
throw new IOException("[FileUtil] File does not exist: "+ file.getPath());
}
if (relativePath == null) {
return file;
}
int length = relativePath.length();
if (length <= 0) {
// relativePath is empty
return file;
}
char lastCharacter = relativePath.charAt(--length);
// if the relative path ends with a separator create a folder!
// e.g. relative path is "/a/b/" that is ends with a separator
boolean resultShouldBeAFolder = separators.indexOf(lastCharacter) != -1;
File result = file;
if (result.isFile()) {
result = result.getParentFile();
}
StringTokenizer tokenizer = new StringTokenizer(relativePath, separators);
boolean hasMoreTokens = tokenizer.hasMoreTokens();
while (hasMoreTokens) {
String token = tokenizer.nextToken();
hasMoreTokens = tokenizer.hasMoreTokens();
if (".".equals(token)) {
// do nothing
}
else if ("..".equals(token)) {
// go to parent
result = result.getParentFile();
}
else {
// do something
result = new File(result, token);
if (! result.exists()) {
// do something
boolean success = false;
if (hasMoreTokens || resultShouldBeAFolder) {
// create a folder
success = result.mkdir();
}
else {
// it is a file
success = result.createNewFile();
}
if (! success) {
throw new IOException("[FileUtil] File could not be created: " + result.getPath());
}
}
}
}
return result;
}
/** This uses a BufferInputStream and an URLConnection to get an URL and return it as a String **/
public static String getStringFromURL(String uri){
StringBuffer buffer = new StringBuffer("");
String line;
BufferedInputStream bin;
BufferedReader in;
URL url;
try {
url = new URL(uri);
bin = new BufferedInputStream(url.openStream());
in = new BufferedReader(new InputStreamReader(bin));
//Put the contents in a string
while ((line = in.readLine()) != null) {
buffer.append(line);
buffer.append('\n');
}
in.close();
}
catch(MalformedURLException mue) { // URL c'tor
return "MalformedURLException: Site not available or wrong url";
}
catch(IOException ioe) { // Stream constructors
return "IOException: Site not available or wrong url";
}
return buffer.toString();
}
/**
* Works well to e.g. save images from a website to a file
* @param uri
* @param file
*/
public static void createFileFromURL(String uri,File file){
try {
URL url = new URL(uri);
BufferedInputStream input = new BufferedInputStream(url.openStream());
FileOutputStream output = new FileOutputStream(file);
byte buffer[]= new byte[1024];
int noRead = 0;
noRead = input.read( buffer, 0, 1024 );
//Write out the stream to the file
while ( noRead != -1 ){
output.write( buffer, 0, noRead );
noRead = input.read( buffer, 0, 1024 );
}
output.flush();
output.close();
}
catch(MalformedURLException mue) { // URL c'tor
//return "MalformedURLException: Site not available or wrong url";
mue.printStackTrace();
}
catch(IOException ioe) { // Stream constructors
//return "IOException: Site not available or wrong url";
ioe.printStackTrace();
}
}
/** uses getLinesFromFile and cuts the lines into java.util.StringTokenizer and returns them in a vector **/
public static List getCommaSeperatedTokensFromLinesFromFile(String pathAndFile, String seperatorToken) throws IOException{
List lines = getLinesFromFile(pathAndFile);
List tokens = new ArrayList();
String item;
Iterator iter = lines.iterator();
StringTokenizer tokenizer;
while (iter.hasNext()) {
item = (String) iter.next();
tokenizer = new StringTokenizer(item,seperatorToken);
tokens.add(tokenizer);
}
return tokens;
}
/**
* Copies the specified sourcefile (source folder) to a backup file (backup folder), creates always a new
* backup file without destroying an existing old backup file
* by adding a number to the suffix if necessary.
* e.g. hello.txt -> hello.txt.backup~
* e.g. hello.txt -> hello.txt.1_backup~
*
* @param sourceFile
* @throws IOException
* @throws FileNotFoundException
* @author thomas
*/
public static void backup(File sourceFile) throws FileNotFoundException, IOException {
FileUtil.backupToFolder(sourceFile, null);
}
/**
* Copies the specified sourcefile (source folder) to a backup file (backup folder) into the specified backup folder,
* creates always a new
* backup file without destroying an existing old backup file
* by adding a number to the suffix if necessary.
* e.g. hello.txt -> hello.txt.backup~
* e.g. hello.txt -> hello.txt.1_backup~
*
* @param sourceFile
* @param destination
* @throws IOException
* @throws FileNotFoundException
* @author thomas
*/
public static void backupToFolder(File sourceFile, File destination) throws FileNotFoundException, IOException {
String name = sourceFile.getName();
if (destination == null) {
destination = sourceFile.getParentFile();
if (destination == null) {
// can not copy the root
throw new IOException("[FileUtil] Can not backup root");
}
}
else if (! destination.exists()) {
if (! destination.mkdirs()) {
throw new IOException("[FileUtil] Can not create backup destination folder: " + destination.getAbsolutePath());
}
}
StringBuffer buffer = null;
File backupFile = null;
int i = 0;
do {
buffer = new StringBuffer(name);
buffer.append(".");
if (i > 0) {
buffer.append(i).append("_");
}
buffer.append(BACKUP_SUFFIX);
backupFile = new File(destination, buffer.toString());
i++;
}
while (backupFile.exists());
if (sourceFile.isDirectory()) {
copyDirectoryRecursivelyKeepTimestamps(sourceFile, backupFile);
}
else {
copyFileKeepTimestamp(sourceFile, backupFile);
}
}
public static void copyFile(File sourceFile,String newFileName)throws java.io.FileNotFoundException,java.io.IOException{
File newFile = new File(newFileName);
copyFile(sourceFile,newFile);
}
public static void copyFileKeepTimestamp(File sourceFile, File newFile) throws FileNotFoundException, IOException {
FileUtil.copyFile(sourceFile, newFile);
long oldTimestamp = sourceFile.lastModified();
newFile.setLastModified(oldTimestamp);
}
public static void copyFile(File sourceFile,File newFile)throws java.io.FileNotFoundException,java.io.IOException{
java.io.FileInputStream input = new java.io.FileInputStream(sourceFile);
if(!newFile.exists()){
newFile.createNewFile();
}
java.io.FileOutputStream output = new FileOutputStream(newFile);
byte buffer[]= new byte[1024];
int noRead = 0;
noRead = input.read( buffer, 0, 1024 );
//Write out the stream to the file
while ( noRead != -1 ){
output.write( buffer, 0, noRead );
noRead = input.read( buffer, 0, 1024 );
}
output.flush();
output.close();
}
/**
* Gunzips one file from the inputGZippedFile and unzips to outputUnZippedFile
*/
public static void gunzipFile(File inputGZippedFile,File outputFile)throws java.io.FileNotFoundException,java.io.IOException{
java.util.zip.GZIPInputStream input = new java.util.zip.GZIPInputStream(new java.io.FileInputStream(inputGZippedFile));
java.io.FileOutputStream output = new java.io.FileOutputStream(outputFile);
//java.util.zip.GZIPOutputStream output = new java.util.zip.GZIPOutputStream();
int buffersize=100;
byte[] buf = new byte[buffersize];
int read = input.read(buf,0,buffersize);
while(read!=-1){
output.write(buf,0,read);
read = input.read(buf,0,buffersize);
}
}
public static void copyDirectoryRecursivelyKeepTimestamps(File inputDirectory,File outputDirectory) throws IOException {
FileUtil.copyDirectoryRecursively(inputDirectory, outputDirectory, true);
}
public static void copyDirectoryRecursively(File inputDirectory, File outputDirectory) throws IOException {
FileUtil.copyDirectoryRecursively(inputDirectory, outputDirectory, false);
}
private static void copyDirectoryRecursively(File inputDirectory,File outputDirectory, boolean keepTimestamp ) throws java.io.IOException{
if(inputDirectory.isDirectory()){
if(!outputDirectory.exists()){
outputDirectory.mkdir();
}
File tempOutFile;
File inputFile;
File[] files = inputDirectory.listFiles();
for (int i = 0; i < files.length; i++) {
inputFile = files[i];
String name = inputFile.getName();
tempOutFile = new File(outputDirectory,name);
if(inputFile.isDirectory()){
copyDirectoryRecursively(inputFile,tempOutFile, keepTimestamp);
}
else if (keepTimestamp) {
FileUtil.copyFileKeepTimestamp(inputFile,tempOutFile);
}
else {
FileUtil.copyFile(inputFile, tempOutFile);
}
}
if (keepTimestamp) {
long oldTimestamp = inputDirectory.lastModified();
outputDirectory.setLastModified(oldTimestamp);
}
}
else{
throw new IOException(inputDirectory.toString()+" is not a directory");
}
}
/**
* Converts a long number representing bytes into human readable format.
* <p>
* This value is mainly for formating values like a file size, memory size
* and so forth, so instead of seeing a large incoherent number you can see
* something like '308.123KB' or '9.68MB'
* @param bytes to format into a string.
* @return human readable format for larger byte counts.
*/
public static String getHumanReadableSize(long bytes) {
long mb = (long) Math.pow(2, 20);
long kb = (long) Math.pow(2, 10);
long gb = (long) Math.pow(2, 30);
long tb = (long) Math.pow(2, 40);
NumberFormat nf = NumberFormat.getNumberInstance();
nf.setMaximumFractionDigits(1);
double relSize = 0.0d;
long abytes = Math.abs(bytes);
String id = "";
if ((abytes / tb) >= 1) {
relSize = (double) abytes / (double) kb;
id = "TB";
}
else if ((abytes / gb) >= 1) {
relSize = (double) abytes / (double) gb;
id = "GB";
} else if ((abytes / mb) >= 1) {
relSize = (double) abytes / (double) mb;
id = "MB";
} else if ((abytes / kb) >= 1) {
relSize = (double) abytes / (double) kb;
id = "KB";
}
else {
relSize = abytes;
id = "b";
}
return nf.format((bytes < 0 ? -1 : 1) * relSize) + " "+id;
}
}