/*
* Copyright (c) 2012 Diamond Light Source Ltd.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package uk.ac.diamond.scisoft.analysis.utils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.RandomAccessFile;
import java.io.Reader;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
/**
* A class with a collection of file management static utility classes. Several method contents copied from code
* snippets available on the web.
*
* @author Matthew Gerring
*/
public final class FileUtils {
private final static String NEWFOLDER = "New Folder";
/**
*
*/
public static final char BOM; // note this character is the same whether UTF-8, UTF-16BE or UTF-16LE
/**
* Notes on Java behaviour (what I think happens) If a file is read in as UTF-8 or UTF-16BE and a BOM is present it
* is left in. If a file is read in as UTF-16 and a BOM is present it is stripped off If a file is written out as
* UTF-16 a BOM is added. If a file is written out as UTF-8 or UTF-16BE a BOM is not added
*/
static {
byte[] b1 = new byte[3];
b1[0] = (byte) 0xEF;
b1[1] = (byte) 0xBB;
b1[2] = (byte) 0xBF;
String bomstr = " ";
try {
bomstr = new String(b1, 0, 3, "UTF-8");
} catch (Exception any) {
throw new RuntimeException("Could not initialize byte order marker"); // important to do this as odd things
// could happen if it fails
}
BOM = bomstr.charAt(0);
}
/**
* @param parent
* @return boolean
*/
static public final boolean recursiveDelete(File parent) {
if (parent.exists()) {
if (parent.isDirectory()) {
File[] files = parent.listFiles();
for (int ifile = 0; ifile < files.length; ++ifile) {
if (files[ifile].isDirectory()) {
recursiveDelete(files[ifile]);
}
if (files[ifile].exists()) {
files[ifile].delete();
}
}
}
return parent.delete();
}
return false;
}
/**
* @param parent
*/
static public final void deleteContents(File parent) {
if (parent.isDirectory()) {
File[] files = parent.listFiles();
for (int ifile = 0; ifile < files.length; ++ifile) {
if (files[ifile].isDirectory()) {
recursiveDelete(files[ifile]);
}
files[ifile].delete();
}
}
}
/**
* Generates a unique file of the name template or template+an integer
*
* @param dir
* @param template
* @param ext
* @return a unique file.
*/
public static File getUnique(final File dir, final String template, final String ext) {
final String extension = ext != null ? (ext.startsWith(".")) ? ext : "." + ext : null;
final File file = new File(dir, template + extension);
if (!file.exists()) {
return file;
}
return getUnique(dir, template, ext, 1);
}
/**
* @param dir
* @param template
* @param ext
* @param i
* @return file
*/
public static File getUnique(final File dir, final String template, final String ext, int i) {
final String extension = ext != null ? (ext.startsWith(".")) ? ext : "." + ext : null;
final File file = ext != null ? new File(dir, template + i + extension) : new File(dir, template + i);
if (!file.exists()) {
return file;
}
return getUnique(dir, template, ext, ++i);
}
/**
* Recursively delete parent folder on exit of JVM
*
* @param parent
*/
static public final void recursiveDeleteOnExit(File parent) {
parent.deleteOnExit();
if (parent.isDirectory()) {
File[] files = parent.listFiles();
for (int ifile = 0; ifile < files.length; ++ifile) {
if (files[ifile].isDirectory()) {
recursiveDeleteOnExit(files[ifile]);
}
files[ifile].deleteOnExit();
}
}
}
/**
* Define buffer size here.
*
* @return the buffer size
*/
static private final int getBufferSize() {
final String size = System.getProperty("org.diamond.util.io.fileutils.buffer.size");
if (size == null) {
return 4096;
}
return Integer.parseInt(size);
}
/**
* Recursively copy one folder to another Deleting the contents of the destination folder before copying. Use at
* your peril!
*
* @param source_dir
* @param destination_dir
* @throws IOException
*/
static public final void recursiveCopy(final File source_dir, final File destination_dir) throws IOException {
FileUtils.recursiveCopy(source_dir, destination_dir, new byte[FileUtils.getBufferSize()]);
}
/**
* @param source_dir
* @param destination_dir
* @param buffer
* @throws IOException
*/
static private final void recursiveCopy(final File source_dir, final File destination_dir, final byte[] buffer)
throws IOException {
if (source_dir == null || destination_dir == null) {
return;
}
if (!source_dir.exists()) {
throw new java.io.FileNotFoundException(source_dir.getAbsolutePath());
}
if (!source_dir.isDirectory()) {
throw new java.io.IOException("recursiveCopy should only be used for folders!");
}
if (source_dir.equals(destination_dir)) {
throw new java.io.IOException("Cannot copy folder on to itself!");
}
if (destination_dir.exists()) {
FileUtils.recursiveDelete(destination_dir);
}
destination_dir.mkdirs();
File[] files = source_dir.listFiles();
for (int ifile = 0; ifile < files.length; ++ifile) {
final File from = files[ifile];
final File to = new File(destination_dir, from.getName());
if (from.isDirectory()) {
FileUtils.recursiveCopy(from, to, buffer);
continue;
}
FileUtils.copy(from, to, buffer);
}
}
/**
* Recursively copy one folder to another Deleting the contents of the destination folder before copying. Use at
* your peril!
*
* @param source_dir
* @param destination_dir
* @throws IOException
*/
static public final void recursiveCopyNio(final File source_dir, final File destination_dir) throws IOException {
if (source_dir == null || destination_dir == null) {
return;
}
if (!source_dir.exists()) {
throw new java.io.FileNotFoundException(source_dir.getAbsolutePath());
}
if (!source_dir.isDirectory()) {
throw new java.io.IOException("recursiveCopy should only be used for folders!");
}
if (source_dir.equals(destination_dir)) {
throw new java.io.IOException("Cannot copy folder on to itself!");
}
if (destination_dir.exists()) {
FileUtils.recursiveDelete(destination_dir);
}
destination_dir.mkdirs();
File[] files = source_dir.listFiles();
for (int ifile = 0; ifile < files.length; ++ifile) {
final File from = files[ifile];
final File to = new File(destination_dir, from.getName());
if (from.isDirectory()) {
FileUtils.recursiveCopyNio(from, to);
continue;
}
FileUtils.copyNio(from, to);
}
}
/**
* Recursively copy one folder to another Not deleting the contents of the destination folder before copying. Any
* file that already exists will not be copied.
*
* @param source_dir
* @param destination_dir
* @throws IOException
*/
static public final void recursiveCopyNioNoDelete(final File source_dir, final File destination_dir)
throws IOException {
if (source_dir == null || destination_dir == null) {
return;
}
if (!source_dir.exists()) {
throw new java.io.FileNotFoundException(source_dir.getAbsolutePath());
}
if (!source_dir.isDirectory()) {
throw new java.io.IOException("recursiveCopy should only be used for folders!");
}
if (source_dir.equals(destination_dir)) {
throw new java.io.IOException("Cannot copy folder on to itself!");
}
File[] files = source_dir.listFiles();
for (int ifile = 0; ifile < files.length; ++ifile) {
final File from = files[ifile];
final File to = new File(destination_dir, from.getName());
if (from.isDirectory()) {
FileUtils.recursiveCopyNioNoDelete(from, to);
continue;
}
FileUtils.copyNioNoCopyOver(from, to);
}
}
/**
* Recursively copy one folder to another, but not deleting destination data. Only copies files if timestamp
* indicates the data is newer. inf[0] - returns files copied, can be used to track progress inf[1] - returns files
* skipped, can be used to track progress inf[2] - if set to -1 will halt copy
*
* @param source_dir
* @param destination_dir
* @throws IOException
*/
static public final void recursiveIncrementalCopy(final File source_dir, final File destination_dir)
throws IOException {
recursiveIncrementalCopy(source_dir, destination_dir, new int[] { 0, 0, 0 });
}
/**
* Recursively copy one folder to another, but not deleting destination data. Only copies files if timestamp
* indicates the data is newer. inf[0] - returns files copied, can be used to track progress inf[1] - returns files
* skipped, can be used to track progress inf[2] - if set to -1 will halt copy
*
* @param source_dir
* @param destination_dir
* @param inf
* @throws IOException
*/
static public final void recursiveIncrementalCopy(final File source_dir, final File destination_dir, int[] inf)
throws IOException {
FileUtils.recursiveIncrementalCopy(source_dir, destination_dir, inf, new byte[FileUtils.getBufferSize()]);
}
/**
* @param source_dir
* @param destination_dir
* @param inf
* @param buffer
* @throws IOException
*/
static private final void recursiveIncrementalCopy(final File source_dir, final File destination_dir, int[] inf,
final byte[] buffer) throws IOException {
if (inf[2] == -1) {
return;
}
if (source_dir == null || destination_dir == null || inf.length < 3) {
return;
}
if (!source_dir.exists()) {
throw new java.io.FileNotFoundException(source_dir.getAbsolutePath());
}
if (!source_dir.isDirectory()) {
throw new java.io.IOException("recursiveCopy should only be used for folders!");
}
if (source_dir.equals(destination_dir)) {
throw new java.io.IOException("Cannot copy folder on to itself!");
}
if (destination_dir.exists()) {
destination_dir.mkdirs();
}
File[] files = source_dir.listFiles();
for (int ifile = 0; ifile < files.length; ++ifile) {
final File from = files[ifile];
final File to = new File(destination_dir, from.getName());
if (from.isDirectory()) {
recursiveIncrementalCopy(from, to, inf, buffer);
continue;
}
if (from.lastModified() > to.lastModified()) {
FileUtils.copy(from, to, buffer);
inf[0]++;
} else {
inf[1]++;
}
}
}
/**
* @param source_file
* @param destination_dir
* @throws IOException
*/
public final static void copy(final File source_file, String destination_dir) throws IOException {
File dest_file = null;
if (source_file.isDirectory()) {
dest_file = new File(destination_dir);
FileUtils.recursiveCopy(source_file, dest_file);
} else {
String fname = source_file.getName();
dest_file = new File(destination_dir, fname);
FileUtils.copy(source_file, dest_file);
}
}
/**
* Overwrites destination_file if it exists, creates new if not.
*
* @param source_file
* @param destination_file
* @throws IOException
*/
public final static void copy(final File source_file, final File destination_file) throws IOException {
FileUtils.copy(source_file, destination_file, new byte[FileUtils.getBufferSize()]);
}
/**
* Overwrites destination_file if it exists, creates new if not.
*
* @param source_file
* @param destination_file
* @param buffer
* @throws IOException
*/
public final static void copy(final File source_file, final File destination_file, final byte[] buffer)
throws IOException {
if (!source_file.exists()) {
return;
}
final File parTo = destination_file.getParentFile();
if (!parTo.exists()) {
parTo.mkdirs();
}
if (!destination_file.exists()) {
destination_file.createNewFile();
}
InputStream source = null;
OutputStream destination = null;
try {
source = new BufferedInputStream(new FileInputStream(source_file));
destination = new BufferedOutputStream(new FileOutputStream(destination_file));
int bytes_read;
while (true) {
bytes_read = source.read(buffer);
if (bytes_read == -1) {
break;
}
destination.write(buffer, 0, bytes_read);
}
} finally {
if (source != null)
source.close();
if (destination!= null)
destination.close();
}
}
/**
* @param source_file
* @param destination_file
* @throws IOException
*/
public final static void copyNio(final File source_file, final File destination_file) throws IOException {
if (!source_file.exists()) {
return;
}
final File parTo = destination_file.getParentFile();
if (!parTo.exists()) {
parTo.mkdirs();
}
if (!destination_file.exists()) {
destination_file.createNewFile();
}
FileChannel srcChannel = null, dstChannel = null;
try {
// Create channel on the source
srcChannel = new FileInputStream(source_file).getChannel();
// Create channel on the destination
dstChannel = new FileOutputStream(destination_file).getChannel();
// Copy file contents from source to destination
dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
// Close the channels
} finally {
if (srcChannel != null) {
srcChannel.close();
}
if (dstChannel != null) {
dstChannel.close();
}
}
}
/**
* @param source_file
* @param destination_file
* @throws IOException
*/
public final static void copyNioNoCopyOver(final File source_file, final File destination_file) throws IOException {
if (destination_file.exists()) {
return;
}
FileUtils.copyNio(source_file, destination_file);
}
/**
* @param source
* @param destination_file
* @throws IOException
*/
public final static void write(final BufferedInputStream source, final File destination_file) throws IOException {
final File parTo = destination_file.getParentFile();
if (!parTo.exists()) {
parTo.mkdirs();
}
if (!destination_file.exists()) {
destination_file.createNewFile();
}
OutputStream destination = null;
try {
destination = new BufferedOutputStream(new FileOutputStream(destination_file));
byte[] buffer = new byte[FileUtils.getBufferSize()];
int bytes_read;
while (true) {
bytes_read = source.read(buffer);
if (bytes_read == -1) {
break;
}
destination.write(buffer, 0, bytes_read);
}
} finally {
source.close();
if (destination != null) {
destination.close();
}
}
}
/**
* @param source_raw
* @param destination_raw
* @throws IOException
*/
public final static void write(final InputStream source_raw, final OutputStream destination_raw) throws IOException {
BufferedOutputStream destination = null;
BufferedInputStream source = null;
try {
source = new BufferedInputStream(source_raw);
destination = new BufferedOutputStream(destination_raw);
byte[] buffer = new byte[FileUtils.getBufferSize()];
int bytes_read;
while (true) {
bytes_read = source.read(buffer);
if (bytes_read == -1) {
break;
}
destination.write(buffer, 0, bytes_read);
}
} finally {
if (source != null) {
source.close();
}
if (destination != null) {
destination.close();
}
}
}
/**
* @param source
* @return byte[]
* @throws IOException
*/
public final static byte[] getByteArrayFromStream(final InputStream source) throws IOException {
return getByteArrayFromStream(source, true);
}
/**
* @param source
* @param shouldClose
* @return byte[]
* @throws IOException
*/
public final static byte[] getByteArrayFromStream(final InputStream source, final boolean shouldClose)
throws IOException {
ByteArrayOutputStream destination = FileUtils.getByteStream(source, shouldClose);
return destination.toByteArray();
}
/**
* @param source
* @return ByteArrayOutputStream
* @throws IOException
*/
public final static ByteArrayOutputStream getByteStream(final InputStream source) throws IOException {
return getByteStream(source, true);
}
/**
* @param source
* @param shouldClose
* @return ByteArrayOutputStream
* @throws IOException
*/
public final static ByteArrayOutputStream getByteStream(final InputStream source, final boolean shouldClose)
throws IOException {
ByteArrayOutputStream destination = new ByteArrayOutputStream();
try {
byte[] buffer = new byte[FileUtils.getBufferSize()];
int bytes_read;
while (true) {
bytes_read = source.read(buffer);
if (bytes_read == -1) {
break;
}
destination.write(buffer, 0, bytes_read);
}
} finally {
if (source != null) {
if (shouldClose) {
source.close();
}
}
}
return destination;
}
/**
* @param file
* @return StringBuffer
* @throws Exception
*/
public static final StringBuffer readFile(final File file) throws Exception {
return FileUtils.readFile(new FileInputStream(file));
}
/**
* @param in
* @return StringBuffer
* @throws Exception
*/
public static final StringBuffer readFile(final InputStream in) throws Exception {
return readFile(in, null);
}
/**
* @param in
* @param charsetName
* @return StringBuffer
* @throws Exception
*/
public static final StringBuffer readFile(final InputStream in, final String charsetName) throws Exception {
BufferedReader ir = null;
try {
if (charsetName != null) {
ir = new BufferedReader(new InputStreamReader(in, charsetName));
} else {
ir = new BufferedReader(new InputStreamReader(in));
}
// deliberately do not remove BOM here
int c;
StringBuffer currentStrBuffer = new StringBuffer();
final char[] buf = new char[4096];
while ((c = ir.read(buf, 0, 4096)) > 0) {
currentStrBuffer.append(buf, 0, c);
}
return currentStrBuffer;
} finally {
if (ir != null) {
ir.close();
}
}
}
/**
* @param f
* @return List<String>
* @throws Exception
*/
public static final List<String> readFileAsList(File f) throws Exception {
List<String> l = new ArrayList<String>();
BufferedReader br = null;
try {
Reader reader = new FileReader(f);
br = new BufferedReader(reader);
String str;
while ((str = br.readLine()) != null) {
l.add(str);
}
} finally {
if (br != null) {
br.close();
}
}
return l;
}
/**
* Reads a file using the encoding parameter passed and returns each line as an item in the result list Optionally:
* the BOM can be removed (first character of file if present) the line can be trimmed of whitespace
*
* @param file
* The file to read
* @param encodingOfFile
* The encoding format the file should be read as
* @param removeBom
* Whether the BOM should be removed, if present.
* @param trimLines
* If each line should have leading and trailing whitespace removed
* @return List<String> lines of the file optionally trimmed
* @throws IOException
* If the file can not be read
*/
public static final List<String> readFileAsList(final File file, final String encodingOfFile,
final boolean removeBom, final boolean trimLines) throws IOException {
final InputStream is = new FileInputStream(file);
final Reader br = new BufferedReader(new InputStreamReader(is, encodingOfFile));
final List<String> fileContents = new ArrayList<String>(33);
try {
String line;
boolean readFirstLine = false;
while ((line = ((BufferedReader) br).readLine()) != null) {
// Remove BOM from file if specified at first part of file
if (removeBom && !readFirstLine) {
readFirstLine = true;
final char firstChar = line.charAt(0);
if (firstChar == FileUtils.BOM) {
line = line.substring(1);
}
}
if (trimLines) {
fileContents.add(line.trim());
} else {
fileContents.add(line);
}
}
} finally {
br.close();
is.close();
}
return fileContents;
}
private final static int TESTNUM = 1;
/**
* This method returns true if file is Unix and false if Windows line endings.
*
* @param stringToTest
* The text of the file
*@return boolean true if the file is Unix.
*/
public static boolean isUnix(final String stringToTest) {
boolean isUnix = false;
StringBuffer sb = new StringBuffer(stringToTest);
int unix = 0, win = 0;
for (int j = 0; j < sb.length(); j++) {
if (unix >= TESTNUM) {
isUnix = true;
break;
} else if (win >= TESTNUM) {
isUnix = false;
break;
}
if (sb.charAt(j) == '\n' && (j == 0 || sb.charAt(j - 1) != '\r')) {
unix += 1;
} else if (sb.charAt(j) == '\n' && (j == 0 || sb.charAt(j - 1) == '\r')) {
win += 1;
}
}
return isUnix;
}
/**
* Returns true if the string is starting with a BOM
*
* @param stringToTest
* @return boolean
*/
public static boolean isBOM(String stringToTest) {
if (stringToTest == null) {
return false;
}
if ("".equals(stringToTest)) {
return false;
}
return stringToTest.charAt(0) == BOM;
}
/**
* @param file
* @param text
* @param encoding
* @throws Exception
*/
public static void write(final File file, final String text, String encoding) throws Exception {
BufferedWriter b = null;
try {
final OutputStream out = new FileOutputStream(file);
final OutputStreamWriter writer = new OutputStreamWriter(out, encoding);
b = new BufferedWriter(writer);
b.write(text.toCharArray());
} finally {
if (b != null) {
b.close();
}
}
}
/**
* This method attempts to write a string to file in US-ASCII. The code was moved directly from atos.SaveTextFile
* and no check has been made to how efficient it is.
*
* @param file
* @param text
* @throws Exception
*/
public static void write(final File file, final String text) throws Exception {
write(file, text, "US-ASCII");
}
/**
* This method writes to a stream a potentially large String. The current limit for Java servlets in 90Mb with this
* method there is a workaround in Java 1.5 for this problem:
* http://forum.java.sun.com/thread.jspa?threadID=418441&messageID=2816084
* http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5026745
*
* @param out
* @param text
* @param charset
* @param addBomIfNeeded
* @throws Exception
*/
public static void write(final OutputStream out, String text, final String charset, final boolean addBomIfNeeded)
throws Exception {
BufferedWriter b = null;
try {
if (addBomIfNeeded && text.charAt(0) != BOM) {
text = BOM + text;
}
b = new BufferedWriter(new OutputStreamWriter(out, charset));
b.write(text.toCharArray());
} finally {
if (b != null) {
b.close();
}
}
}
/**
* @param file
* @param list
* @throws Exception
*/
public static void write(final File file, final List<String> list) throws Exception {
BufferedWriter bw = null;
try {
final OutputStream out = new FileOutputStream(file);
bw = new BufferedWriter(new OutputStreamWriter(out));
for (int i = 0; i < list.size(); i++) {
final String line = list.get(i);
bw.write(line, 0, line.length());
bw.newLine();
}
} finally {
if (bw != null) {
bw.close();
}
}
}
/**
* @param file
* @return File
*/
public static File createNewUniqueDir(final File file) {
return createNewUniqueDir(file, FileUtils.NEWFOLDER);
}
/**
* @param file
* @param templateName
* @return File
*/
public static File createNewUniqueDir(final File file, final String templateName) {
File sug = new File(file, templateName);
if (sug.exists()) {
int i = 2;
while (sug.exists()) {
sug = new File(file, templateName + " (" + i + ")");
++i;
}
}
sug.mkdirs();
return sug;
}
/**
* @param name
* @return String
*/
public final static String getParentDirName(final String name) {
final int indx = name.lastIndexOf("/");
String ret;
if (indx > -1) {
ret = name.substring(0, indx);
} else {
ret = "/";
}
if (!ret.endsWith("/")) {
ret = ret + "/";
}
return ret;
}
/**
* @param file
* @param fromNoClose
* @throws Exception
*/
static public final void writeToFile(final File file, final InputStream fromNoClose) throws Exception {
final BufferedInputStream buf = new BufferedInputStream(fromNoClose);
final FileOutputStream fl = new FileOutputStream(file);
final BufferedOutputStream out = new BufferedOutputStream(fl);
try {
byte[] buffer = new byte[FileUtils.getBufferSize()];
int bytes_read;
while (true) {
bytes_read = buf.read(buffer);
if (bytes_read == -1) {
break;
}
out.write(buffer, 0, bytes_read);
}
} finally {
out.flush();
out.close();
}
}
/**
* @param dir
* @return long
*/
public static long getDiskSpace(final File dir) {
long inuse = 0;
if (dir.isDirectory()) {
final File[] files = dir.listFiles();
for (File element : files) {
inuse += getDiskSpace(element);
}
} else {
inuse += dir.length();
}
return inuse;
}
/**
* @param tmp
* @param sizeInMB
* @return boolean
* @throws IOException
*/
public static boolean isDiskSpaceAvaliableMB(final File tmp, final long sizeInMB) throws IOException {
return isDiskSpaceAvaliable(tmp, sizeInMB * 1000000);
}
/**
* @param tmp
* @param sizeInB
* @return boolean
* @throws IOException
*/
public static boolean isDiskSpaceAvaliable(final File tmp, final long sizeInB) throws IOException {
if (!tmp.getParentFile().exists()) {
tmp.getParentFile().mkdirs();
}
if (!tmp.exists()) {
tmp.createNewFile();
}
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile(tmp, "rw");
raf.setLength(sizeInB);
return true;
} catch (IOException ioe) {
return false;
} finally {
if (raf != null) {
raf.close();
}
tmp.delete();
}
}
/**
* @param file
* @param subFolders
* @return long
*/
public static long getFileSizeRecursive(File file, boolean subFolders) {
long size = 0;
if (file.isDirectory()) {
File[] files = file.listFiles();
if (files != null) {
for (File element : files) {
if (!subFolders && element.isDirectory()) {
continue;
}
long tmpSize = getFileSizeRecursive(element, subFolders);
if (tmpSize != -1) {
size += tmpSize;
}
}
return size;
}
return -1;
}
return file.length();
}
/**
* Get File extension (result will NOT include ".")
*
* @param fileName
* @return String file extension value, or "" is no extension
*/
public static String getFileExtension(String fileName) {
int posExt = fileName.lastIndexOf(".");
// No File Extension
return posExt == -1 ? "" : fileName.substring(posExt + 1);
}
/**
* Get File extension (result will NOT include ".")
*
* @param file
* @return String file extension value, or "" is no extension
*/
public static String getFileExtension(File file) {
return getFileExtension(file.getName());
}
/**
* Get Filename minus it's extension if present
*
* @param file
* File to get filename from
* @return String filename minus its extension
*/
public static String getFileNameNoExtension(File file) {
return getFileNameNoExtension(file.getName());
}
/**
* Get Filename minus it's extension if present
*
* @param fileName path to get filename of
* @return String filename minus its extension
*/
public static String getFileNameNoExtension(String fileName) {
int posExt = fileName.lastIndexOf(".");
// No File Extension
return posExt == -1 ? fileName : fileName.substring(0, posExt);
}
/**
* Formats a file size
*
* @param longSize
* @param decimalPos
* @return formatted string for size.
*/
public static String formatSize(long longSize, int decimalPos) {
NumberFormat fmt = NumberFormat.getNumberInstance();
if (decimalPos >= 0) {
fmt.setMaximumFractionDigits(decimalPos);
}
final double size = longSize;
double val = size / (1024 * 1024 * 1024);
if (val > 1) {
return fmt.format(val).concat(" GB");
}
val = size / (1024 * 1024);
if (val > 1) {
return fmt.format(val).concat(" MB");
}
val = size / 1024;
if (val > 10) {
return fmt.format(val).concat(" KB");
}
return fmt.format(size).concat(" bytes");
}
public static String setExtension(final String path, final String ext) {
final int index = path.lastIndexOf(".");
return path.substring(0, index)+"."+ext;
}
public static String getDirectory(final String filePath) {
File dir = new File(filePath);
if (!dir.isDirectory()) dir = dir.getParentFile();
return dir.getAbsolutePath();
}
/**
* Attempts to construct a legal file name from a file name.
* With throw an NPE if null or maybe return empty string if no legal characters.
* @param name
* @return name
*/
public static final String getLegalFileName(String name) {
name = name.replace(" ", "_");
name = name.replaceAll("[^a-zA-Z0-9_]", "");
return name;
}
/**
* Waits for a file lock for a given time, with a given frequency.
* Does nothing if cannot lock after totalTime - to avoid deadlocks
* @param f
* @param frequency
* @param totalTime
*/
public static void pauseForLock(File f, int frequency, int totalTime) throws Exception {
// If file locked, wait for up to 2s
int waited = 0;
final FileOutputStream out = new FileOutputStream(f);
try {
FileLock lock = out.getChannel().tryLock();
try {
while(lock==null) {
Thread.sleep(frequency);
waited+=frequency;
if (waited>=totalTime) break;
}
} finally {
if (lock!=null) lock.release();
}
} finally {
out.close();
}
}
/**
*
*
* @param name prefix of the file
* @return a writable temporary file path
*/
public static String getTempFilePath(String name) {
String file = "";
String tmpfilepath = System.getProperty("java.io.tmpdir") + File.separator;
String tmpDiamondFilePath = "/dls/tmp/";
String username = System.getProperty("user.name");
File tmpDir = new File(tmpfilepath);
// if tmp directory is writable
boolean canWrite =tmpDir.canWrite();
if (canWrite) {
File folderTmp = new File(tmpfilepath + username);
if (!folderTmp.exists())
folderTmp.mkdir();
file = tmpfilepath + username + File.separator +"tmp_" + name;
} else if (!canWrite) {
File diamondFolderTmp = new File(tmpDiamondFilePath);
if (diamondFolderTmp.canWrite()) {
File diamondTmpUserFolder = new File(tmpDiamondFilePath + username);
if(!diamondTmpUserFolder.exists()) {
diamondTmpUserFolder.mkdir();
}
file = tmpDiamondFilePath + username + File.separator +"tmp_" + name;
} else {
//TODO other case?
}
}
return file;
}
}