You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

896 lines
25 KiB
Java

/*
* Copyright (C) 2009-2017 Alistair Neil <info@dazzleships.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package lib;
import java.io.*;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
/**
*
* @author Alistair Neil info@dazzleships.net
*/
public class SimpleFile {
public static final int PERIOD_MINUTES = 0;
public static final int PERIOD_HOURS = 1;
public static final int PERIOD_DAYS = 2;
public static final int NOTFOUND = 0;
public static final int FILEDELETEOK = 1;
public static final int FILEDELETEFAIL = 2;
private final int blockreadsize = 1024;
private BufferedReader br;
private BufferedWriter bw;
private ZipOutputStream zos;
private File f;
private String filter = "";
public SimpleFile() {
}
/**
* Constructor
*
* @param pathname
*/
public SimpleFile(String pathname) {
f = new File(pathname);
}
/**
* Set filename
*
* @param pathname
*/
public final void setFileName(String pathname) {
f = new File(pathname);
}
/**
* Set file
*
* @param file
*/
public final void setFile(File file) {
f = file;
}
/**
* Get file
*
* @return file
*/
public final File getFile() {
return f;
}
/**
* Close file and any resources such as buffered readers/writers that are
* attached to it.
*/
public final void closeFile() {
if (br != null) {
try {
br.close();
} catch (IOException ex) {
Logger.getLogger(SimpleFile.class.getName()).log(Level.SEVERE, null, ex);
}
br = null;
}
if (bw != null) {
try {
bw.close();
} catch (IOException ex) {
Logger.getLogger(SimpleFile.class.getName()).log(Level.SEVERE, null, ex);
}
bw = null;
}
}
/**
* Sets the file filter
*
* @param filter
*/
public final void setFileFilter(String filter) {
this.filter = filter;
}
/**
* Gets the current file filter
*
* @return Returns the file filter
*/
public final String getFileFilter() {
return filter;
}
public final static String getSeparator() {
return File.separator;
}
/**
* Creates a new folder
*
* @return True if successful
*/
public final boolean createFolder() {
if (f.exists()) {
return true;
}
return f.mkdirs();
}
/**
* Creates a new folder
*
* @param path The location of the new folder
* @return True if successful
*/
public final static boolean createFolder(String path) {
File fl = new File(path);
if (fl.exists()) {
return true;
}
return fl.mkdirs();
}
/**
* Create a new file
*
* @return True if file exist or is created
*/
public final boolean createFile() {
boolean createNewFile = true;
if (!f.exists()) {
try {
createFolder(f.getParent());
createNewFile = f.createNewFile();
} catch (IOException ex) {
createNewFile = false;
}
}
return createNewFile;
}
/**
* Gets the file list at the specified directory location based on filter
* contents
*
* @return An array of Files
*/
public final File[] getFileList() {
File[] arrFilesCache;
if (filter.isEmpty()) {
arrFilesCache = f.listFiles();
} else {
arrFilesCache = f.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.getPath().contains(filter);
}
});
}
return arrFilesCache;
}
public final File getOldestFile() {
long lngLastAge = new Date().getTime();
File oldest = null;
File[] arrFiles = getFileList();
for (File fi : arrFiles) {
if (fi.lastModified() < lngLastAge) {
lngLastAge = fi.lastModified();
oldest = fi;
}
}
return oldest;
}
public final static void walkFileTree(String path, ArrayList<File> files) {
walkFileTree(path, files, "");
}
public final static void walkFileTree(String path, ArrayList<File> files, final String filter) {
File[] arrFilesCache;
File root = new File(path);
if (filter.isEmpty()) {
arrFilesCache = root.listFiles();
} else {
arrFilesCache = root.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.getPath().contains(filter);
}
});
}
if (arrFilesCache == null) {
return;
}
for (File f : arrFilesCache) {
if (f.isDirectory()) {
walkFileTree(f.getAbsolutePath(), files, filter);
} else {
files.add(f);
}
}
}
/**
* Deletes the supplied list of files, be very carefull with this
*
* @param files
*/
public final void deleteFileList(File[] files) {
for (File fx : files) {
if (fx.isFile()) {
boolean delete = fx.delete();
}
}
}
/**
* Delete folder and its contents using specified folder path
*
* @param folder
* @return boolean True if successful
*/
public final static boolean deleteFolder(String folder) {
if (OSFunction.isLinux() && folder.contentEquals("/")) {
return false;
}
return deleteFolder(new File(folder));
}
/**
* Delete a folder and all of its contents works recursively
*
*/
private static boolean deleteFolder(File folder) {
if (!folder.exists()) {
return false;
}
for (File fx : folder.listFiles()) {
if (fx.isDirectory()) {
deleteFolder(fx);
} else {
boolean delete = fx.delete();
}
}
return folder.delete();
}
/**
* Wipe folder and its contents using specified folder path
*
* @param folder
*/
public final static void secureWipeFolder(String folder) {
if (OSFunction.isLinux() && folder.contentEquals("/")) {
return;
}
secureWipeFolder(new File(folder));
}
/**
* Wipe folder and its contents using specified File
*
* @param folder
*/
public final static void secureWipeFolder(File folder) {
if (!folder.exists()) {
return;
}
for (File fx : folder.listFiles()) {
if (fx.isDirectory()) {
secureWipeFolder(fx);
} else {
secureWipe(fx);
}
}
folder = renameTo(folder, "0000000");
folder.delete();
}
/**
* Wipe file using specified filename
*
* @param filename
*/
public final static void secureWipe(String filename) {
secureWipe(new File(filename));
}
/**
* Wipe file using specified File
*
* @param f
*/
public final static void secureWipe(File f) {
if (!f.exists()) {
return;
}
FileOutputStream fos = null;
byte b[] = new byte[4096];
long i = f.length() / 4096;
int remainder = (int) (f.length() % 4096);
byte r[] = new byte[remainder];
try {
// Overwrite with zeros
fos = new FileOutputStream(f, false);
while (i-- > 0) {
fos.write(b);
fos.flush();
}
fos.write(r);
fos.close();
// Zero file length
b = new byte[0];
fos = new FileOutputStream(f, false);
fos.write(b);
} catch (IOException ex) {
Logger.getLogger(SimpleFile.class
.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
if (fos != null) {
fos.close();
}
// Rename file
f = renameTo(f, "0000000000");
// Delete file
f.delete();
} catch (IOException ex) {
}
}
}
public final static File renameTo(File f, String newname) {
String path = f.getParent();
if (path != null) {
path += File.separator + newname;
File nf = new File(path);
if (f.renameTo(nf)) {
return nf;
}
}
return f;
}
/**
* Copy multiple files from one folder to another
*
* @param from The from path
* @param to The to path
* @param ignore
*/
public final static void copyFolderContents(String from, String to, String ignore) {
try {
File ourFile = new File(from);
for (File fx : ourFile.listFiles()) {
if (!ignore.contains(fx.getName())) {
copyFromTo(fx.getAbsolutePath(), to + fx.getName());
}
}
} catch (Exception ex) {
Logger.getGlobal().logp(Level.WARNING, "SimpleFile", "copyFolderContents()", "", ex);
}
}
/**
* Returns an array of filenames, array if populated from the offset value
* onwards
*
* @param offset
* @return An array of filenames
*/
public final String[] getFilenames(int offset) {
String filename;
File[] fileList = getFileList();
String[] result = new String[fileList.length + offset];
try {
for (int i = 0; i < fileList.length; i++) {
filename = fileList[i].getName();
result[i + offset] = filename.substring(0, filename.indexOf('.'));
}
return result;
} catch (Exception ex) {
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(), "getFilenames(int offset)", "", ex);
return null;
}
}
/**
* Test to see if path exists
*
* @return Returns true if file exists
*/
public final boolean exists() {
return f.exists();
}
/**
* Test to see if path exists
*
* @param pathname The pathname to check for
* @return Returns true if file exists
*/
public final static boolean exists(String pathname) {
return new File(pathname).exists();
}
/**
* Deletes file
*
* @return Returns true if successful
*/
public final boolean delete() {
return f.delete();
}
/**
* Deletes the specified file
*
* @param filename
* @return Returns true if successful
*/
public final static boolean delete(String filename) {
return new File(filename).delete();
}
/**
*
* @param toname
* @return Returns true if successful
*/
public final boolean renameFile(String toname) {
return f.renameTo(new File(toname));
}
/**
* Opens a buffered file for read
*
* @return Returns null if failed
*/
public final BufferedReader openBufferedRead() {
try {
br = new BufferedReader(new FileReader(f));
return br;
} catch (FileNotFoundException ex) {
}
return null;
}
/**
* Use this if you need access to a file within a jar
*
*/
public final void openBufferedResource() {
try {
String path = f.getPath();
path = path.replace('\\', '/');
InputStream is = getClass().getResourceAsStream(path);
br = new BufferedReader(new InputStreamReader(is));
} catch (Exception ex) {
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(), "openBufferedRead(int filehandle)", "", ex);
}
}
/**
* Opens a buffered file for append
*
*/
public final void openBufferedAppend() {
try {
bw = new BufferedWriter(new FileWriter(f, true));
} catch (IOException ex) {
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(), "openBufferedAppend()", "", ex);
}
}
/**
* Read a single line from a text file
*
* @return Contents as String
*/
public final String readLine() {
try {
return br.readLine();
} catch (IOException ex) {
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(), "readLine(int filehandle)", "", ex);
}
return null;
}
/**
* Read bytes from previously opened BufferedReader
*
* @return Returns the entire contents from a file
*/
public final String readEntireFile() {
char[] cb = new char[blockreadsize];
StringBuilder sb = new StringBuilder();
int bytes;
try {
while (br.ready()) {
bytes = br.read(cb);
sb.append(cb, 0, bytes);
}
return sb.toString();
} catch (IOException ex) {
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(), "readEntireFile()", "", ex);
}
return "";
}
public final FileInputStream openFileInputStream(String filename) {
try {
return new FileInputStream(new File(filename));
} catch (FileNotFoundException ex) {
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(), "openFileInputStream()", "", ex);
return null;
}
}
/**
* Opens a file output stream
*
* @return Returns Opened file output stream
*/
public final FileOutputStream openFileOutputStream() {
try {
return new FileOutputStream(f);
} catch (FileNotFoundException ex) {
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(), "openFileOutputStream()", "", ex);
return null;
}
}
/**
* Opens a buffered file for write
*
*/
public final void openBufferedWrite() {
try {
bw = new BufferedWriter(new FileWriter(f));
} catch (IOException ex) {
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(), "openBufferedWrite()", "", ex);
}
}
public final void flushWriter() {
try {
bw.flush();
} catch (IOException ex) {
}
}
/**
* Write to a previously opened output file
*
* @param data The data to be written
* @param newlines The number of newlines to generate
*/
public final void writeFile(String data, int newlines) {
try {
bw.write(data);
while (newlines > 0) {
bw.newLine();
newlines--;
}
} catch (IOException ex) {
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(),
"writeToFile(" + data + "," + String.valueOf(newlines) + ")", "", ex);
}
}
/**
* Write to a previously opened output file
*
* @param data The character data to be written
* @param nochars
*/
public final void writeFile(char[] data, int nochars) {
try {
bw.write(data, 0, nochars);
} catch (IOException ex) {
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(), "writeToFile()", "", ex);
}
}
/**
* Copy file to
*
* @param frompath
* @param topath
*/
public final static void copyFromTo(String frompath, String topath) {
try {
Path source = new File(frompath).toPath();
Path dest = new File(topath).toPath();
Files.copy(source, dest, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException ex) {
Logger.getGlobal().logp(Level.WARNING, "SimpleFile", "copyFromTo()", "", ex);
}
}
public final static void mergeFiles(String srcpath1, String srcpath2, String destpath) {
try (OutputStream os = new FileOutputStream(new File(destpath))) {
Path source = new File(srcpath1).toPath();
Files.copy(source, os);
source = new File(srcpath2).toPath();
Files.copy(source, os);
os.close();
} catch (IOException ex) {
Logger.getGlobal().logp(Level.WARNING, "SimpleFile", "mergeFiles", "", ex);
}
}
/**
* Get the age of a specified file
*
* @param filepath
* @param period
* @return Age of file as float
*/
public final static float getAgeOfFile(String filepath, int period) {
File fx = new File(filepath);
if (!fx.exists()) {
return -1;
}
float fltAge = System.currentTimeMillis() - fx.lastModified();
switch (period) {
case PERIOD_MINUTES:
return fltAge / 60000;
case PERIOD_HOURS:
return fltAge / (60000 * 60);
case PERIOD_DAYS:
return fltAge / (60000 * 60 * 24);
}
return -1;
}
/**
* Test to see our file is older in minutes, returns true if it is
*
* @param filename
* @param minutes
* @return boolean
*/
public final static boolean isMinutesOlder(String filename, long minutes) {
long lngAge = System.currentTimeMillis() - new File(filename).lastModified();
return lngAge > (60000 * minutes);
}
/**
* Test to see our file is older in hours, returns true if it is
*
* @param filename
* @param hours
* @return boolean
*/
public final static boolean isHoursOlder(String filename, long hours) {
long lngAge = System.currentTimeMillis() - new File(filename).lastModified();
return lngAge > (60000 * 60 * hours);
}
/**
* Test to see our file is older in days, returns true if it is
*
* @param filename
* @param days
* @return boolean
*/
public final static boolean isDaysOlder(String filename, long days) {
long lngAge = System.currentTimeMillis() - new File(filename).lastModified();
return lngAge > (60000 * 60 * 24 * days);
}
/**
* Opens a zipstream. returns false if it fails
*
* @param level
* @return an open zipstream
*/
public final boolean openZipStream(int level) {
try {
zos = new ZipOutputStream(new FileOutputStream(f.getAbsolutePath()));
if (level < 0 || level > 9) {
level = 6;
}
zos.setLevel(level);
return true;
} catch (FileNotFoundException ex) {
}
return false;
}
/**
* Close a zip stream
*/
public final void closeZipStream() {
if (zos != null) {
try {
zos.close();
} catch (IOException ex) {
}
}
}
public final static void compress(String source, String dest) {
final Path pathSource = Paths.get(source);
try {
final ZipOutputStream outputStream = new ZipOutputStream(new FileOutputStream(dest));
Files.walkFileTree(pathSource, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attributes) {
try {
Path targetFile = pathSource.relativize(file);
outputStream.putNextEntry(new ZipEntry(targetFile.toString()));
byte[] bytes = Files.readAllBytes(file);
outputStream.write(bytes, 0, bytes.length);
outputStream.closeEntry();
} catch (IOException e) {
}
return FileVisitResult.CONTINUE;
}
});
outputStream.close();
} catch (IOException e) {
}
}
/**
* Add files to a zip file
*
* @param srcfiles An array of Files
* @return boolean True if successful
*/
public final boolean addFilesToZip(File... srcfiles) {
FileInputStream in = null;
if (srcfiles == null || srcfiles.length == 0) {
return false;
}
try {
for (File fx : srcfiles) {
in = new FileInputStream(fx);
// name the file inside the zip file
zos.putNextEntry(new ZipEntry(fx.getName()));
byte[] b = Files.readAllBytes(Paths.get(fx.getAbsolutePath()));
zos.write(b, 0, b.length);
in.close();
}
return true;
} catch (IOException ex) {
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException ex) {
}
}
return false;
}
/**
* Extracts a zip file to a supplied location
*
* @param destpath Destination for contents of zip file
* @return True if successful
*/
public final boolean extractZipTo(String destpath) {
FileOutputStream fos;
final int BUFFER = 2048;
try {
FileInputStream fis = new FileInputStream(f);
try (ZipInputStream zin = new ZipInputStream(new BufferedInputStream(fis))) {
ZipEntry entry;
while ((entry = zin.getNextEntry()) != null) {
int count;
byte data[] = new byte[BUFFER];
try {
fos = new FileOutputStream(destpath + File.separator + entry.getName());
} catch (FileNotFoundException ex) {
continue;
}
try (BufferedOutputStream dest = new BufferedOutputStream(fos, 2048)) {
while ((count = zin.read(data, 0, BUFFER)) != -1) {
dest.write(data, 0, count);
}
dest.flush();
dest.close();
}
fos.close();
}
zin.close();
fis.close();
}
return true;
} catch (IOException ex) {
Logger.getGlobal().logp(Level.WARNING, this.getClass().getName(), "extractZipTo()", "", ex);
}
return false;
}
public final static boolean objectWrite(String filepath, Object o) {
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream(new File(filepath)));
} catch (FileNotFoundException ex) {
} catch (IOException ex) {
}
if (oos == null) {
return false;
}
try {
oos.writeObject(o);
oos.close();
return true;
} catch (IOException ex) {
}
return false;
}
public final static Object objectRead(String filepath, Object defObject) {
ObjectInputStream oos = null;
try {
oos = new ObjectInputStream(new FileInputStream(new File(filepath)));
} catch (FileNotFoundException ex) {
} catch (IOException ex) {
}
if (oos == null) {
return defObject;
}
Object result = defObject;
try {
result = oos.readObject();
} catch (IOException | ClassNotFoundException ex) {
}
return result;
}
}