I know how to read file one by one from a folder in java.But I want to know If I give a folder named Search and in Search folder it has 3 different folders named A,B,C and each folder has multiple text files.I want to read all files which has in A,B,C folder by giving folder name Search as user input.can it be possible? I am new in java.
Sure it is. This sounds like you want to walk a folder (meaning, you want to do something for every file in a given folder, and for every subfolder in that folder, and for every file in that subfolder, and for every subfolder in the subfolder, ad infinitum, until you've seen everything).
You can handroll a recursive algorithm yourself using Files.newDirectoryStream, or, just use the existing API:
Path folderToWalk = Paths.get("/path/to/folder");
Files.walkFileTree(folderToWalk, new SimpleFileVisitor<Path>() {
#Override public visitFile(Path f, BasicFileAttributes attrs) throws IOException {
// this is invoked for _every_ file anywhere in the folder structure.
}
});
You can also add methods that are called if a file cannot be visited (for example, because of access rights issues), as well as if you want to get directory names - see the API.
Within visitFile, you can do whatever you want. For example, if you want to fully read the file into a string, you can invoke Files.readString(f);. See the Files API for all the stuff you can do*.
*) You said 'I know how to read...' - it's possible you've learned the obsolete, outdated java.io.FileInputStream API. Don't use that - use the Files API. It is less boneheaded about errors and charset encoding, gives you more stuff (such as giving you access to the file owner's name and group, and softlinks), and more high-level API primitives, such as 'just read the whole thing into a string for me please', and, 'just walk this entire file tree for me please'.
Related
I'm working on a project which, in part, displays all the files in a directory in a JTable, including sub-directories. Users can double-click the sub-directories to update the table with that new directory's content. However, I've run into a problem.
My lists of files are generated with file.listFiles(), which pulls up everything: hidden files, locked files, OS files, the whole kit and caboodle, and I don't have access to all of them. For example, I don't have permission to read/write in "C:\Users\user\Cookies\" or "C:\ProgramData\ApplicationData\". That's ok though, this isn't a question about getting access to these. Instead, I don't want the program to display a directory it can't open. However, the directories I don't have access to and the directories I do are behaving almost exactly the same, which is making it very difficult to filter them out.
The only difference in behavior I've found is if I call listFiles() on a locked directory, it returns null.
Here's the block of code I'm using as a filter:
for(File file : folder.listFiles())
if(!(file.isDirectory() && file.listFiles() == null))
strings.add(file.getName());
Where 'folder' is the directory I'm looking inside and 'strings' is a list of names of the files in that directory. The idea is a file only gets loaded into the list if it's a file or directory I'm allowed to edit. The filtering aspect works, but there are some directories which contain hundreds of sub-directories, each of which contains hundreds more files, and since listFiles() is O(n), this isn't a feasible solution (list() isn't any better either).
However,
file.isHidden() returns false
canWrite()/canRead()/canExecute() return true
getPath() returns the same as getAbsolutePath() and getCanonicalPath()
createNewFile() returns false for everything, even directories I know are ok. Plus, that's a solution I'd really like to avoid even if that worked.
Is there some method or implementation I just don't know to help me see if this directory is accessible without needing to parse through all of its contents?
(I'm running Windows 7 Professional and I'm using Eclipse Mars 4.5.2, and all instances of File are java.io.File).
The problem you have is that you are dealing with File. By all accounts, in 2016, and, in fact, since 2011 (when Java 7 came out), it has been superseded by JSR 203.
Now, what is JSR 203? It is a totally new API to deal with anything file systems and file system objects; and it extend the definition of a "file system" to include what you find on your local machine (the so called "default filesystem" by the JDK) and other file systems which you may use.
Sample page on how to use it: here
Among the many advantages of this API is that it grants access to metadata which you could not access before; for instance, you specifically mention the case, in a comment, that you want to know which files Windows considers as "system files".
This is how you can do it:
// get the path
final Path path = Paths.get(...);
// get the attributes
final DosAttributes attrs = Files.readAttributes(path, DosFileAttributes.class);
// Is this file a "system file"?
final boolean isSystem = attrs.isSystem();
Now, what is Paths.get()? As mentioned previously, the API gives you access to more than one filesystem at a time; a class called FileSystems gives access to all file systems visible by the JDK (including creating new filesystems), and the default file system, which always exists, is given by FileSystems.getDefault().
A FileSystem instance also gives you access to a Path using FileSystem#getPath.
Combine this and you get that those two are equivalent:
Paths.get(a, b, ...)
FileSystems.getDefault().getPath(a, b, ...)
About exceptions: File handles them very poorly. Just two examples:
File#createNewFile will return false if the file cannot be created;
File#listFiles will return null if the contents of the directory pointed by the File object cannot be read for whatever reason.
JSR 203 has none of these drawbacks, and does even more. Let us take the two equivalent methods:
File#createNewFile becomes Files#createFile;
File#listFiles becomes either of Files#newDirectoryStream (or derivatives; see javadoc) or (since Java 8) Files#list.
These methods, and others, have a fundamental difference in behaviour: in the event of a failure, they will throw an exception.
And what is more, you can differentiate what exception this is:
if it is a FileSystemException or derivative, the error is at the filesystem level (for instance, "access denied" is an AccessDeniedException);
if is is an IOException, then the problem is more fundamental.
This answer cannot contain each and every use case of JSR 203; this API is vast, very complete, although not without flaws, but it is infinitely better than what File has to offer in any case.
I faced the very same problem with paths like C://users/myuser/cookies.
I already used JSR203, so the above answer kind of didn't help me.
In my case the important attribute of those files was the hidden one.
I ended up using the FileSystemview, which excluded those files as I wanted.
File[] files = FileSystemView.getFileSystemView().getFiles(new File(strHomeDirectory), !showHidden);
I know about the Methods in FileUtils, but the FileUtils won't overwrite.
Also in Files.move("", "", StandardCopyOption.REPLACE_EXISTING) when the file exists and it's not empty, then the following exception is thrown: java.nio.file.DirectoryNotEmptyException
Sample:
/file1/test1
/file2/test1
How do I merge, move, and overwrite (such as move in windows), /file1/test1 to /file2/test1 ?
has java function for this job? I want don't write any method
You could do naive approach with standard java util functions, and nit with Files.
First, write a method, what will move and overwrite one file. Before moving, check if the file with this name is is the target folder and delete it, what is simpler, (or open end overwrite content, what is unnecessary complicated).
Then, get the list of all files in source folder and apply the method above in the loop.
my task:
input parameter - path to file. This path may not contain any folders. I want create all folder structure and create file.
my current decision:
File file = new File("D:\\nonexistingFolder\\folder2\\1.txt");
file.getParentFile().mkdirs();
file.createNewFile();
Is it possible to simplify this code? For example to replace 2 second lines with single
I don't think Java has a short hand for that. You need to use mkdirs() method for this. Java 7 introduced a Files class which has createDirectories method, but that too doesn't satisfy your requirement. However you can use Apache Commons FileUtils class. Eg:
FileOutputStream file = FileUtils.openOutputStream(new File("D:\\nonexistingFolder\\folder2\\1.txt"));
This will create intermediate folders and file for you. Apparantly it'll be using all those step underneat. Its just a personal choice whether or not to add a third party library for just avoiding 2 lines of code.
In most other languages / operating system I've worked with, a statement like
File f = new File(....);
would attempt to open the file, and either create one if it didn't exist, or return an error code if it was missing. So, what happens in java.io? I'd like to understand the mindset of the run time engine. Can I actually get a handle to a non-existent file? Dose the java run time engine hold off on making the file until the 1st time I write to it? If not, shouldn't
if(f.exists()) {…}
always be “true”?
- any comments welcome - Joe
As described in the Javadoc, java.io.File represents a path, not a file. Bad naming. Think of operations on File as path operations, because that's what they are. Unless something specifically says that it creates a file at a given path, it doesn't.
You can create a File by creating a reference to a non existing File. If you pass that File to a FileOutputsteam the Stream will create the File on your drive.
So if you cant be certain that the File doesnt exist you need to be able to check its existence with f.exists() othwerwise you wouldnt be able to make an intelligent decision on how to proceed
From the Android Developers official documentation you can read that a File is:
An "abstract" representation of a file system entity identified by a
pathname.
The actual file referenced by a File may or may not exist. It may
also, despite the name File, be a directory or other non-regular file.
I'm working on a small application in Java that takes a directory structure and renames the files according to a certain format, after parsing the original name.
What is the best Java class / methodology to use in order to facilitate these file operations?
Edit: the question is only regarding the file operations part, I got the "getting the formatted name" down :)
Edit 2: Also, how do I list files recursively?
Use java.io.File
Listing all files in a directory
http://www.javaprogrammingforums.com/java-code-snippets-tutorials/3-how-list-all-files-directory.html
File folder = new File(path);
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
// Do something with "listOfFiles[i]"
}
UPDATE
To list the files recursively, your best approach is fairly easy:
Create a queue of directories. Initially add the first directory to the queue
Pop the first directory element off the queue.
List all files in that directory, same as above
Iterate over all the files in that directory
If a file is a directory (use isDirectory() method), add it to the back of the queue.
Else, process this next file as needed (e.g. print)
Stop when the queue is empty.
An example (I think a bit different from my approach above) is http://www.javapractices.com/topic/TopicAction.do?Id=68
Renaming a file
http://www.roseindia.net/java/example/java/io/RenameFileOrDir.shtml
boolean Rename = oldfile.renameTo(newfile);
Finding a new name to rename to
I'm not sure what you want the formatting rules to be - when I implemented the same utility in Perl for my own use I used Regular Expressions. For Java, that'd be java.util.regex
This Sun Totorial could be a good start. If I where you I would basically retrieve all the files in the directory and then loop through them, as shown here. You might have to use regular expressions as well, a basic tutorial can be found here
You can always use the standard java.io.File class, but it's primitive and not very useful on its own.
For complex file-I/O operations, I recommend using Apache Commons IO, which provides a rich class library for (among other things) file operations. See classes like FileUtils and FilesystemUtils
There's the class File, that does all you need:
listFiles()
renameTo()