Basically, I'm just trying to run a list of all the files in a folder using the list function from the Java File class:
artistList = (new File(myPathName)).list();
But what I get is some missing files, even after I have "show hidden files" in Windows 7. I'm wondering where these files are.
If it helps, the path I'm searching in is a folder like /media which I have organized into /media/artist/album/title.mp3 for all my song data. The extra files I end up finding up are AlbumArt jpeg files (and I used songbird version 9 beforehand to sort the folders first, I'm just trying to rename the match the ID3 tags myself with a small Java program).
With the organisation you descibed there will be no media files in the directory /media where your search / listing starts, you have to navigate trought subdirectories untill you reach /media/artist/album from there on you can get files that you actualy looking for. Also you might have to add a filter to list method and implement the filter's accept method to kick out thumbnails and hidden meta-files.
Here a piece of code (untested) that could help you
private final static Set<String> mediaExtensions;
static {
mediaExtensions = new HashSet<String>();
mediaExtensions.add(".mp3");
mediaExtensions.add(".wav");
mediaExtensions.add(".ogg");
// and so on
}
public static void list(File file, List<File> result) {
if(file.isFile()) {
result.add(file);
} else if(file.isDirectory()) {
File files[] = file.listFiles(new FileFilter() {
#Override
public boolean accept(File pathname) {
boolean accept = false;
int i = pathname.getName().lastIndexOf('.');
if(i != -1) {
String ext = pathname.getName().substring(i);
accept = (! pathname.isHidden()) &&
mediaExtensions.contains(ext);
}
return accept;
}
});
if(files != null) {
for(File f : files) {
list(f, result);
}
}
}
}
Related
I need to find a file name from the list of filenames and to initiate two methods according to the found result. I tried:
FileList result = service.files().list()
.setPageSize(10)
.setFields("nextPageToken, files(id, name)")
.execute();
List<File> files = result.getFiles();
if (files == null || files.size() == 0) {
System.out.println("No files found.");
} else {
System.out.println("Files:");
for (File file : files) {
System.out.printf("%s (%s)\n", file.getName(), file.getId());
Boolean found = files.contains("XYZ");
if(found)
{
insertIntoFolder();
} else {
createFolder();
}
}
}
I need to find XYZ (the filename) from a list of file names (like sjh, jsdhf, XYZ, ASDF). Once I've found it I need to stop the search. If the name doesn't match the list of names I need to create a folder only once after checking all names from that list.
Boolean found = files.contains("XYZ");
This line is problematic. files is a list of File objects, none of which will match the String "XYX". List.contains() essentially calls Object.equals() on every element of the list, and File.equals("XYZ") will always return false.
If you're programming in an IDE like Eclipse it should show a warning on this line, since it's a bug that can be detected at compile-time.
To determine if a File in a List<File> has a filename matching a given string you need to operate on the filename itself, so the above line should instead be:
boolean found = file.getName().equals("XYZ");
Depending on what exactly you're trying to match you might want to use .getName(), .getAbsolutePath(), or .toString().
It's also a good idea to use the Path API introduced in Java 7, rather than File, which is essentially a legacy class at this point.
If you want a more elegant solution than manually looping over files looking for a match you can use Files.newDirectoryStream(Path, Filter) which allows you to define a Filter predicate that only matches certain files, e.g.
Files.newDirectoryStream(myDirectory, p -> p.getFileName().toString().equals("XYZ"))
File.list(FilenameFilter) is a similar feature for working with File objects, but again, prefer to use the Path API if possible.
Here is a example:
/**
* return true if file is in filesList else return false
*/
static boolean isFileInList(File file, List<File> filesList) {
for(File f: filesList) {
if (f.equals(file)) {
return true;
}
}
return false;
}
public static void main(String[] args) {
List<File> files;// the filelist; make sure assign these two variable.
File file; // the file you want to test.
if (isFileInList(file, files)) {
//file is presented
} else {
//file is not presented
createFolder();
}
}
package test;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
public class DirectoryContents {
public static void main(String[] args) throws IOException {
File f = new File("."); // current directory
FilenameFilter textFilter = new FilenameFilter() {
public boolean accept(File dir, String name) {
String lowercaseName = name.toLowerCase();
if (lowercaseName.endsWith(".txt")) {
return true;
} else {
return false;
}
}
};
File[] files = f.listFiles(textFilter);
for (File file : files) {
if (file.isDirectory()) {
System.out.print("directory:");
} else {
System.out.print(" file:");
}
System.out.println(file.getCanonicalPath());
}
}
}
I have the below code to get the lastest modified file by given directory and the prefix of the filename.
When I ran the HPE fortify analysis it gave me "Path manipulation" findings.
Can you guys guide me how to fix this finding?
What is the best and secure approach to access filesystem for a web application?
public static File getLatestFilefromDirWithFileName(String archivesDirectoryPath, String fileStartWith){
File archivesDirectory = new File(archivesDirectoryPath);
FilenameFilter textFilter = new FilenameFilter() {
public boolean accept(File dir, String name) {
if (name.startsWith(fileStartWith)) {
return true;
} else {
return false;
}
}
};
File[] filesInArchiveDir = archivesDirectory.listFiles(textFilter);
if (filesInArchiveDir == null || filesInArchiveDir.length == 0) {
return null;
}
File lastModifiedFile = filesInArchiveDir[0];
for (int i = 1; i < filesInArchiveDir.length; i++) {
if (lastModifiedFile.lastModified() < filesInArchiveDir[i].lastModified()) {
lastModifiedFile = filesInArchiveDir[i];
}
}
return lastModifiedFile;
}
You must ensure that archivesDirectoryPath do not allow to access sensible folders.
One way to do it, is to validate that the specified folder will be located in a white list of location. This white list could either be define in your code or configurable by "administrator" users. Trying to process a folder that is not on this list should raise Exception.
You can check that no /../ are used in folder name, but checking that the resulting folder is part of your white list should be enough.
I am not asking how to check if a file exists or how to check if a file is in a specific directory level. Rather I want to know how to check if an existing file is anywhere underneath a specified directory.
Obviously if a file is a direct child of a directory that is easy to check. But what I want to be able to do is efficiently check if an existing file is in a directory including any possible subdirectory. I'm using this in an Android project where I am keeping fine grain control over my cache and I want a utility method to check if a file I may be manipulating is in my cache folder.
Example:
cache dir
/ \
dir file1
/ \
file2 file3
isCacheFile(file2) should return true
Currently I have a method that does it like so
private static final File cacheDir = AssetManager.getInstance().getCacheDir(); // Not android.content.res.AssetManager
private static final String cacheDirName = cacheDir.getAbsolutePath();
public static boolean isCacheFile(File f) {
if (!f.exists()) return false;
return f.getAbsolutePath().startsWith(cacheDirName);
}
However, I am inclined to believe there is a better way to do this. Does anyone have any suggestions?
If you have a known path (in the form of File f), and you want to know if it is inside a particular folder (in the form of File cacheDir), you could simply traverse the chain of parent folders of your file and see if you meet the one you are looking for.
Like this:
public static boolean isCacheFile(File f) {
while (f.getParentDir()!=null) {
f = f.getParentDir();
if (f.equals(cacheDir)) {
return true;
}
}
return false;
}
boolean isContains(File directory){
File[] contents = directory.listFiles();
if (contents != null) {
for(int i = 0; i < contents.length; i++){
if(contents[i].isDirectory())
isContains(contents[i]);
else if(contents[i].getName().equals(*your_file_name*))
return true;
}
}
return false;
}
You could do it by recursion, by calling if the file exists in each sub-directory.
first check if the file exists in the root directory.
boolean exist = new File(rootDirectory, temp).exists();
then if the file wasn't in the root directory, then list all the files and call the method again in the sub-directoy files recursionally until you find the file or there are no more sub-directories.
public String getPathFromFileName(String dirToStart,Sring fileName){
File f = new File(dirToStart);
File[] list = f.listFiles();
String s="null";
for(int i=0;i<list.length;i++){
if(list[i].isFile()){
//is a file
if(fileName.equals(list[i])){
s=dirToStart+"/"+fileName;
break;
}
}else{
//is a directory search further.
getPathFromFileName(dirToStart+list[i]);
}
}
return s;
}
call this method by passing the parent directory name and the file name to search in subdirectories.
you check the return value if it is not equal to "null", then the files path is returned.
Ok so part of my program searches the C drive for all mp3 files, the only problem is that it won't go into and subfolders. Here is my code so far.
public static List<String> ListFiles() {
List<String> files = new ArrayList<String>();
File folder = new File("C:/");
File[] listOfFiles = folder.listFiles();
for (File file : listOfFiles) {
if (file.isFile() && file.toString().contains(".mp3")) {
String fileS = file.getName();
files.add(fileS);
}
}
return files;
}
Try a recursive approach. The path is the current directory that you're in. Recursively call this on each folder and you will get to each file.
public void walk(String path) {
File root = new File(path);
File[] list = root.listFiles();
if (list == null) return;
for (File f : list) {
if (f.isDirectory()) {
walk(f.getAbsolutePath());
}
else {
//do what you want with files
}
}
}
Test whether file is a folder. If it is, pass it to ListFiles and append the return value to files.
For this to work, you need to change ListFiles to accept a File object as argument and start your search with this File instead of with "C:/"
Look into DirectoryStream<Path> class and the Files.isDirectory() method. Basically what you want to do is to check whether each Path is a file or directory.
If it is a directory, you call your method again. Else, you continue iterating.
Globbing is also possible with a directory stream. Saves you a lot of time instead of having to manually check file extensions.
If you wish to continue with your method or with directory stream, you will need to make a few modifications to your program to accomodate recursion.
If you want to do this yourself, you need to make it recursive. Which is what Oswald is getting at. A recursive method is a method that calls itself. So when you search a folder, for each element in it, if its an mp3, add it to the list, if its a folder, call your method again passing that folder in as the input.
I know it's Java question but why not just use Groovy and do it like:
static List<String> listMp3s() {
List<String> files = []
File rootFolder = new File('C:/')
rootFolder.eachFileRecurse(FileType.FILES) {
if (it.name.endsWith('.mp3')) {
files << it.name
}
}
return files
}
I'm trying to write this script that takes an Excel sheet, gets all the names of files from the cells, and moves each of those files to a specific folder. I've already got most of the code done, I just need to be able to search for each file in the source directory using just its title. Another problem is that I'm searching for multiple file types (.txt, .repos, .xlsx, .xls, .pdf, and some files don't have extensions), I only can search by the file name without the extension.
In my findAndMoveFiles method, I've got an ArrayList of each File and a Guava Multimap of XSSFCells to Strings (a cell is one cell from the Excel file and a String is the name of the folder it needs to go into, one to many relationship) as parameters. What I've got right now for the method is this.
public static void findAndMoveFiles(List<File> files, Multimap<XSSFCell, String> innerCells) {
// For each file, get its values (folders), and put that file in each of those folders
for (XSSFCell cell : innerCells.keySet()) {
// find the file in the master directory
//Finder f = new Finder();
//if (f.canBeFound(FOLDER, cell.getStringCellValue())) {
File file = find(FOLDER, cell.getStringCellValue());
//System.out.println(file.getAbsolutePath());
//List<String> values = new ArrayList(innerCells.get(cell));
/*for (String folder : values) {
File copy = file;
if (copy != null) {
System.out.println(folder);
System.out.println(copy.getAbsolutePath());
if (copy.renameTo(new File("C:\\strobell\\" + folder + "\\" + copy.getAbsolutePath()))) {
System.out.println(copy.getName() + " has been moved successfully.");
} else {
System.out.println(copy.getName() + " has failed to move.");
}
}
}*/
//}
}
}
public static File find(File dir, String fileName) {
String files = "";
File[] listOfFiles = dir.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
files = listOfFiles[i].getAbsolutePath();
if (files.equals(fileName)) {
return listOfFiles[i];
}
}
}
return null;
}
I commented out parts because it wasn't working. I was getting NullPointerExceptions because some files were being returned as null. I know that it's returning null, but each file should be found.
If there are any 3rd party libraries that can do this, that would be amazing, I've been racking my brain on how to do this properly.
Instead of
File[] listOfFiles = dir.listFiles();
use
File[] listOfFiles = dir.list(new FileNameFilter() {
public boolean accept(File dir, String name) {
if( /* code to check if file name is ok */ ) {
return true;
}
return false;
}
}););
Then you can code your logic on the file names in the condition.