I want to determine if a new file or document is placed inside a specific folder/directory using java. For example, There are no files inside the "C:\Users\User\Documents" directory and then I downloaded a pdf file from the Internet and was placed on the mentioned directory. How can I determine if a new file is detected on the directory using java programming language? (It should also print-out the name of the directory and the new file name). Can I have any tips on how to create this kind of program using Java language? It should be continuous or in an infinite loop.
I tried this by using this:
package readfilesfromfolder;
import java.io.File;
public class ReadFilesFromFolder {
public static File folder = new File("C:/Documents and Settings/My Documents/Downloads");
static String temp = "";
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Reading files under the folder "+ folder.getAbsolutePath());
listFilesForFolder(folder);
}
public static void listFilesForFolder(final File folder) {
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
listFilesForFolder(fileEntry);
} else {
if (fileEntry.isFile()) {
temp = fileEntry.getName();
if ((temp.substring(temp.lastIndexOf('.') + 1, temp.length()).toLowerCase()).equals("txt"))
System.out.println("File= " + folder.getAbsolutePath()+ "\\" + fileEntry.getName());
}
}
}
}
}
But based on the outcome, it just accessed the directory but did not list for any new items. Also, it is not yet in loop because I haven't placed it yet. Thank you :) (*Note: I am still new to Java programming :) *)
You could use the Watch Service. A watch service that watches registered objects for changes and events. For example a file manager may use a watch service to monitor a directory for changes so that it can update its display of the list of files when files are created or deleted.
A good example can be found here.
You too can use the Commons IO library from the Apache Foundation, mainly the org.apache.commons.io.monitor package.
Thank you guys for the tip! :) I found out how to do this using the WatchService :)
This is the output based on my research and reading :)
public static void main(String[] args) throws IOException{
// TODO code application logic here
WatchService watchService = FileSystems.getDefault().newWatchService();
//The path needed for changes
Path directory = Paths.get("C:\\Users\\User\\Documents");
//To determine whether a file is created, deleted or modified
//ENTRY_CREATE can be changed to ENTRY_MODIFY and ENTRY_DELETE
WatchKey watchKey = directory.register(watchService, StandardWatchEventKinds.ENTRY_CREATE);
//This portion is for the output of what file is created, modified, or deleted
while (true){
for (WatchEvent<?> event : watchKey.pollEvents()) {
System.out.println(event.kind());
Path file = directory.resolve((Path) event.context());
System.out.println(file);
}
}
}
Hope this can help other people. Thanks also to those who helped me as well as to the authors of different research materials used to create this one :) Credits to Mr.Kriechel for this one :)
Related
I have a problem when reading a text file in java. The class is FlashCardReader and I have the following constructor that handles the part of the reading.
public FlashCardReader( String fileName ) {
try{
reader = new BufferedReader(new FileReader(fileName));
}catch(FileNotFoundException e){
System.out.println("The file was not found or the name may be wrong!");
}
}
My main method looks like this:
public static void main(String[] args) {
FlashCardReader fcr = new FlashCardReader("Questions.txt");
}
And the final output is: The file was not found or the name may be wrong!
Some help would be greatly appreciated, cheers!
You can print the current directory of your java program where it is executed from with this java code,
System.out.println("CurrentDir: " + (new File(".").getCanonicalPath()));
Say it prints,
CurrentDir: D:\pkr\test
Then you can correctly choose a path through which your file can be correctly located.
Most likely, your src folder should be in test directory and in that case you can either move your file from src folder to test folder or refer your file in your code like this,
..\\Questions.txt
which should be able to read your file.
Let me know if this works.
I want to monitor a folder for newly created subfolders for specific .csv files using Java WatchService API (Windows 7 x64, Java 8). I expect the final application like this: folders\files will be created somewhere else and loaded into a cloud (e.g. GDrive). From there I will synchronize them with a local folder (using stock software). This local folder I want to monitor and process files within minutes after they appear. Also very important is not to miss any new files.
I use WatchService as in many tutorials and questions here, but still it behaves strangely.
When the folder (already with files) is created it is both CREATED and MODIFIED - thus two events for a folder. I can live with it, but it sometimes misses files in it completely. (I suppose, files are copied so fast, that they are there even before this new folder is registered and monitored).
When I copy several folders with files at once (F1,F2,F3) then it:
registers F1, detects modified files in F1, processes them, registers F2, registers F3.
Again, the files in the last two folders are not detected anyhow.
Here is a simplified code that I use. I am looking for a cause of this issues and how to make it more robust.
I can cut and paste all files from every new folder and hope then it will detect them, but this is the worst case solution.
More general question - what happens between ws.take() and ws.pollEvents() and ws.reset()? Are there blind-moments, when events are not registered?
public static void main(String args[]) {
// SET UP LOGGER AND CONFIG VARIABLES HERE
// CREATE AN OBJECT AND DEFINE AN ABSTRACT startListening()
WatchServiceClass wsc = new WatchServiceClass() {
public void startListening(WatchService watchService) {
while (true) {
WatchKey queuedKey = watchService.take();
// DOESNT HELP: Thread.sleep(1000);
List<WatchEvent<?>> events = queuedKey.pollEvents();
for (WatchEvent<?> watchEvent : events) {
if (watchEvent.kind() == StandardWatchEventKinds.OVERFLOW) {
continue;
}
String action // create, modify or delete
String fileName // self explanatory
String fullPath
String fullPathParent
if (action.equals("create")) { // TRACK NEW FOLDERS
registerDir(Paths.get(fullPath), watchService);
}
if (new File(fullPath).isDirectory()) {
continue; // NOT DOING ANYTHING WITH DIRECTORIES
}
// IF HERE, THEN THIS IS THE FILE, DO SOMETHING
// TAKES SEVERAL MINUTES
}
if (!queuedKey.reset()) {
keyPathMap.remove(queuedKey);
}
if (keyPathMap.isEmpty()) {
break;
}
}
}
};
// END OF startListening() METHOD DEFINITION
while (true) { // MAIN INFINITE LOOP
try (WatchService watchService = FileSystems.getDefault().newWatchService()) {
wsc.registerDir(Paths.get(DATA_DIR), watchService);
wsc.startListening(watchService);
} catch (Exception e) {
e.printStackTrace();
}
}
}
So I'm trying to create a program in Unix that will take in a directory as a parameter and then recursively go through, open all of the folders, look through all of the files, and then delete all of the class files. I thought I was taking the correct steps as I was given code for a similar program and told to use it as a basis, but upon testing my program and I discover that nothing happens.
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.ParseException;
public class ClassFileDeleter {
public static void main(String[] args) throws ParseException {
String dirName = args[0];
deleteFile(dirName);
}
private static void deleteFile(String dirName) {
Path path = Paths.get(dirName);
File dir = path.toFile();
if(dir.exists()) {
File[] files = dir.listFiles();
if(dir.isDirectory()) {
for(File f:files) {
if(!f.isDirectory())
if(f.toString().endsWith(".class"))
System.out.println("yes");
else deleteFile(dirName + "/" + f.getName());
}}}
}}
I am at a loss at what I should do. I haven't attempted to delete anything yet because I don't want to delete anything that isn't a class file so I am using some dummy code that should print 'yes' once the program finds a class file. However when I run my code, absolutely nothing happens. I believe that there is either an issue with the way I am searching for class files (We are supposed to use endsWith) or with the way I am attempting to use recursion to look through all of the files in the specified directory. If I could have some assistance, that would be great.
I would start with a isFile check (and then test the extension of a file and log it if it matches), then you could recursively descend any directories. Something like,
private static void deleteFile(String dirName) {
File dir = new File(dirName);
if (dir.isFile()) {
if (dir.getName().endsWith(".class")) {
try {
System.out.println("Delete: " + dir.getCanonicalPath());
// dir.delete();
} catch (IOException e) {
e.printStackTrace();
}
}
} else if (dir.isDirectory()) {
File[] files = dir.listFiles();
for (File f : files) {
try {
deleteFile(f.getCanonicalPath());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
It strikes me that the code that you have to recurse through the directory, is creating a file object not a directory.
A quick google gave me this from the Oracle java tutorial (http://docs.oracle.com/javase/tutorial/essential/io/dirs.html#listdir).
Listing a Directory's Contents
You can list all the contents of a directory by using the newDirectoryStream(Path) method. This method returns an object that implements the DirectoryStream interface. The class that implements the DirectoryStream interface also implements Iterable, so you can iterate through the directory stream, reading all of the objects. This approach scales well to very large directories.
Remember: The returned DirectoryStream is a stream. If you are not using a try-with-resources statement, don't forget to close the stream in the finally block. The try-with-resources statement takes care of this for you.
The following code snippet shows how to print the contents of a directory:
Path dir = ...;
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
for (Path file: stream) {
System.out.println(file.getFileName());
}
} catch (IOException | DirectoryIteratorException x) {
// IOException can never be thrown by the iteration.
// In this snippet, it can only be thrown by newDirectoryStream.
System.err.println(x);
}
The Path objects returned by the iterator are the names of the entries resolved against the directory. So, if you are listing the contents of the /tmp directory, the entries are returned with the form /tmp/a, /tmp/b, and so on.
This method returns the entire contents of a directory: files, links, subdirectories, and hidden files. If you want to be more selective about the contents that are retrieved, you can use one of the other newDirectoryStream methods, as described later in this page.
Note that if there is an exception during directory iteration then DirectoryIteratorException is thrown with the IOException as the cause. Iterator methods cannot throw exception exceptions.
So I'd take a look there and see what you can work out.
I would like to locate a file named SAVE.properties. I have looked at different questions that seem like they would answer me, but I can't see that they do.
For example, I would like to check to see whether or not SAVE.properties exists within a directory (and its subfolders).
I would also like to know how I could save a .properties file (and then read it afterwards from this location) to the directory where my program is being run from. If it is run from the desktop, it should save the .properties file there.
Saving properties can easily be achieved through the use of Properties#store(OutputStream, String), this allows you to define where the contents is saved to through the use of an OutputStream.
So you could use...
Properties properties = ...;
//...
try (FileOutputStream os = new FileOutputStream(new File("SAVE.properties"))) {
properties.store(os, "Save");
} catch (IOException exp) {
exp.printStackTrace();
}
You can also use Properties#load(InputStream) to read the contents of a "properties" file.
Take a closer look at Basic I/O for more details.
Locating a File is as simple as using
File file = new File("SAVE.properties");
if (file.exists) {...
This checks the current working directory for the existence of the specified file.
Searching the sub directories is little more involved and will require you to use some recursion, for example...
public File find(File path) {
File save = new File(path, "SAVE.properties");
if (!save.exists()) {
save = null;
File[] dirs = path.listFiles(new FileFilter() {
#Override
public boolean accept(File pathname) {
return pathname.isDirectory();
}
});
for (File dir : dirs) {
save = find(dir);
if (save != null) {
break;
}
}
}
return save;
}
Using find(new File(".")) will start searching from the current working directory. Just beware, under the right circumstances, this could search your entire hard disk.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Copying files from one directory to another in Java
How can I move all files from one folder to other folder with java?
I'm using this code:
import java.io.File;
public class Vlad {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
// File (or directory) to be moved
File file = new File("C:\\Users\\i074924\\Desktop\\Test\\vlad.txt");
// Destination directory
File dir = new File("C:\\Users\\i074924\\Desktop\\Test2");
// Move file to new directory
boolean success = file.renameTo(new File(dir, file.getName()));
if (!success) {
System.out.print("not good");
}
}
}
but it is working only for one specific file.
thanks!!!
By using org.apache.commons.io.FileUtils class
moveDirectory(File srcDir, File destDir) we can move whole directory
If a File object points to a folder you can iterate over it's content
File dir1 = new File("C:\\Users\\i074924\\Desktop\\Test");
if(dir1.isDirectory()) {
File[] content = dir1.listFiles();
for(int i = 0; i < content.length; i++) {
//move content[i]
}
}
Since Java 1.7 there is java.nio.file.Files which offers operations to work with files and directories. Especially the move, copy and walkFileTree functions might be of interest to you.
You can rename the directory itself.
You can iterate over files in directory and rename them one-by-one. If directory can contain subdirectories you have to do this recursively.
you can use utility like Apache FileUtils that already does all this.