i am trying to write a jave code that does the following, but atm have no clue how to realize this:
let us say: i have 7 files in different or equal paths on local system, that i want to copy somewhere else using as few pathnames in my shell command as possible
correctfiles are the files i want, somefiles i do not care about
for instance i do not want :
copy C:\tmp\folder1\subfolder12\correctfile3 && copy C:\tmp\folder1\subfolder12\correctfile4
instead i want the Uberfolder whenever possible:
copy C:\tmp\folder1\subfolder12\
and that demands that there is no somefile in copy C:\tmp\folder1\subfolder12
because i do not want to transfer somefile
e.g.
C:\tmp\folder1: somefile1, somefile2
C:\tmp\folder1\subfolder11: correctfile1, correctfile2
C:\tmp\folder1\subfolder12: correctfile3, correctfile4
C:\tmp\folder2\subfolder21: correctfile5
C:\tmp\folder2\subfolder22: correctfile6, correctfile7
so in this example i could use
copy C:\tmp\folder2
because alle files in that folder are correctfiles
and for the others i would have to
copy C:\tmp\folder1\subfolder11
copy C:\tmp\folder1\subfolder12
because there are somefiles in Uberfolder C:\tmp\folder1 that i do not want to transfer
how could i achieve this?
a java class that sort of groups the files according to pathnames, using as few pathnames as possible
This is actually quite simple. From a List<File> filesToCopy create a
Map<String,Set<String>> dir2names = new HashMap<>();
for( File f: filesToCopy ){
String name = f.getName();
// test name for null and do error handling
String dir = f.getParent();
// dir for null and do error handling
Set<String> names = dir2names.get( dir );
if( names == null ){
names = new HashSet<>();
dir2names.put( dir, names );
}
names.add( name );
}
mapping the directory parts to file names. Iterate the keys of this map
for( String dirname: dir2names.keySet() ){
File[] entries = new File( dirname ).listFiles();
if( entries.length > dir2names.get( dirname ).size() ){
// add list created from dirname + set of names to files to copy
for( String name: dir2names.get( dirname ){
String pathname = new File( dirname, name ).getAbsolutePath();
// add pathname to files to copy
}
} else {
// add directory identified by dirname to files to copy
}
}
I don't think it is worth doing this recursively.
Related
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 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.
I have an .ear, a .jar and a .war packages. I am reading my servlet classes dinamically by inspecting the file system and registering the mappings.
The thing is it works for development, I am able to read the directories and the proper file names do be able to create the mappings. The problem is that if I package my ear It does not work:
Using new File( ... ).isDirectory()
to check if I am in a directory, returns always false for a valid directory path.
Using new File( ... ).listFiles()
to be able to list the files from a directory, returns always null for a valid directory path.
I have solved the directory checking issue by detecting an end path that does not end with an extension (for my purpose such verification is enough), but I am still not able to list the files from a given path.
Given this situation I have the question:
How can I list the file names at runtime from a package .war?
The current code:
private void addAllFiles( File dir, ArrayList<ConventionPath> list ) {
for ( File file : dir.listFiles() ) { // dir.listFiles() comes null here =/
String absolutePath = file.getAbsolutePath();
boolean isActionDir = ConventionFiles.isActionDir( absolutePath, fileSeparator );
boolean isActionFile = ConventionFiles.isActionFile( absolutePath );
if ( isActionDir ) {
addAllFiles( file, list );
}
if ( isActionDir || isActionFile ) {
ConventionPath conventionPath =
new ConventionPath( absolutePath, fileSeparator );
list.add( conventionPath );
}
}
}
Now I made it work.
Instead of accessing the file via the file system I used the servlet context (I suppose this is the correct way to go):
URL root = context.getResource( "/WEB-INF/classes/com/package/" );
// /default-host/WEB-INF/classes/
String rootPath = root.getPath();
// /WEB-INF/classes/
rootPath = rootPath.substring( rootPath.indexOf( "/WEB-INF" ), rootPath.length() );
And then recursively I get the information I want from the resources:
Set<String> resourcesPath = context.getResourcePaths( rootPath );
How can I delete the file in the directory / folder
I am using this code:
private static final String FILE_DIR = "data\\session";
private static final String FILE_TEXT_EXT = ".cache";
private void DeleteCache(String folder, String ext){
GenericExtFilter filter = new GenericExtFilter(ext);
File dir = new File(folder);
File fileDelete;
String[] list = dir.list(filter);
for(String file : list){
String temp = new StringBuffer().append(File.separator).append(file).toString();
fileDelete = new File(temp);
boolean isDelete=fileDelete.delete();
System.out.println("File : "+temp+"is Delete : "+isDelete);
}
if(list.length == 0 ) return;
}
public class GenericExtFilter implements FilenameFilter{
private String ext;
public GenericExtFilter(String ext){
this.ext=ext;
}
public boolean accept (File dir, String name){
return (name.endsWith(ext));
}
}
but why yes if, cache do not want to be removed
example error
File : \31052012-TPBSDERG.cache -is Delete : false
Probably because the file does not exist.
Try using....
File[] list = dir.listFiles(filter);
Instead
UPDATE
There are many reasons why a file may not be deleted. The actual process is depended on the underlying OS, but the most common reasons are, the file is open by another process (or your program), you don't have the correct permissions to delete the file and/or the file doesn't exist.
There are a number of interesting issues with your code...
String temp = new StringBuffer().append(File.separator).append(file).toString();
This is appending a file separator to the file which now says, "look for the file in the root directory of the current drive", which is (probably) not where the file exists.
For example;
File dir = new File(System.getProperty("user.home"));
String[] list = dir.list(filter);
for(String file : list){
String temp = new StringBuffer().append(File.separator).append(file).toString();
System.out.println(temp + " - " + new File(temp).exists());
}
This outputs something like...
/.bash_history - false
/.CFUserTextEncoding - false
/.config - false
/.cups - false
Which is obviously wrong, these files don't live in the root folder
Equally if I do;
File dir = new File(System.getProperty("user.home"));
String[] list = dir.list(filter);
for(String file : list){
System.out.println(file + " - " + new File(file).exists());
}
This outputs something like...
.bash_history - false
.CFUserTextEncoding - false
.config - false
.cups - false
This is equally as useless, as these files don't exist in the current execution location either...
Now, however, if I do something like...
String folder = System.getProperty("user.home");
File[] list = new File(folder).listFiles();
for (File file : list) {
System.out.println(file + " - " + file.exists());
}
I get...
/path/to/home/.bash_history - true
/path/to/home/.CFUserTextEncoding - true
/path/to/home/.config - true
/path/to/home/.cups - true
Which is, obviously, far more useful.
You have to remember, Java is stupid, it doesn't know that when you specify a String value for a name where to look for that file, it makes an assumption based on your current location (unless you specify an absolute path of course)
You are iterating over a list of files in folder, but this is NOT where you attempt to delete the files from.
BTW: is that "31052012-TPBSDERG.cache -" the actual file name???
Use this file to delete (and do not prepend with File.separator, the parent folder is what matters):
fileDelete = new File( dir, file );
and it will work. dir.list(filter) only returns file names without path (e.g. directory name), and if dir is not the current working directory, new File( file ) will not point to the file it was included for, new File( dir, file ) will.
Good Day!
I wrote the method in Java which must search files in folders and do some operations with them.
So the problem is that when I try to check what I have (file or dir) I receive nothing in both cases! But as i can see paths look correct.
How can I fix this problem?
Here is the code:
public void searchInDir(){
File inputFile = new File( this.fileName );
String[] namesOfFilesDir = inputFile.list();
for ( int i = 0; i < namesOfFilesDir.length; i++ )
{
String normalPath = this.getNormalPath(inputFile.getCanonicalPath()); //C:\User -> C:\\User
// Two separators for correcting path to file
String pathToCurrentFile = normalPath + File.separator + File.separator + namesOfFilesDir[i];
File f = new File( pathToCurrentFile, namesOfFilesDir[i] );
System.out.printf("FileName=%s, Path=[%s]\n", namesOfFilesDir[i], pathToCurrentFile);
System.out.println(f.isDirectory());//False
System.out.println(f.isFile());//False too
//Some other code
}
}
For example this.fileName consists path to folder ( and this folder consists one folder and 2 files).
I got next:
FileName=Readme.txt, Path=[C:\\workspace\\Grep\\t\\Readme.txt]
false
false
FileName=t2, Path=[C:\\workspace\\Grep\\t\\t2]
false
false
FileName=test.txt, Path=[C:\\workspace\\Grep\\t\\test.txt]
false
false
Ok. Program says that.
Lets print next code as an example.
File f = new File("C:\\workspace\\Grep\\t\\Readme.txt");
System.out.println(f.isFile());
Program will print ”True”.
This part makes no sense:
String pathToCurrentFile = normalPath + File.separator + File.separator + namesOfFilesDir[i];
File f = new File( pathToCurrentFile, namesOfFilesDir[i] );
Even if we forget about the double separator for the time being, it makes no sense to first construct the file name by adding namesOfFilesDir[i], then construct a File() object using the two-argument constructor which basically adds namesOfFilesDir[i] once more. Try printing f.getAbsolutePath() and you'll see what I mean. It should have probably been something like:
File f = new File( normalPath, namesOfFilesDir[i] );
Probably the file doesn't exist, so it is neither a file nor a directory. Try printing the output of f.exists() as well.
Did you notice the duplicate file separator in your path?
I think that perhaps your paths are not correct. Both isFile() and isDirectory() only return true if the file/directory actually exists. Have you tried calling exists() on the file? Also, I'm suspicious of what your getNormalPath() method is doing - I think it might be mangling the filenames.
The 1st System.out.println is missleading!
It would have been better to output the path of f.
Anyway, according the output:
FileName=Readme.txt, Path=[C:\workspace\Grep\t\Readme.txt]
f will be C:\workspace\Grep\t\Readme.txt\Readme.txt
that is, namesOfFilesDir[i] is being appended twice!
It would be easier/better to work just with instances of File directly:
File inputFile = new File(this.fileName);
File[] files = inputFile.listFiles();
for (File f : files) {
System.out.printf("FileName=%s, Parent=[%s]\n", f.getName(), f.getParent());
System.out.println(f.isDirectory());
System.out.println(f.isFile());
//Some other code
}