Get the number of files in a folder, omitting subfolders - java

Is the any way to get the number of files in a folder using Java?
My question maybe looks simple, but I am new to this area in Java!
Update:
I saw the link in the comment. They didn't explained to omit the subfolders in the target folder.
How to do that? How to omit sub folders and get files in a specified directory?
Any suggestions!!

One approach with pure Java would be:
int nFiles = new File(filename).listFiles().length;
Edit (after question edit):
You can exclude folders with a variant of listFiles() that accepts a FileFilter. The FileFilter accepts a File. You can test whether the file is a directory, and return false if it is.
int nFiles = new File(filename).listFiles( new MyFileFilter() ).length;
...
private static class MyFileFilter extends FileFilter {
public boolean accept(File pathname) {
return ! pathname.isDirectory();
}
}

You will need to use the File class. Here is an example.

This method allows you to count files inside the folder without loading all files into memory at once (which is good considering folders with big amount of files which could crash your program), and you can additionaly check file extension etc. if you put additional condition next to f.isFile().
import org.apache.commons.io.FileUtils;
private int countFilesInDir(File dir){
int cnt = 0;
if( dir.isDirectory() ){
Iterator it = FileUtils.iterateFiles(dir, null, false);
while(it.hasNext()){
File f = (File) it.next();
if (f.isFile()){ //this line weeds out other directories/folders
cnt++;
}
}
}
return cnt;
}
Here you can download commons-io library: https://commons.apache.org/proper/commons-io/

Related

Adding files from folder to the list in android app

