How to split directory path components in string in java [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
how to split the string in java
FileSystemView fsv = FileSystemView.getFileSystemView();
File[] roots = fsv.getRoots();
for (int i = 0; i < roots.length; i++)
{
System.out.println("Root: " + roots[i]);
}
System.out.println("Home directory: " + fsv.getHomeDirectory());
Root: C:\Users\RS\Desktop
Home directory: C:\Users\RS\Desktop
I want cut the root or Home Directory components like
String C, Users, RS, Desktop

I'd rather not succumb to the temptation of using split ona file name, when java has its own cleaner, cross-platform functions for path manipluation.
I think this basic pattern works from java 1.4 and onward:
File f = new File("c:\\Some\\Folder with spaces\\Or\\Other");
do {
System.out.println("Parent=" + f.getName());
f = f.getParentFile();
} while (f.getParentFile() != null);
System.out.println("Root=" + f.getPath());
Will output:
Path=Other
Path=Or
Path=Folder with spaces
Path=Some
Root=c:\
You probably want to use f.getCanonicalPath or f.getAbsolutePath first, so it also works with relative paths.
Unfortunately, this needs f.getPath for the root and f.getName for the other parts, and i create the parts in backward order.
UPDATE: You can compare f with fsv.getHomeDirectory() while scanning upward, and break when it turns out you were in a subdirectory of your home folder.

In the light of user844382 answer, this is the platform safe way for splitting the path:
String homePath = FileSystemView.getFileSystemView().getHomeDirectory().getAbsolutePath();
System.out.println(homePath);
System.out.println(Arrays.deepToString(homePath.split(Matcher.quoteReplacement(System.getProperty("file.separator")))));
}
On linux it outputs:
/home/isipka
[, home, isipka]
On windows it outputs:
C:\Documents and Settings\linski\Desktop
[C:, Documents and Settings, linski, Desktop]
If you omit the Matcher.quoteReplacement() method call, the code will fail on windows. This method handles the escaping of special characters like "\" (file separator on windows) and "$".

You could use java.nio.file.Path for this:
FileSystemView fsv = FileSystemView.getFileSystemView();
File[] roots = fsv.getRoots();
for (int i = 0; i < roots.length; i++)
{
System.out.println("Root: " + roots[i]);
Path p = roots[i].toPath();
for (int j=0; j < p.getNameCount(); j++)
System.out.println(p.getName(j));
}
System.out.println("Home directory: " + fsv.getHomeDirectory());

FileSystemView fsv = FileSystemView.getFileSystemView();
File[] roots = fsv.getRoots();
for (int i = 0; i < roots.length; i++) {
System.out.println("Root: " + roots[i]);
for (String s : roots[i].toString().split(":?\\\\")) {
System.out.println(s);
}
}
System.out.println("Home directory: " + fsv.getHomeDirectory());

Try using regex split root.split(":?\\\\")

A solution that is different than the others would be to get the name from the File API:
File file = roots[i];
while (file != null) {
if (file.getName().length() > 0) {
System.out.println(file.getName());
} else {
System.out.println(file.getPath().substring(0, 1));
}
file = file.getParentFile();
}
This solution returns the path in the reversed order, so you will have to do some small changes.

Try the String.split() method. http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/String.html#split(java.lang.String)
It takes regular expressions when splitting, so it's possible to do some really advanced stuff. For you splitting by \\might do it.
Since \ adds functionality to regular expressions, we need to mark it as a character rather than the "regex operator". That explains the double .

Related

java - get files and subdirectory only of a particular directory level

Having a Path, how can I list all files/subdirectories of a particular depth level?
Using find(...) from java.nio.file.Files I can specify maxDepth not the depth I want to search.
I could use the matcher in find() to filter the files based on the depth level but I don't know how to create this matcher.
In general having 2 paths how can I know if one is a "sub-path" and its depth level related to the other path?
Thanks
You can do it like this:
File folder = new File("your/path");
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
System.out.println("File " + listOfFiles[i].getName());
} else if (listOfFiles[i].isDirectory()) {
System.out.println("Directory " + listOfFiles[i].getName());
}
}
It allows you to go inside folder, but if you want to go up one level do:
File folder = new File("your/path");
File parentFolder = folder.getParentFile();

