Java Forum / General / January 2007
systematic file(s) deletion
NickName - 19 Dec 2006 20:52 GMT Hi,
Say, I have a bunch of files sitting under C:\Program Files\ThisProgram\DataFiles directory, and I'm running out of disk space, so, I'd like to sysmatically remove all the file that is more than two days old under this directory. How would I do that?
Please work with me through the following semi-code.
// first, need to point to/move to this directory, how? /* There's this method to find out current directory, System.getProperty("user.dir"); is there any method that would set current directory such as System.setProperty("user.dir") = "C:\Program Files\ThisProgram\DataFiles"; ?? */ ...
// now, we're ready to instantiate the directory File dir = new File("MyDirectoryName");
// use var children as file names, use array to store them String[] children = dir.list(); // validation if (children == null) { // Either dir does not exist or is not a directory } else { // some sort of preparation int c = 0; Date today = new Date();
// iteration of files for (int i=0; i<children.length; i++) { // Get filename of file or directory String filename = children[i]; // debug to display files System.out.println(filename);
// find each file's date/time stamp // var c for file counter, increment it c++;
// could we use dynamic var name like "file"&c where "file" is string and c is var value? File "file"&c = new File(filename); long "file"&c&"date = "file"&c.lastModified;
/* now compare each file's date stamp against today's date if it's two days old delete it, DatePart? How to? */ ... // delete file boolean del = (new File("file"&c)).delete();
} }
Better way? Many thanks in advance.
Daniel Dyer - 19 Dec 2006 21:01 GMT > Hi, > [quoted text clipped - 15 lines] > */ > ... I'd use the find command (under Cygwin on Windows). The command would look something like this (I have tested to make sure this is correct):
find "C:\Program Files\ThisProgram\DataFiles" -mtime 3 -exec rm -f {} \;
Dan.
 Signature Daniel Dyer http://www.uncommons.org