I'm trying to create a list of files in my sdcard (and then get a random one from this list).
I've read tutorials but none of those worked.
My code is as following:
try{
File file=new File("/sdcard");
File[] list = new File ("/sdcard").listFiles();
ArrayList<String> lista = new ArrayList<String>();
for (File f : list){
if (f.isFile()){
if (f.getName().startsWith("aa")){
lista.add(f.getName());
}
}
}
Random gen = new Random();
String s = lista.get(gen.nextInt(lista.size()-1)).toString();
wyswietl.setText(s);
}catch(NullPointerException e){
Log.e("nope", e.getMessage());
}
LogCat shows exceptions.
I've checked every single line - when I try to show lista.size() - it throws ResourcesNotFoundException.
What interesting is, changing String s into
String s = lista.get(1).toString()
works - it shows me one of the files in the folder.
So my question is: how can I fix this and get a list of files (which start with "aa") in /sdcard folder?
If you want to pick one random item in array list, I believe it should be
String s = lista.get(gen.nextInt(lista.size()));
Random.nextInt(int n) retrieves random value between 0-(n-1). See Random.nextInt() documentation.
ResourceNotFound exception I believe is related to failure to locate resource ID inside R.java not index out of bound exception.
TextView.setText() with integer value parameter, interprets integer value as a resource ID, see here. So if you call
atextView.setText(lista.size());
It will throw ResourceNotFoundException because it may not point to correct resource ID. If you want to display number of items in list then
atextView.setText(String.valueOf(lista.size()));
If lista.size () equals 0 then exception can occur...
( because gen.nextInt (-1) )
I hope you to prevent it.
Here is the different way to the filter on list of file based on file name !!!!
File f = new File("/sdcard");
String fileList[];
if(f.isDirectory()){
fileList = f.list(new FilenameFilter() {
#Override
public boolean accept(File dir, String name) {
// TODO Auto-generated method stub
if (name.startsWith("aa")){
return true;
}
return false;
}
});
'FileList' is an array where you get all the File object and then you can easily get the file name from that!!!!
Hope this will help!!!
I've found the solution why this code didn't work. The files weren't in the folder yet - i had to add names to the list manually, then in other function check if they are on sdcard (if not, there is need to copy; if yes, I can display the content).

Searching files in a directory and pairing them based on a common sub-string

I have been attempting to program a solution for ImageJ to process my images.
I understand how to get a directory, run commands on it, etc etc. However I've run into a situation where I now need to start using some type of search function in order to pair two images together in a directory full of image pairs.
I'm hoping that you guys can confirm I am on the right direction and that my idea is right. So far it is proving difficult for me to understand as I have less than even a month's worth of experience with Java. Being that this project is directly for my research I really do have plenty of drive to get it done I just need some direction in what functions are useful to me.
I initially thought of using regex but I saw that when you start processing a lot of images (especially with imagej which it seems does not dump data usage well, if that's the correct way to say it) that regex is very slow.
The general format of these images is:
someString_DAPI_0001.tif
someString_GFP_0001.tif
someString_DAPI_0002.tif
someString_GFP_0002.tif
someString_DAPI_0003.tif
someString_GFP_0003.tif
They are in alphabetical order so it should be able to go to the next image in the list. I'm just a bit lost on what functions I should use to accomplish this but I think my overall while structure is correct. Thanks to some help from Java forums. However I'm still stuck on where to go to next.
So far here is my code: Thanks to this SO answer for partial code
int count = 0;
getFile("C:\");
string DAPI;
string GFP;
private void getFile(String dirPath) {
File f = new File(dirPath);
File[] files = f.listFiles();
while (files.length > 0) {
if (/* File name contains "DAPI"*/){
DAPI = File f;
string substitute to get 'GFP' filename
store GFP file name into variable
do something(DAPI, GFP);
}
advance to next filename in list
}
}
As of right now I don't really know how to search for a string within a string. I've seen regex capture groups, and other solutions but I do not know the "best" one for processing hundreds of images.
I also have no clue what function would be used to substitute substrings.
I'd much appreciate it if you guys could point me towards the functions best for this case. I like to figure out how to make it on my own I just need help getting to the right information. Also want to make sure I am not making major logic mistakes here.
It doesn't seem like you need regex if your file names follow the simple pattern that you mentioned. You can simply iterate over the files and filter based on whether the filename contains DAPI e.g. see below. This code may be oversimplification of your requirements but I couldn't tell that based on the details you've provided.
import java.io.*;
public class Temp {
int count = 0;
private void getFile(String dirPath) {
File f = new File(dirPath);
File[] files = f.listFiles();
if (files != null) {
for (File file : files) {
if (file.getName().contains("DAPI")) {
String dapiFile = file.getName();
String gfpFile = dapiFile.replace("DAPI", "GFP");
doSomething(dapiFile, gfpFile);
}
}
}
}
//Do Something does nothing right now, expand on it.
private void doSomething(String dapiFile, String gfpFile) {
System.out.println(new File(dapiFile).getAbsolutePath());
System.out.println(new File(gfpFile).getAbsolutePath());
}
public static void main(String[] args) {
Temp app = new Temp();
app.getFile("C:\\tmp\\");
}
}
NOTE: As per Vogel612's answer, if you have Java 8 and like a functional solution you can have:
private void getFile(String dirPath) {
try {
Files.find(Paths.get(dirPath), 1, (path, basicFileAttributes) -> (path.toFile().getName().contains("DAPI"))).forEach(
dapiPath -> {
Path gfpPath = dapiPath.resolveSibling(dapiPath.getFileName().toString().replace("DAPI", "GFP"));
doSomething(dapiPath, gfpPath);
});
} catch (IOException e) {
e.printStackTrace();
}
}
//Dummy method does nothing yet.
private void doSomething(Path dapiPath, Path gfpPath) {
System.out.println(dapiPath.toAbsolutePath().toString());
System.out.println(gfpPath.toAbsolutePath().toString());
}
Using java.io.File is the wrong way to approach this problem. What you're looking for is a Stream-based solution using Files.find that would look something like this:
Files.find(dirPath, 1, (path, attributes) -> {
return path.getFileName().toString().contains("DAPI");
}).forEach(path -> {
Path gfpFile = path.resolveSibling(/*build GFP name*/);
doSomething(path, gfpFile);
});
What this does is:
Iterate over all Paths below dirPath 1 level deep (may be adjusted)
Check that the File's name contains "DAPI"
Use these files to find the relevant "GFP"-File
give them to doSomething
This is preferrable to the files solution because of multiple things:
It's significantly more informative when failing
It's cleaner and more terse than your File-Based solution and doesn't have to check for null
It's forward compatible, and thus preferrable over a File-Based solution
Files.find is available from Java 8 onwards

Is there an easy way to find files by extension type to put them into a File array in Java?

I've searched and searched, and I'm looking for a library or method that will allow me to find files in the current directory by extension, (.zip for example). I want to load these into a File array. I know I can get all the files in a directory with listfiles() then do some logic to get just the zip files, but I was wondering if I'm just doing too much work to accomplish this. I do not want to use any third party libraries.
Use File.listFiles(FilenameFilter).
Since FilenameFilter is a single method interface, you can implement it using a lambda expression in Java 8.
File[] files = new File(".").listFiles((dir, name) -> name.endsWith(".zip"));
Or with an anonymous class in any Java version:
File[] files = new File(".").listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.endsWith(".zip");
}
});
Update
Since file extensions are normally not case-sensitive, you might want to use:
name.toLowerCase().endsWith(".zip")
File provides a overloaded 'listFiles' method where you can pass an FileNameFilter.
You can instantiate the 'FileNameFilter' as an anonymous class.
The following will return all Files which ends with .txt
File f = new File("/path/to/directory");
String ext = ".txt";
File[] arr = f.listFiles(new FilenameFilter() {
#Override
public boolean accept(File dir, String name) {
return name.endsWith(ext);
}
});