Add index to filename for existing file (file.txt => file_1.txt)

I want to add an index to a filename if the file already exists, so that I don't overwrite it.
Like if I have a file myfile.txt and same time myfile.txt exists in destination folder - I need to copy my file with name myfile_1.txt
And same time if I have a file myfile.txt, but destintation folder contains myfile.txt and myfile_1.txt - generated filename has to be myfile_2.txt
So the functionality is very similar to the creation of folders in Microsoft operating systems.
What's the best approach to do that?
Using commons-io:
private static File getUniqueFilename( File file )
{
String baseName = FilenameUtils.getBaseName( file.getName() );
String extension = FilenameUtils.getExtension( file.getName() );
int counter = 1
while(file.exists())
{
file = new File( file.getParent(), baseName + "-" + (counter++) + "." + extension );
}
return file
}
This will check if for instance file.txt exist and will return file-1.txt
You might also benefit from using the apache commons-io library. It has some usefull file manipulation methods in class FileUtils and FilenameUtils.
Untested Code:
File f = new File(filename);
String extension = "";
int g = 0;
int i = f.lastIndexOf('.');
extension = fileName.substring(i+1);
while(f.exists()) {
if (i > 0)
{ f.renameTo(f.getPath() + "\" + (f.getName() + g) + "." + extension); }
else
{ f.renameTo(f.getPath() + "\" + (f.getName() + g)); }
g++;
}
Try this link partly answers your query.
https://stackoverflow.com/a/805504/1961652
DirectoryScanner scanner = new DirectoryScanner();
scanner.setIncludes(new String[]{"**/myfile*.txt"});
scanner.setBasedir("C:/Temp");
scanner.setCaseSensitive(false);
scanner.scan();
String[] files = scanner.getIncludedFiles();
once you have got the correct set of files, append a proper suffix to create a new file.

File.renameTo() doesn't have any effect

I'd like to be able to rename a list of folders in order to remove unwanted characters (a dot and double space have to become a single space, for example).
Upon clicking a button in the Gui, you'll see a messagebox with the correctly formatted name appear which indicates that both the formatting is correct and the function is called.
When I look at the test folders I've created, the names aren't changed (not even after refreshing). Using a hardcoded string doesn't work either.
What am I overlooking?
public void cleanFormat() {
for (int i = 0; i < directories.size(); i++) {
File currentDirectory = directories.get(i);
for (File currentFile : currentDirectory.listFiles()) {
String formattedName = "";
formattedName = currentFile.getName().replace(".", " ");
formattedName = formattedName.replace(" ", " ");
currentFile.renameTo(new File(formattedName));
JOptionPane.showMessageDialog(null, formattedName);
}
}
}
For future browsers: This was fixed with Assylias' comment. Below you will find the eventual code which fixed it.
public void cleanFormat() {
for (int i = 0; i < directories.size(); i++) {
File currentDirectory = directories.get(i);
for (File currentFile : currentDirectory.listFiles()) {
String formattedName = "";
formattedName = currentFile.getName().replace(".", " ");
formattedName = formattedName.replace(" ", " ");
Path source = currentFile.toPath();
try {
Files.move(source, source.resolveSibling(formattedName));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Well, first of all the File.renameTo is trying to rename a file on the same filesystem.
The following is from java doc
Many aspects of the behavior of this method are inherently platform-dependent:
The rename operation might not be able to move a file from one filesystem to
another, it might not be atomic, and it might not succeed if a file with the
destination abstract pathname already exists.
The call to getName() returns just the name of the file and not any directory information. So you may be trying to rename the file to a different directory.
Try adding the containing directory to the file object you pass into rename
currentFile.renameTo(new File(currentDirectory, formattedName));
Also like others have said you should be checking the return value of renameTo which is probably false, or use the new methods in Files class which I've found to throw pretty informative IOExceptions.
First of all check return value, File.renameTo returns true if the renaming succeeded; false otherwise. E.g. you cannot rename / move a file from c: to d: on Windows.
And most importantly, use Java 7's java.nio.file.Files.move instead.

How to create multiple directories given the folder names

I have a list of files, the names of these files are are made of a classgroup and an id (eg. science_000000001.java)
i am able to get the names of all the files and split them so i am putting the classgroups into one array and the ids in another.. i have it so that the arrays cant have two of the same values.
This is the problem, i want to create a directory with these classgroups and ids, an example:
science_000000001.java would be in science/000000001/science_000000001.java
science_000000002.java would be in science/000000002/science_000000002.java
maths_000000001.java would be in maths/000000001/maths_000000001.java
but i cannot think of a way to loop through the arrays correctly to create the appropriate directories?
Also i am able to create the folders myself, its just getting the correct directories is the problem, does anyone have any ideas?
Given:
String filename = "science_000000001.java";
Then
File fullPathFile = new File(filename.replaceAll("(\\w+)_(\\d+).*", "$1/$2/$0"));
gives you the full path of the file, in this case science/000000001/science_000000001.java
If you want to create the directory, use this:
fullPathFile.getParentFile().mkdirs();
The above answer is really good for creating new files with that naming convention. If you wanted to sort existing files into their relative classgroups and Ids you could use the following code:
public static void main(String[] args) {
String dirPath = "D:\\temp\\";
File dir = new File(dirPath);
// Get Directory Listing
File[] fileList = dir.listFiles();
// Process each file
for(int i=0; i < fileList.length; i++)
{
if(fileList[i].isFile()) {
String fileName = fileList[i].getName();
// Split at the file extension and the classgroup
String[] fileParts = fileName.split("[_\\.]");
System.out.println("One: " + fileParts[0] + ", Two: " + fileParts[1]);
// Check directory exists
File newDir = new File(dirPath + fileParts[0] + "\\" + fileParts[1]);
if(!newDir.exists()) {
// Create directory
if(newDir.mkdirs()) {
System.out.println("Directory Created");
}
}
// Move file into directory
if(fileList[i].renameTo(new File(dirPath + fileParts[0] + "\\" + fileParts[1] + "\\" + fileName))) {
System.out.println("File Moved");
}
}
}
}
Hope that helps.

Traversing files and directories using Java

I have a small code wich can return the list of files under any directory.
What I need to do is get the Directories and Files under the first given directory.
This is the code I'm using.
File dir = new File("C:/myDocument/myFolder");
String[] children = dir.list();
if (children == null) {
} else {
for (int i=0; i<children.length; i++) {
String filename = children[i];
System.out.println(filename);
}
}
Another thing is when I select the path from Windows 7, I get this C:\myFolder\myFolder.
If I use this path in Java I get this error Invalide Escape sequence
Do I have to change it to C:/myDocument/myFolder to get it work.
Help.
Thanks
Yes, forward slashes are fine. They get normalized to the OS-dependent separator.
What the error tells you is that \m is an invalid escape sequence. Each backward slash tries to escape the following character. So if you need backward slashes in a string, use a double slash: "c:\\myDocuments\\myFolder"
In order to get directories and files, you use .listFiles() and then file.isDirectory() to check if it's a directory.
I use a similar way to clear given folders.
private static void deleteTree(File file)
{
if(file.isDirectory())
{
File afile[] = file.listFiles();
System.out.println("Directory: " + file.getFilename);
if(afile.length > 0)
{
for(int i = 0; i < afile.length; i++)
{
if(afile[i].isDirectory())
System.out.println("Directory: " + afile[i].getFilename);
deleteTree(afile[i]);
else
System.out.println("File: " + afile[i].getFilename);
}
}
} else {
System.out.println("File: " + file.getFilename);
}
}
You can misuse File.list(FilenameFilter) for file traversal, e.g:
// list files in dir
new File(dir).list(new FilenameFilter() {
public boolean accept(File dir, String name) {
String file = dir.getAbsolutePath() + File.separator + name;
System.out.println(file);
return false;
}
});

Categories