+ Properties object for preferences, loaded on startup, saved on close + MyProgBar on comparison + Remaining time calculated on comparison modified MyFilesystemParser.java + counters for dumped and compared lines modified MyProgBar.java * now uses long values x threw NullPointerException when Graphics g was null x some pixel corrections, incl. addition correction if run on EPOC + more accessors
393 lines
13 KiB
Java
393 lines
13 KiB
Java
import java.io.BufferedOutputStream;
|
|
import java.io.BufferedReader;
|
|
import java.io.BufferedWriter;
|
|
import java.io.File;
|
|
import java.io.FileInputStream;
|
|
import java.io.FileOutputStream;
|
|
import java.io.InputStreamReader;
|
|
import java.io.IOException;
|
|
import java.io.OutputStreamWriter;
|
|
|
|
import java.util.Calendar;
|
|
import java.util.Date;
|
|
import java.util.zip.GZIPInputStream;
|
|
import java.util.zip.GZIPOutputStream;
|
|
|
|
public class MyFilesystemParser {
|
|
|
|
File logFile;
|
|
private String curLine;
|
|
private String ignoreDir;
|
|
private long counter;
|
|
public long cmpcounter;
|
|
public long dumpcounter;
|
|
|
|
public MyFilesystemParser(String logfile) {
|
|
logFile = new File(logfile+".gz");
|
|
ignoreDir = System.getProperty("user.dir");
|
|
while (ignoreDir.charAt(ignoreDir.length()-1)=='\\') ignoreDir = ignoreDir.substring(0, ignoreDir.length()-1);
|
|
}
|
|
|
|
public boolean driveIsWritable(char drive) {
|
|
File flTest = new File (drive+":\\");
|
|
return flTest.canWrite();
|
|
}
|
|
|
|
public boolean driveExists(char drive) {
|
|
File flTest = new File(drive+":\\");
|
|
return flTest.exists();
|
|
}
|
|
|
|
public boolean driveIsReadable(char drive) {
|
|
File flTest = new File(drive+":\\");
|
|
return flTest.canRead();
|
|
}
|
|
|
|
/* public File[] listRoots() {
|
|
File[] result = new File[1];
|
|
result[0] = new File("E:\\");
|
|
return result;
|
|
}
|
|
*/
|
|
public File[] listRoots() {
|
|
int count = 0;
|
|
for (char d='A';d<='Z';d++) {
|
|
if (driveExists(d)) count++;
|
|
}
|
|
File[] result = new File[count];
|
|
count = 0;
|
|
for (char d='A';d<='Z';d++) {
|
|
if (driveExists(d)) result[count++] = new File(d+":\\");
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/** Returns all files of a specified directory
|
|
ATTENTION! ignoreDir has to contain a directory which should be ignored (temp, etc.).
|
|
The String must have no trailing backslash or slash. Also keep in mind that we work with
|
|
equalsIgnoreCase - so this won't work correctly on UNIXish machines
|
|
@param dir Directory to get contents of
|
|
@param noIgnoreDir If false, the startup-directory is ignored (because there are temporary files, data files, etc.)
|
|
@return File[] with File-Objects of all files in that directory
|
|
*/
|
|
public File[] listFiles(File dir, boolean noIgnoreDir) {
|
|
String[] files = dir.list();
|
|
File[] result;
|
|
if ( files != null && ( !dir.getAbsolutePath().equalsIgnoreCase(ignoreDir) || noIgnoreDir )) {
|
|
result = new File[files.length];
|
|
for (int i=0; i<files.length; i++) {
|
|
String lastItem = dir.getAbsolutePath();
|
|
result[i] = new File(lastItem+((lastItem.charAt(lastItem.length()-1)=='\\')?"":"\\")+files[i]);
|
|
}
|
|
} else {
|
|
result = new File[0];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/** Swaps two items of the files array */
|
|
public void swap(File[] files, int i1, int i2) {
|
|
File tmp = files[i2];
|
|
files[i2] = files[i1];
|
|
files[i1] = tmp;
|
|
}
|
|
|
|
/** String.compareToIgnoreCase() */
|
|
public int lge(String s1, String s2) {
|
|
return s1.toLowerCase().compareTo(s2.toLowerCase());
|
|
}
|
|
|
|
/** Helper method to partition QuickSort-areas */
|
|
public int sortQuickPart(File[] files, int lo, int hi) {
|
|
String p = files[(lo+hi)/2].getName(); // Pivot-Element
|
|
|
|
while (lo <= hi) {
|
|
while (lge(files[hi].getName(), p) > 0) hi--;
|
|
while (lge(files[lo].getName(), p) < 0) lo++;
|
|
if (lo < hi) {
|
|
swap(files, lo++, hi--);
|
|
} else {
|
|
return hi;
|
|
}
|
|
}
|
|
return hi;
|
|
}
|
|
|
|
/** QuickSort implementation */
|
|
public void sortQuick(File[] files, int lo, int hi) {
|
|
if (lo<hi) {
|
|
int p = sortQuickPart(files, lo, hi);
|
|
sortQuick(files, p+1, hi);
|
|
sortQuick(files, lo, p);
|
|
}
|
|
}
|
|
|
|
/** Arranges all directory-entries of the list at top */
|
|
public void sortDirsFirst(File[] files) {
|
|
int x;
|
|
if (files.length>0 && files[0].isDirectory()) x=1; else x=0;
|
|
File tmp;
|
|
for (int i=1;i<files.length;i++) {
|
|
if (files[i].isDirectory()) {
|
|
tmp = files[i];
|
|
for (int j=i;j>x;j--) {
|
|
files[j] = files[j-1];
|
|
}
|
|
files[x] = tmp;
|
|
x++;
|
|
}
|
|
}
|
|
}
|
|
|
|
/** Returns the sorted files-array */
|
|
public File[] sortDir(File[] files) {
|
|
if (files.length>=2) {
|
|
sortQuick(files, 0, files.length-1);
|
|
// sortDirsFirst(files);
|
|
}
|
|
return files;
|
|
}
|
|
|
|
/** Writes all file-entries incl. size and time of dir and sub-dirs to fw */
|
|
public void dumpFiles(BufferedOutputStream fw, File dir) throws IOException {
|
|
File[] entries = sortDir(listFiles(dir, false));
|
|
for (int i=0; i<entries.length; i++) {
|
|
if (entries[i].isDirectory() && entries[i].canRead()) {
|
|
fw.flush();
|
|
dumpFiles(fw, entries[i]);
|
|
} else if (entries[i].isFile()) {
|
|
fw.write((entries[i].getPath()+"\t"+entries[i].length()+"\t"+entries[i].lastModified()+"\r\n").getBytes());
|
|
dumpcounter++;
|
|
}
|
|
}
|
|
fw.flush();
|
|
}
|
|
|
|
/** Walks the root-directories of all drives and calls dumpFiles() */
|
|
public long dumpAllDrives() throws IOException {
|
|
BufferedOutputStream fw = new BufferedOutputStream(new GZIPOutputStream(new FileOutputStream(logFile)));
|
|
File[] roots = listRoots();
|
|
dumpcounter = 0;
|
|
for (int i=0;i<roots.length;i++) {
|
|
if (roots[i].canWrite()) {
|
|
dumpFiles(fw, roots[i]);
|
|
}
|
|
}
|
|
fw.close();
|
|
return dumpcounter;
|
|
}
|
|
|
|
/** Compares file-liste from cmp to actual files on disk and writes changes to out */
|
|
public void cmpFiles(BufferedReader cmp, BufferedOutputStream out, File dir, BufferedOutputStream dout) throws IOException {
|
|
File[] entries = sortDir(listFiles(dir, false));
|
|
String myLine = "";
|
|
for (int i=0; i<entries.length; i++) {
|
|
if (entries[i].isDirectory() && entries[i].canRead()) {
|
|
// readable directory ... submerge
|
|
out.flush();
|
|
if (dout != null) dout.flush();
|
|
cmpFiles(cmp, out, entries[i], dout);
|
|
} else if (entries[i].isFile()) {
|
|
// it's a file
|
|
myLine = entries[i].getPath()+"\t"+entries[i].length()+"\t"+entries[i].lastModified();
|
|
if (dout != null) dout.write((myLine+"\r\n").getBytes());
|
|
String fn1 = curLine.substring(0, curLine.indexOf("\t"));
|
|
String fn2 = myLine.substring(0, myLine.indexOf("\t"));
|
|
while (lge(fn1, fn2) < 0) {
|
|
// file from dump is behind our current file on disk.
|
|
// i.e.: a file got deleted - never mind, do not log
|
|
out.write(("-\t"+curLine+"\r\n").getBytes());
|
|
counter++;
|
|
curLine = cmp.readLine();
|
|
cmpcounter++;
|
|
fn1 = curLine.substring(0, curLine.indexOf("\t"));
|
|
}
|
|
if (!myLine.equals(curLine)) {
|
|
// something's different - name (new file) or just size or date - log it!
|
|
if (fn1.equals(fn2)) {
|
|
// both entries are about the same file, but size or date differs
|
|
out.write(("*\t"+myLine+"\r\n").getBytes());
|
|
counter++;
|
|
curLine = cmp.readLine();
|
|
cmpcounter++;
|
|
} else {
|
|
// there's a new file on disk
|
|
out.write(("+\t"+myLine+"\r\n").getBytes());
|
|
counter++;
|
|
}
|
|
} else {
|
|
// both entries are equal - never mind, advance to next
|
|
curLine = cmp.readLine();
|
|
cmpcounter++;
|
|
}
|
|
} // else if (entries[i].isFile())
|
|
} // for (int i=0; i<entries.length; i++)
|
|
out.flush();
|
|
}
|
|
|
|
/** Walks all root-directories and calls cmpFiles() */
|
|
public long dumpDifferences(String outfile, boolean redump) throws IOException {
|
|
BufferedOutputStream out = new BufferedOutputStream(new GZIPOutputStream(new FileOutputStream(outfile)));
|
|
BufferedOutputStream dout;
|
|
if (redump) dout = new BufferedOutputStream(new GZIPOutputStream(new FileOutputStream("$$mfs$$.$$$"))); else dout = null;
|
|
BufferedReader cmp = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(logFile))));
|
|
counter = 0;
|
|
cmpcounter = 1;
|
|
File[] roots = listRoots();
|
|
curLine = cmp.readLine();
|
|
for (int i=0;i<roots.length;i++) {
|
|
if (roots[i].canWrite()) {
|
|
cmpFiles(cmp, out, roots[i], dout);
|
|
}
|
|
}
|
|
cmp.close();
|
|
out.close();
|
|
if (dout != null) {
|
|
// redumped! Try to delete old file and rename new one.
|
|
dout.close();
|
|
File dump = new File("$$mfs$$.$$$");
|
|
if (logFile.delete()) {
|
|
if (!dump.renameTo(logFile)) {
|
|
System.out.println("ERROR: Could not rename new log to "+logFile.getName()+".");
|
|
}
|
|
} else {
|
|
System.out.println("ERROR: Could not delete old logfile. Redump is still there.");
|
|
}
|
|
}
|
|
return counter;
|
|
}
|
|
|
|
public long dumpDifferences(String outfile) throws IOException {
|
|
return dumpDifferences(outfile, false);
|
|
}
|
|
|
|
/** Removes a line from a log, doesn't touch the file on disk */
|
|
public boolean removeLine(String infile, String filename) {
|
|
try {
|
|
BufferedWriter tout = new BufferedWriter(new OutputStreamWriter(new GZIPOutputStream(new FileOutputStream("$$mfs$$.$$$"))));
|
|
BufferedReader fin = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(infile))));
|
|
String tmp;
|
|
int tab;
|
|
String myfn;
|
|
while ((tmp = fin.readLine()) != null) {
|
|
tab = tmp.indexOf("\t");
|
|
myfn = tmp.substring(tab+1, tmp.indexOf("\t", tab+1));
|
|
if (!myfn.equals(filename)) tout.write(tmp+"\r\n");
|
|
}
|
|
tout.close();
|
|
fin.close();
|
|
File oldlog = new File(infile);
|
|
File newlog = new File("$$mfs$$.$$$");
|
|
if (oldlog.delete()) {
|
|
if (!newlog.renameTo(oldlog)) {
|
|
System.out.println("ERROR: Could not rename new log to "+logFile.getName()+".");
|
|
return false;
|
|
}
|
|
} else {
|
|
System.out.println("ERROR: Could not delete old logfile. Redump is still there.");
|
|
return false;
|
|
}
|
|
return true;
|
|
} catch (IOException ioe) {
|
|
ioe.printStackTrace();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/** Deletes dump */
|
|
public boolean delDump() {
|
|
return logFile.delete();
|
|
}
|
|
|
|
/** Fills a string with preceding zeroes until its length is digits */
|
|
private String formatNumber(int value, int digits) {
|
|
String result = String.valueOf(value);
|
|
while (result.length() < digits) {
|
|
result = "0" + result;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/** Returns the formatted date of the dump file as String */
|
|
public String getDumpDate(File flLog) {
|
|
String result = "";
|
|
if (flLog.exists()) {
|
|
Date dtTime = new Date(flLog.lastModified());
|
|
Calendar clTime = Calendar.getInstance();
|
|
clTime.setTime(dtTime);
|
|
|
|
result += formatNumber(clTime.get(Calendar.YEAR), 4) + "-";
|
|
result += formatNumber(clTime.get(Calendar.MONTH), 2) + "-";
|
|
result += formatNumber(clTime.get(Calendar.DATE), 2) + " ";
|
|
result += formatNumber(clTime.get(Calendar.HOUR_OF_DAY), 2) + ":";
|
|
result += formatNumber(clTime.get(Calendar.MINUTE), 2) + ".";
|
|
result += formatNumber(clTime.get(Calendar.SECOND), 2);
|
|
} else {
|
|
result = "<DOES NOT EXIST>";
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public String getDumpDate() {
|
|
return getDumpDate(logFile);
|
|
}
|
|
|
|
public String getDumpDate(String name) {
|
|
File flLog = new File(name);
|
|
return getDumpDate(flLog);
|
|
}
|
|
|
|
/** Returns a list of data files */
|
|
public String[] getMonitored(String mask) {
|
|
File[] files = sortDir(listFiles(new File("."), true));
|
|
String fn = "";
|
|
String[] result = new String[0];
|
|
String[] tmp;
|
|
for (int i=0;i<files.length;i++) {
|
|
fn = files[i].getName();
|
|
if (fn.length()-mask.length()>0 && fn.substring(fn.length()-mask.length()).equals(mask)) {
|
|
tmp = new String[result.length+1];
|
|
for (int j=0;j<result.length;j++) {
|
|
tmp[j] = result[j];
|
|
}
|
|
tmp[tmp.length-1] = fn.substring(0, fn.length()-mask.length());
|
|
result = tmp;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/** Returns all entries of specified file */
|
|
public String[] getEntries(String fname) {
|
|
File infile = new File(fname);
|
|
String[] result = new String[0];
|
|
String[] tmp;
|
|
String ln;
|
|
int tab;
|
|
try {
|
|
BufferedReader in = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(infile))));
|
|
ln = in.readLine();
|
|
while (ln != null) {
|
|
tmp = new String[result.length+1];
|
|
for (int i=0;i<result.length;i++) {
|
|
tmp[i] = result[i];
|
|
}
|
|
tab = ln.indexOf("\t");
|
|
String fn = ln.substring(tab+1, ln.indexOf("\t", tab+1));
|
|
File fl = new File(fn);
|
|
String status = ln.substring(0, tab);
|
|
if (!fl.exists()) {
|
|
status += "!";
|
|
}
|
|
tmp[tmp.length-1] = status+" "+fn;
|
|
result = tmp;
|
|
ln = in.readLine();
|
|
}
|
|
in.close();
|
|
} catch (Exception ex) {
|
|
ex.printStackTrace();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
} |