Daniel Dyer - 19 Dec 2006 21:02 GMT > I'd use the find command (under Cygwin on Windows). The command would > look something like this (I have tested to make sure this is correct): Sorry, I meant *haven't* tested (as in don't blame me if it trashes your file system).
Dan.
 Signature Daniel Dyer http://www.uncommons.org
NickName - 20 Dec 2006 19:58 GMT > > I'd use the find command (under Cygwin on Windows). The command would > > look something like this (I have tested to make sure this is correct): [quoted text clipped - 7 lines] > Daniel Dyer > http://www.uncommons.org Ok, I just looked up info on Cygwin. It would not be applicable to what I need in my working environment. Additionally, I'd like to use this case to learn more basics on file manipulation in java. Thanks though.
Oliver Wong - 20 Dec 2006 20:36 GMT > Hi, > [quoted text clipped - 14 lines] > Files\ThisProgram\DataFiles"; ?? > */ The concept of a "current" directory isn't well defined in Java, possibly because it isn't well defined across all the OSes that Java supports. If you wanted to make this an actual utility for users to use, best to have the user provide the path to the directory they want to operate on as a command line argument or something similar.
> ... > [quoted text clipped - 24 lines] > // could we use dynamic var name like "file"&c where "file" is > string and c is var value? No, you can't use "dynamic var names" in the way that you described. The closest thing I can think of to what you're trying to do is to use an array. But a simpler way would be to not keep around a reference to every file you're going to work with, but rather to just keep a reference to the single file you're currently working with at that time.
> File "file"&c = new File(filename); > long "file"&c&"date = "file"&c.lastModified; File doesn't have a publicly accessible "lastModified" field, but it has a lastModified() method which you can invoke.
> /* now compare each file's date stamp against today's date if > it's two days old delete it, > DatePart? How to? */ Numerical comparison is typically done via the >, >=, ==, !=, =< and < operators.
> ... > // delete file [quoted text clipped - 4 lines] > > Better way? Many thanks in advance. This is probably a dangerous program to learn Java with, since you might mistakenly delete data that you don't want to delete by accidentally introducing bugs into your program. Why not write a less destructive program for the purposes of learning? Maybe one that merely *lists* all files older than a certain age, and leaves it up to the user to manually delete them?
- Oliver
NickName - 26 Dec 2006 22:29 GMT Thanks for the very helpful advice, pls see below.
[...]
> The concept of a "current" directory isn't well defined in Java, > possibly because it isn't well defined across all the OSes that Java > supports. If you wanted to make this an actual utility for users to use, > best to have the user provide the path to the directory they want to operate > on as a command line argument or something similar. Good idea of letting user to provide this via a param, however, the downside, could be a typo in the path, so, maybe let user select a directory would be good.
> No, you can't use "dynamic var names" in the way that you described. The > closest thing I can think of to what you're trying to do is to use an array. > But a simpler way would be to not keep around a reference to every file > you're going to work with, but rather to just keep a reference to the single > file you're currently working with at that time. Good to know.
> > File "file"&c = new File(filename); > > long "file"&c&"date = "file"&c.lastModified; > > File doesn't have a publicly accessible "lastModified" field, but it has > a lastModified() method which you can invoke. My typo, it should have read "file"&c.lastModified[];
> > /* now compare each file's date stamp against today's date if > > it's two days old delete it, > > DatePart? How to? */ > > Numerical comparison is typically done via the >, >=, ==, !=, =< and < > operators. Good to know. A specific date comparison question below.
// list all files under Temp folder. File dir = new File("Temp");
String[] children = dir.list(); if (children == null) { // Either dir does not exist or is not a directory } else { for (int i = 0; i < children.length; i++) { // Get filename of file or directory String filename = children[i];
if ((new Date()) - (new Date(filename.???()))) > 30 // find file(s) that is older than 30 days // what method to use?
{ System.out.println("\nTemp: " + filename); } } }
> > ... > > // delete file [quoted text clipped - 10 lines] > for the purposes of learning? Maybe one that merely *lists* all files older > than a certain age, and leaves it up to the user to manually delete them? Well, I could use a TEMP directory, data there are no longer of value.
> - Oliver John Ersatznom - 27 Dec 2006 01:11 GMT > Thanks for the very helpful advice, pls see below. > [quoted text clipped - 9 lines] > downside, could be a typo in the path, so, maybe let user select a > directory would be good. There's something called JFileChooser that you might find interesting if so. :)
NickName - 27 Dec 2006 16:12 GMT > > Thanks for the very helpful advice, pls see below. > > [quoted text clipped - 12 lines] > There's something called JFileChooser that you might find interesting if > so. :) Good to know. Thanks. Could you answer the following question?
A specific date comparison question below.
// list all files under Temp folder. File dir = new File("Temp");
String[] children = dir.list(); if (children == null) { // Either dir does not exist or is not a directory } else { for (int i = 0; i < children.length; i++) { // Get filename of file or directory String filename = children[i];
if ((new Date()) - (new Date(filename.???()))) > 30 // find file(s) that is older than 30 days // what method to use?
{ System.out.println("\nTemp: " + filename); } } }
John Ersatznom - 29 Dec 2006 15:13 GMT > if ((new Date()) - (new Date(filename.???()))) > 30 > // find file(s) that is older than 30 days > // what method to use? Check out the API docs, particularly Date's compareTo and File's lastModified methods.
http://java.sun.com/j2se/1.5.0/docs/api/
Oliver Wong - 27 Dec 2006 17:21 GMT > String filename = children[i]; > [quoted text clipped - 3 lines] > days > // what method to use? The File class has a method to get the date of last modification, called lastModified(). You have an instance of a String, which presumably represents the path to a file. File also has a constructor which accepts a String.
- Oliver
NickName - 27 Dec 2006 22:04 GMT > > String filename = children[i]; > > [quoted text clipped - 10 lines] > > - Oliver Right. Initially I used the lastModified() method, the code looked like, if ((new Date()) - (new Date(filename.lastModified())) > 30 // find file(s) that is older than 30 days // assumed the millseconds and whatever Date() produces would // be able to auto convert? But it failed to compile. Or am I wrong?
Many thanks.
Oliver Wong - 27 Dec 2006 22:36 GMT > Right. Initially I used the lastModified() method, the code looked > like, [quoted text clipped - 4 lines] > // be able to auto convert? > But it failed to compile. Or am I wrong? Invoke lastModified() on the date, not the string.
new Date(filename).lastModified()
- Oliver
NickName - 28 Dec 2006 16:30 GMT > > Right. Initially I used the lastModified() method, the code looked > > like, [quoted text clipped - 10 lines] > > - Oliver NickName - 28 Dec 2006 16:31 GMT > > Right. Initially I used the lastModified() method, the code looked > > like, [quoted text clipped - 10 lines] > > - Oliver Thanks. Made change accordingly, however, the following code still won't work if ((new Date()) - (new Date(filename).lastModified())) > 30 { System.out.println("\nTemp files older than 30 days: " + filename); };
Also, tried, System.out.println(new Date(filename).getTime()); for testing, won't work neither. What's wrong?
Oliver Wong - 28 Dec 2006 18:42 GMT > Thanks. Made change accordingly, however, the following code still > won't work [quoted text clipped - 6 lines] > System.out.println(new Date(filename).getTime()); > for testing, won't work neither. What's wrong? In the future, when something "won't work", you should probably state what results you got (your computer exploded? You got a compile error? A runtime exception? The program runs fine, but didn't do what you expected it to do?), what results you expected (the program is supposed to calculate the fibbonacci sequence? Determine prime factors?), and how they differed (in case the difference is too subtle for us to notice).
I'm guessing that you had some sort of compile error in the first case, and I have no idea what results you got with the second case (maybe a ParseException? Or it ran but with results you didn't understand nor expect?)
The problem in the first case is that you're applying the subtraction operator on a Date object, "(new Date()) - [something]" when the subtraction operator is only defined on numbers. Based on the text in your println() statement, it looks like you're testing whether a file is older than 30 days.
If that's the case, notice that the string that you supply to the Date constructor is supposed to represent a date, and not a filename. E.g. the contents of the string should look like "Jan 1st, 2007" and not "C:\myfile.txt".
- Oliver
NickName - 28 Dec 2006 22:20 GMT >> [...] >> [quoted text clipped - 22 lines] > > - Oliver Ok. Sorry for not providing exact err msg.
Now, here's the latest attempt. Many thanks.
// test output today's day extraction, divide milliseconds System.out.println("test date manipulation:" + (new Date().getTime()) / (8640000)); // result: successful
// list files
File dir = new File("Temp");
String[] children = dir.list(); if (children == null) { // Either dir does not exist or is not a directory } else { for (int i = 0; i < children.length; i++) { // Get filename of file or directory String filename = children[i]; File fd = new File(filename); long ftime = fd.lastModified();
// test output of the file day value System.out.println(ftime); // result: 0 // comment: bad // question: what's wrong?
// System.out.println("now = " + new Date().getTime()); /* debug */ // 1000 * 60 * 60 * 24 = 1 day = 8640000
// System.out.println((new File(filename).lastModified()) / (8640000)); /* if ( (new Date().getTime()) / (8640000) - (new File(filename).lastModified()) / (8640000) ) > 30 { System.out.println("\nTemp files older than 30 days: " + filename); }; */ }
Oliver Wong - 28 Dec 2006 23:23 GMT >> In the future, when something "won't work", you should probably state >> what results you got (your computer exploded? You got a compile error? A [quoted text clipped - 3 lines] >> the >> fibbonacci sequence? Determine prime factors?), and how they differed (in [...]
> Now, here's the latest attempt. [code snipped]
Okay. Does it work and you're just showing it to us, or is there some problem and you want us to help you fix the problem?
- Oliver
EJP - 29 Dec 2006 04:22 GMT >>Right. Initially I used the lastModified() method, the code looked >>like, [quoted text clipped - 8 lines] > > new Date(filename).lastModified() Nonsense. Date doesn't have a lastModified() method. What you need is
if ((System.getCurrentTimeMillis() - (filename.lastModified()) > 30*24*60*60*1000L)
Oliver Wong - 29 Dec 2006 15:27 GMT >>>Right. Initially I used the lastModified() method, the code looked >>>like, [quoted text clipped - 13 lines] > if ((System.getCurrentTimeMillis() - (filename.lastModified()) > > 30*24*60*60*1000L) You're right about the date not having a lastModified method, but neither does filename, which I suspect is a String.
In other words, the OP really needs to address the usenet issues I've been addressing before we can hope to seriously help with the problem: Post an SSCCE, state exactly what the problem is (it won't compile? An exception is thrown? Something else?), and state what the program is supposed to do.
Without this information, everyone will be confused (as demonstrated by my error, and EJP's error, etc.) and will give incorrect advice.
I've lost the motivation to help NickName, and probably will not regain this motivation until the SSCCE and other issues above are addressed.
- Oliver
NickName - 29 Dec 2006 16:47 GMT [...]
> In other words, the OP really needs to address the usenet issues I've > been addressing before we can hope to seriously help with the problem: Post [quoted text clipped - 8 lines] > > - Oliver /* objective: list files in the Temp directory that are 30 days older than today's date */
/* one way to solve the problem: compare today's date with each file's dateTimeStamp */
// specifically, the technique to use here is to get today's date value by // using (new Date().getTime()) / (8640000));
// and another technique of using File Class's lastModified() method // to get "similar" value for the date of each file // this technique works with "known" file, see a case below.
File fileD = new File("TestFile.txt"); long fdate = fileD.lastModified(); System.out.println("\t and it was last edited on " + fdate);
// here's the clean code with Comments
// list files // the Temp directory has 10 files, of which one file name includes white spaces
File dir = new File("Temp");
String[] children = dir.list(); if (children == null) {
} else { for (int i = 0; i < children.length; i++) {
String filename = children[i]; File fd = new File(filename);
// debug: to print out each file name System.out.println(fd); // result: yes it does
long ftime = fd.lastModified(); // test output of the file day value System.out.println(ftime); // result: 0 // comment: bad // question: what's wrong?
}
Oliver Wong - 29 Dec 2006 18:28 GMT > long ftime = fd.lastModified(); > // test output of the file day value > System.out.println(ftime); > // result: 0 > // comment: bad > // question: what's wrong? This is much better. See the javadocs http://java.sun.com/javase/6/docs/api/java/io/File.html
<quote> Returns: A long value representing the time the file was last modified, measured in milliseconds since the epoch (00:00:00 GMT, January 1, 1970), or 0L if the file does not exist or if an I/O error occurs </quote>
So either the file does not exist, or an I/O error occurred. Did you try checking the output of fd.exists() ?
- Oliver
NickName - 29 Dec 2006 20:14 GMT > > long ftime = fd.lastModified(); > > // test output of the file day value [quoted text clipped - 17 lines] > > - Oliver Ok, I now changed the code to the following (please see embeded comments) below:
// list files // the Temp directory has 10 files, of which one file name includes white spaces
File dir = new File("Temp");
String[] children = dir.list(); if (children == null) {
} else { for (int i = 0; i < children.length; i++) {
String filename = children[i];
// test file existence boolean exist = (new File(filename)).exists(); if (exist) { System.out.println(filename); } else { System.out.println("file instantiation failed for " + filename + "why? because it has already been instantiated?"); }
}
Thanks. Would this technique not be able to solve this problem?
Oliver Wong - 29 Dec 2006 21:15 GMT >> > long ftime = fd.lastModified(); >> > // test output of the file day value [quoted text clipped - 50 lines] > > Thanks. Would this technique not be able to solve this problem? I'm not sure what problem you're referring to when you say "this problem". It won't magically create a file, if that's the problem you're trying to solve. Not that whether or not a file exists on the file system has nothing to do with the JVM's instantiation of objects. Consider this example code to gain some enlightment as to what the exist() does:
public class Example {
public static boolean checkFileExists(String pathToFile) { File temp = new File(pathToFile); return temp.exists(); }
public static void main(String[] args) { if (checkFileExists("C:/autoexec.bat")) { System.out.println("You have an autoexec.bat file in the root of your C drive."); } else { System.out.println("You don't have an autoexec.bat file in the root of your C drive."); } } }
Notice that this program always instantiates exactly 1 file object, regard of whether or not you have an autoexec.bat file on your file system.
- Oliver
NickName - 03 Jan 2007 22:09 GMT > [ ... ] > > [quoted text clipped - 28 lines] > > - Oliver Thank you very much for the interesting example. With your code, you have a public class, which has a method, and the method is being called by the class itself, and here you have a basic flow control construct. And the famous String class (external) is being called/used.
Would you add a constructor somewhere with the code? Or probably I need to read on the OOP concepts a bit before asking more questions. Once again, I appreciated.
Oliver Wong - 04 Jan 2007 21:19 GMT [...]
>> public class Example { >> [quoted text clipped - 23 lines] > have a public class, which has a method, and the method is being called > by the class itself, I don't like this phrasing, "the method is being called by the class itself". I prefer to think that the JVM "magically" starts a main thread, and has that main thread call my static void main method.
> and here you have a basic flow control construct. > And the famous String class (external) is being called/used. I don't think it makes sense to say a class is called. Only methods can be called. And Strings are used in my example, yes, but that's wasn't the main focus of the example. It's about as significant, IMHO, to the fact that the character 'e' was used in typing out that source code. It's a true statement, but not very relevant.
> Would you add a constructor somewhere with the code? I'm not sure I understand the question. If I wanted to add a constructor, I could certainly do so, but I didn't want to add one, which is why the example didn't contain one. Are you asking me to add a constructor to the example to demonstrate how it might be done, or are you asking something else?
- Oliver
NickName - 05 Jan 2007 14:46 GMT [ ...]
> Are you asking me to add a constructor > to the example to demonstrate how it might be done? > > - Oliver Yes, thank you in advance.
Oliver Wong - 08 Jan 2007 19:20 GMT > [ ...] > >> Are you asking me to add a constructor >> to the example to demonstrate how it might be done? > > Yes, thank you in advance. public class Example {
public Example() { /*A constructor which doesn't do anything.*/ }
public static boolean checkFileExists(String pathToFile) { File temp = new File(pathToFile); return temp.exists(); }
public static void main(String[] args) { if (checkFileExists("C:/autoexec.bat")) { System.out.println("You have an autoexec.bat file in the root of your C drive."); } else { System.out.println("You don't have an autoexec.bat file in the root of your C drive."); } } }
- Oliver
Lew - 09 Jan 2007 04:34 GMT >>> Are you asking me to add a constructor >>> to the example to demonstrate how it might be done? "NickName" wrote in message
>> Yes, thank you in advance.
> public class Example { > public Example() { > /*A constructor which doesn't do anything.*/ > } ...
> } Oliver, you are a patient and generous person.
- Lew
Oliver Wong - 09 Jan 2007 15:52 GMT >>>> Are you asking me to add a constructor >>>> to the example to demonstrate how it might be done? [quoted text clipped - 10 lines] > > Oliver, you are a patient and generous person. I can't help but think there must be a misunderstanding somewhere, but I haven't figured out where the misunderstanding lies yet. Perhaps the problem was that the OP did not know the appropriate syntax for adding a constructor to a class.
- Oliver
NickName - 10 Jan 2007 22:54 GMT > >>>> Are you asking me to add a constructor > >>>> to the example to demonstrate how it might be done? [quoted text clipped - 17 lines] > > - Oliver "Perhaps the problem was that the OP did not know the appropriate syntax for adding a constructor to a class. "
Yes, thanks for the note as well as the sample for a Constructor construction. The little java doc that I got from JBuilder IDE talks a little bit about Constructor, however, I still don't know if when a constructor is required for a class and when it is not.
Oliver Wong - 10 Jan 2007 23:06 GMT > Yes, thanks for the note as well as the sample for a Constructor > construction. The little java doc that I got from JBuilder IDE talks a > little bit about Constructor, however, I still don't know if when a > constructor is required for a class and when it is not. Whenever you create an object using the "new" keyword (e.g. "new Foo()"), a new instance of the appropriate object is created, and then the constructor is immediately invoked on that new instance. If you haven't written a constructor, then the compiler will automatically provide a default constructor which doesn't do anything.
See http://java.sun.com/docs/books/tutorial/java/javaOO/constructors.html
- Oliver
John Ersatznom - 15 Jan 2007 14:17 GMT > Yes, thanks for the note as well as the sample for a Constructor > construction. The little java doc that I got from JBuilder IDE talks a > little bit about Constructor, however, I still don't know if when a > constructor is required for a class and when it is not. A constructor is required for a class if either * the instances need some initialization of their state, particularly in a parametrized way so you need an explicit constructor that takes arguments, or * you want to restrict instance creation, so you need to make constructors protected or private or package-private, or both.
As for syntax for things like this, that and anything else truly basic and fundamental is documented at java.sun.com; particularly, check out the Java Tutorial there and the class library API docs. Those two are the most crucial references to know; bookmark them in your browser and be thankful they're free-as-in-beer! (As you grow more experienced, the API docs will increase and the Tutorial decrease in relative importance to you. Third party libraries and their API docs will become of interest at some point too. One wonderful thing about Java in general is how well-documented everything tends to be, and how avoidable paying for big doorstops tends to be. For most other languages you need at least one big fat "Essential C++" or "colored book" or "animal book" or something of the sort to make any headway!)
see@signature.invalid - 30 Dec 2006 02:24 GMT > > This is much better. See the javadocs > > http://java.sun.com/javase/6/docs/api/java/io/File.html
> Ok, I now changed the code to the following (please see embeded > comments) below: [quoted text clipped - 16 lines] > } > Thanks. Would this technique not be able to solve this problem? Note that you didn't tell us the results of running your updated code, but I'm fairly certain that it reported that "file instantiation failed ...". (By the way, File.exists() does not instantiate the file, it only checks for its existence.)
So, go back and read the javadocs referenced above. Look at the wording for the definition of function File.list(). Now compare that to the wording of File.getName() and File.getPath(). Pay particular attention to the distinction between the terms "name" and "pathname."
In any case, you might consider using File.listFiles() instead of File.list(), which would both save you a step or two and, more than likely, incidentally eliminate your symptoms.
- dmw
NickName - 03 Jan 2007 21:48 GMT > [ ... ] > [quoted text clipped - 14 lines] > > - dmw The docs are very helpful, thank you.
EJP - 30 Dec 2006 01:21 GMT > String[] children = dir.list(); > if (children == null) { [quoted text clipped - 4 lines] > String filename = children[i]; > File fd = new File(filename); File fd = new File(dir, filename);
NickName - 03 Jan 2007 22:00 GMT > > String[] children = dir.list(); > > if (children == null) { [quoted text clipped - 6 lines] > > File fd = new File(dir, filename); Thanks. It's almost there. The revised code per your instruction above looks like this: String[] children = dir.list(); if (children == null) {
} else { for (int i = 0; i < children.length; i++) {
String filename = children[i];
File fd = new File(dir, filename); long ft = (fd.lastModified()/(8640000));
long now = (new Date().getTime() / (8640000));
if ( (now - ft)/10 > 30) { System.out.println("\nTemp files older than 30 days: " + filename); }
Comments: 1) Currently the (now - ft)/10 formula would seem to generate a date difference value between TODAY and a file's date from the list. However, previously when I used a test file, doing something like
File testFile = new File("myTest.txt"); Long testFileDate = testFile.lastModified();
then, the formula of (now - testFileDate) // now, as long now = (new Date().getTime() / (8640000)); would yield a date difference 2 if the myTest.txt is two days old.
How come? Thanks.
John Ersatznom - 04 Jan 2007 11:15 GMT > long now = (new Date().getTime() / > (8640000)); Is it your intention for "now" to be in units of tenths of a day? :)
NickName - 04 Jan 2007 16:23 GMT > > long now = (new Date().getTime() / > > (8640000)); > > Is it your intention for "now" to be in units of tenths of a day? :) I "stole" the following formula long now = (new Date().getTime() / (8640000)); from the net and thought it was for a day. What formular would be for a day?
Thanks.
John Ersatznom - 06 Jan 2007 02:25 GMT >>> long now = (new Date().getTime() / >>>(8640000)); [quoted text clipped - 5 lines] > from the net and thought it was for a day. What formular would be for > a day? 1000 ms in a s * 60 s in a m * 60 m in an h * 24 h in a day gives 86400000 -- with one more zero.
NickName - 08 Jan 2007 19:57 GMT > >>> long now = (new Date().getTime() / > >>>(8640000)); [quoted text clipped - 8 lines] > 1000 ms in a s * 60 s in a m * 60 m in an h * 24 h in a day gives > 86400000 -- with one more zero. Thanks.
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|