How to find out if a directory is under or above another directory in the file system hierarchy

I am currently working on a project which is an implementation similar to FTP. For this, I need to implement virtual chrooting, which should also work on Windows platforms.
My current approach is that each user has a specific home directory (represented by a File object) and every time the user is trying to access a file or directory, the server will check whether this file or directory is inside this home directory or not.
Sadly, I am not sure, how I can implement this check in a way that is not taking up too much CPU time and HDD access time. One could simply try to walk up the directories and if we land on a directory that equals the given home directory, we are satisfied. If we reach the root directory, we return falsebecause it's very likely that the given file is not inside the home directory.
I am sure this check would work, but I also assume that this would be very costly and maybe very unefficient in a multi-user environment.
I would appreciate any help to design this algorithm better. Maybe there even exists a method for that? I did not find one yet though.
Thanks in advance!
// EDIT: As requested, here are some examples for this file structure
- /
- home/
- user1/
- file1.txt
- file2.txt
- user2/
- picture.png
- someDir/
We assume 2 users ("user1" and "user2") with the home directories "/home/user1" for user1 and "/home/user2" for user2.
The method I am looking for should give the following results, if applied on this scenario:
isInsideHome("/home/user2/picture.png", "user1") -> false
isInsideHome("/home/user1/file1.txt", "user1") -> true
isInsideHome("/", "user1") -> false
isInsideHome("/home", "user2") -> false
I hope these examples clarify what I am looking for.
Assuming you're not calling methods such as createNewFile(), exists() etc java.io.File doesn't require HDD access, and will only minimal CPU.
For example, none of following paths exist on my computer, but the code executes without exception.
public static void main(String[] args) {
System.out.println(isInsideHome("/home/user2/picture.png", "user1"));
System.out.println(isInsideHome("/home/user1/file1.txt", "user1"));
System.out.println(isInsideHome("/", "user1"));
System.out.println(isInsideHome("/home", "user2"));
}
private static boolean isInsideHome(String pathStr, String leaf) {
File path = new File(pathStr);
File search = new File(leaf);
while ((path = path.getParentFile()) != null) {
if (search.getName().equals(path.getName())) {
return true;
}
}
return false;
}
The source for java.io.File.getParentFile() shows that no HDD access is involved...
public static void main(String[] args) {
System.out.println(isInsideHome("/home/user2/picture.png", "user1"));
System.out.println(isInsideHome("/home/user1/file1.txt", "user1"));
System.out.println(isInsideHome("/", "user1"));
System.out.println(isInsideHome("/home", "user2"));
}
private static boolean isInsideHome(String pathStr, String leafStr) {
File path = new File(pathStr);
File leaf = new File(leafStr);
while ((path = path.getParentFile()) != null) {
if (leaf.getName().equals(path.getName())) {
return true;
}
}
return false;
}

Read files in directory and (if any) copy to folder [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Copying files from one directory to another in Java
I have a folder (c:/InstallationFiles) with .jar files in it. i want to read through it and if the name equals test1 i want to copy it to a test1 folder, then if the name is test2 copy it to a test2 folder etc. this is what i have so far:
private static int copyJARFiles() {
resultCode = 0;
File installFolder = new File(Constants.WINDOWS + Constants.INSTALLATION_FOLDER);
File[] installFiles = installFolder.listFiles();
for (int i = 0; i < installFiles.length; i++) {
if (installFiles[i].equals("test1.jar")){
}
if (installFiles[i].equals("test2.jar")){
}
}
return resultCode;
}
not sure how to copy it then. im still a rookie.
thank you / kind regards
if you want to copy jar:
You can use apache IO api. Use the below code:
FileUtils.copy(sourceFile,destinationFile);
You can also use java 7. It contains direct function to copy files.
if you want extract jar:
You can use java.util.zip.*; package classes.
Please let me know if you need more explanation.
Not sure I fully understood your task but maybe this example will help you
for (File f : installFolder.listFiles()) {
if (f.getName().endsWith(".jar")) {
File targetDir = new File(installFolder, f.getName().replace(".jar", ""));
if (!targetDir.exists()) {
targetDir.mkdir();
}
File target = new File(targetDir, f.getName());
Files.copy(f.toPath(), target.toPath());
}
}
The main idea is that Java 7 provides us with Files.copy util

Categories