my output has \.
my expected output is:
temp/F1.java
temp/F2.java
temp/subtemp/F3.java
What's wrong?..................................................................................................................................................................................................................
public class FileFinder
{
public static void main(String[] args) throws IOException
{
File dir1 = new File("temp");
dir1.mkdir() ;
File f1 = new File("temp/F1.java") ;
f1.createNewFile() ;
File f2 = new File("temp/F2.java") ;
f2.createNewFile() ;
File dir2 = new File("temp/subtemp") ;
dir2.mkdir() ;
File f3 = new File("temp/subtemp/F3.java") ;
f3.createNewFile() ;
find(dir1, ".java");
}
/**
Prints all files whose names end in a given extension.
#param aFile a file or directory
#param extension a file extension (such as ".java")
*/
public static void find(File aFile, String extension)
{
//-----------Start below here. To do: approximate lines of code = 10
// 1. if aFile isDirectory
if (aFile.isDirectory()) {
//2. use listFiles() to get an array of children files
File[] children = aFile.listFiles();
//3. use sort method of Arrays to sort the children
Arrays.sort(children);
//4. for each file in the sorted children
for (File child : children) {
//5. recurse
find(child, extension);
}
}//
else {//
//6. otherwise the file is not a directory, so
//use toString() to get the file name
String fileName = aFile.toString();
//7. use replace() to change '\' to '/'
fileName.replace('\'' , '/');
//8. if the file name endsWith the extension
if (fileName.endsWith(extension)) {
//9. then print it.
System.out.println(fileName);
}
}
//-----------------End here. Please do not remove this comment. Reminder: no changes outside the todo regions.
}
}
You need to escape the slash. Currently you're escaping a single quote instead.
Change:
fileName.replace('\'' , '/');
To:
fileName = fileName.replace('\\' , '/');
replace() doesn't change the value, you'd have to save it again which is what I did above.
this code
fileName.replace('\'' , '/');
is changing a ' to a / and to use replaceAll which uses regexp
what you want is
fileName.replaceAll("\\" , "/");
but actually - why bother with this code at all, you are not even saving the result of the replace. For that you would need
fileName = fileName.replaceAll("\\" , "/");
Related
I have written a find function which is like this :
public static List<File> find ( String path, String fName) {
List<File> list = new ArrayList<>() ;
File dir = new File(path) ;
if( dir. isDirectory() ) {
for( String aChild : dir. list()) {
list = find(path + File.separator + aChild, fName) ;
}
}
else {
File[] files = dir. listFiles ( (d, name) -> name. startsWith(fName) && name. endsWith(".txt")) ;
for(File fl : files)
list. add(fl) ;
}
return list;
}
The Directory structure on my Local machine is like C:\Salary with sub directories like January, February etc. Each of the sub directory contains files like 601246_jan_sal.txt or 601246_ feb_sal.txt.
I am calling the find function like
List<File> filePath = Utils. find("C:\\Salary\\", "601246") ;
And then performing operation on each individual file.
The problem is that in the find method dir.listFiles(FileNameFilter) is returning null value.
What am I doing wrong?
Below is basically the same method with the exception that is uses regex along with the String#matches() method to determine a file name match. I used regex so that the ? and * wildcard characters can be used within your file name search criteria, for example:
"601246*.txt"
You may find this useful for other searches you might like to carry out.
There is no returned object with this method, you just need to pass the List to it. Here is an example of how you might use it:
List<File> fileList = new ArrayList<>();
String searchCriteria = "601246*.txt";
searchFolder(new File("C:\\Salary"), searchCriteria, fileList);
// Display found files within the Console Window:
if (!fileList.isEmpty()) {
for (File file : fileList) {
System.out.println(file.getAbsolutePath());
}
}
else {
System.out.println("File name (" + searchCriteria + ") can not be found!");
}
This will search the directory (and all its sub-directories) located at C:\Salary within the local file system for all files that start with 601246 and ends with .txt. Since your files are in the following format:
601246_jan_sal.txt or 601246_ feb_sal.txt
and you happen to want all the files for February Sales, your search criteria might be: *feb?sal.txt.
Here is the searchFolder() method:
/**
* This method navigates through the supplied directory and any
* sub-directories contained within it for the supplied file name search
* criteria. Anything found is placed within the supplied List object.<br>
*
* #param file (File) The starting point directory (folder) in
* the local file system where the file(s) search
* should begin.<br>
*
* #param searchCriteria (String) The name of the file to search for. The
* wildcard characters '?' and '*' can also be used
* within the search criteria. Using an asterisk (*)
* allows you to replace a string of text. This is
* often useful if you know what kind of file you’re
* looking for but don’t know where it is or what
* certain name parts might be. <br><br>
*
* The wildcard '?' lets you use it to replace any character in a search.
* This means that if you’re looking for a file and you’re not sure how it
* is spelled, you can simply substitute '?' for the characters you don’t
* know. In the following example, we search for files that start with
* “img_2” and ends with “.jpg”:<pre>
*
* img_2???.jpg</pre><br>
*
* #param list (List Interface of type File: {#code List<File>})
* This would be the List of File you pass to this
* method. It will be this list that is filled with
* found files objects.<br>
*
* #param ignoreLetterCase (Optional - Boolean) Default is true. The search
* is not letter case sensitive. If false is
* supplied then the search is letter case
* sensitive.
*/
public static void searchFolder(File file, String searchCriteria, List<File> list, boolean... ignoreLetterCase) {
boolean ignoreCase = true;
if (ignoreLetterCase.length > 0) {
ignoreCase = ignoreLetterCase[0];
}
// Convert the supplied criteria string to a Regular Expression
// for the String#matches() method
String regEx = searchCriteria.replace("?", ".").replace("-", ".").replace("*", ".*?");
if (ignoreCase) {
regEx = "(?i)" + regEx;
}
if (file.isDirectory()) {
//System.out.println("Searching directory ... " + file.getAbsoluteFile());
//do you have permission to read this directory?
if (file.canRead()) {
for (File temp : file.listFiles()) {
if (temp.isDirectory()) {
searchFolder(temp, searchCriteria, list, ignoreCase);
}
else {
if (temp.getName().matches(regEx)) {
list.add(temp);
}
}
}
}
else {
System.err.println(file.getAbsoluteFile() + " - PERMISSION DENIED!");
}
}
}
Since you are using recursion, you should pass the list (of files) as a parameter to method find and not create a new list on each invocation. Hence the method find does not need to return a value.
public static void find(String path, String fName, List<File> fileList) {
File dir = new File(path);
if (dir.isDirectory()) {
for (File aChild : dir.listFiles()) {
if (aChild.isDirectory()) {
find(aChild.getAbsolutePath(), fName, fileList);
}
else {
String name = aChild.getName();
if (name.startsWith(fName) && name.endsWith(".txt")) {
fileList.add(aChild);
}
}
}
}
else {
String name = aChild.getName();
if (name.startsWith(fName) && name.endsWith(".txt")) {
fileList.add(aChild);
}
}
}
If method parameter path indicates a directory, then list the files in that directory. For each file in the directory, check whether the name of the file matches your search criteria and if it does then add it to the list. If it doesn't then check if it is itself a directory and if it is then recursively call method find with the new directory.
Initially call method find like so
List<File> list = new ArrayList<File>();
find("C:\\Salary\\", "601246", list);
Now list should contain the list of relevant files. So the following line will print the contents of list
System.out.println(list);
I see a fundamental problem in your logic that answers your question. Here are the key lines along with an explanation:
if( dir.isDirectory() ) {
....
}
else {
File[] files = dir.listFiles(...); // <- "dir" is a file, not a directory
for(File fl : files)
list.add(fl) ;
}
You check if File object dir represents a directory. If that test fails (ie: it's not a directory), then you call dir.listFiles on it and assign the result to files. But if it's not a directory, then by the definition of that function, it will return null. It seems that if the check for a directory fails, you should just add the object to list instead of performing another operation on it.
I think you want this:
if( dir.isDirectory() ) {
....
}
else {
list.add(dir) ;
}
I guess dir isn't really the right name for the variable here, as it isn't always a directory.
Note that the Files.walk() method already does what you're trying to do.
public static List<File> find ( String path, String fName) {
List<File> result = new ArrayList<>();
FileVisitor<Path> visitor = new SimpleFileVisitor() {
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
if (attrs.isRegularFile()) {
String name = file.getFileName();
if (name.startsWith(fName) && name.endsWith(".txt")) {
result.add(file.toFile());
}
}
return FileVisitResult.CONTINUE;
}
};
Files.walk(Paths.get(path), visitor);
return result;
}
I am trying to search files from sd card so i can delete multiple and duplicate files.``
private List<String> searchForFileNameContainingSubstring(String substring)
{
path = Environment.getExternalStorageDirectory().getPath() + "/";
//This is assuming you pass in the substring from input.
File file = new File(path); //Change this to the directory you want to search in.
List<String> filesContainingSubstring = new ArrayList<String>();
if (file.exists() && file.isDirectory())
{
String[] files = file.list(); //get the files in String format.
for (String fileName : files)
{
if (fileName.contains(substring))
filesContainingSubstring.add(fileName);
}
}
for (String fileName : filesContainingSubstring)
{
System.out.println(fileName); //or do other operation
}
return filesContainingSubstring; //return the list of filenames containing substring.
}
How can i scan other sub folders from sdcard/ directories
It only shows results from sdcard directories
You can use Apache Common's FileUtils.listFiles method.
You can search recursively throughout a folder by setting the third parameter as true.
Also, you can target specific file extensions by passing in the second argument a String array as seen below. If you want to target any extensions pass null.
Note: the extensions names do not include '.' it's "jpg" and not ".jpg"
String[] extensions = {"png","jpg"};
Collection images = FileUtils.listFiles(new File("dirPath"),extensions, true);
for (Object obj : images){
File file = (File) obj;
// your code logic
}
I'd like to create a function to do the following: to replace an arbitrary string filled with potential "../" and "./" in the middle of it, to point to an absolute file name with the dots and extraneous slashes removed. ex: /data/data/org.hacktivity.datatemple/../../data/./org.hacktivity.datatemple/
private String validDirectory( String baseDirectory, String addOn ) {
if ( baseDirectory + addOn ISN'T A VALID DIRECTORY ) {
Toast(error);
return baseDirectory;
}
else {
// ex: /data/data/org.hacktivity.datatemple/../org.hacktivity.datatemple/ => /data/data/org.hacktivity.datatemple
return TRIMMED VERSION OF baseDirectory + addOn;
}
}
You are searching for the canonicalPath of a File object. Use getCaconicalPath() or getCanonocalFile() to eliminate relative path elements:
File baseDir = new File(baseDirectory);
File addOnDir = new File(baseDir, addOn);
String canonicalPath = addOnDir.getCanonicalPath();
System.out.println(canonicalPath); // /data/data/org.hacktivity.datatemple
I'm writing a program that does various data analysis functions for use with Excel.
I need a way of returning file names of documents so I can search through them and find the ones I want.
I need to be able to take a string, saved as a variable, and use it to return the name of every document in a folder whose file name contains that string.
This will be used to sift through pre-categorized sections of data. Ideally I would save those documents' file names in a string array for later use within other functions.
private List<String> searchForFileNameContainingSubstring( String substring )
{
//This is assuming you pass in the substring from input.
File file = new File("C:/Users/example/Desktop"); //Change this to the directory you want to search in.
List<String> filesContainingSubstring = new ArrayList<String>();
if( file.exists() && file.isDirectory() )
{
String[] files = file.list(); //get the files in String format.
for( String fileName : files )
{
if( fileName.contains( substring ) )
filesContainingSubstring.add( fileName );
}
}
for( String fileName : filesContainingSubstring )
{
System.out.println( fileName ); //or do other operation
}
return filesContainingSubstring; //return the list of filenames containing substring.
}
Using this method, you could pass in the input from the user as the string you want the filename to contain. The only other thing you need to change is where you want in your directory to start searching for files, and this program only looks in that directory.
You could further look recursively within other directories from the starting point, but I won't add that functionality here. You should definitely look into it though.
This also assumes that you are looking for everything within the directory, including other folders and not just files.
You can get the list of all the files in a directory and then store them in an array. Next, using the java.io.File.getName() method, you can get the names of the files. Now you can simply use the .indexOf() method to check whether the string is a substring of the file name. I assume that all the items in the directory of concern are files and not sub directories.
public static void main(String[] args) throws IOException {
File[] files = new File("X:/").listFiles(); //X is the directory
String s <--- the string you want to check filenames with
for(File f : files){
if(f.getName().toLowerCase().indexOf(s.toLowerCase()) != -1)
System.out.println(f.getName());
}
}
This should display the names of all those files in the directory X:\ whose names include the String s.
References
This question: How do I iterate through the files in a directory in Java?
The java.io.File.getName() method
Statutory edit info
I have edited this answer simply to replace the previous algorithm, for checking the existence of a substring in a string, with the one that is currently used in the code above.
Here is an answer to search the file recursively??
String name; //to hold the search file name
public String listFolder(File dir) {
int flag;
File[] subDirs = dir.listFiles(new FileFilter() {
#Override
public boolean accept(File pathname) {
return pathname.isDirectory();
}
});
System.out.println("File of Directory: " + dir.getAbsolutePath());
flag = Listfile(dir);
if (flag == 0) {
System.out.println("File Found in THe Directory: " + dir.getAbsolutePath());
Speak("File Found in THe Directory: !!" + dir.getAbsolutePath());
return dir.getAbsolutePath();
}
for (File folder : subDirs) {
listFolder(folder);
}
return null;
}
private int Listfile(File dir) {
boolean ch = false;
File[] files = dir.listFiles();
for (File file : files) {
Listfile(file);
if (file.getName().indexOf(name.toLowerCase()) != -1) {//check all in lower case
System.out.println(name + "Found Sucessfully!!");
ch = true;
}
}
if (ch) {
return 1;
} else {
return 0;
}
}
I am working on a program that must print the names of each file and subfolder in a given directory.
So far I have the following (this is just the working code):
File directory = new File( [the path] );
File[] contents = directory.listFiles();
for ( File f : contents )
{
String currentFile = f.getAbsolutePath();
System.out.println( currentFile );
}
This needs to be displayed to the user, who doesn't need to see the full path. How can I get the output to only be the file names?
This should help you
File directory = new File("\\your_path");
File[] contents = directory.listFiles();
for (File f : contents) {
System.out.println(f.getName());
}
I suppose that sometimes you might not know the path base (for whatever reason), so there is a way to split the String. You just cut the part before the slash (/) and take all that's left. As you split it, there might be (and probably is) multiple slashes so you just take the last part
String currentFile;
String[] parts;
for ( File f : contents) {
currentFile = f.getAbsolutePath();
parts = currentFile.split("/");
if (!parts.equals(currentFile)) {
currentFile = parts[parts.length-1];
}
System.out.println(currentFile);
}
Example:
"file:///C:/Users/folder/Desktop/a.html" goes to be "a.html"
The file name is being printed as a simple String, meaning that it can be edited. All you have to do is use Str.replace on your path.
This code currentFile = currentFile.replace("[the path]", ""); would replace your file path with a blank, effectively erasing it.
Some code inserted correctly, such as
for ( File f : contents)
{
currentFile = f.getAbsolutePath();
currentFile = currentFile.replace("[the path]", "");
System.out.println(currentFile);
}
will do this for each file your program finds.