I have a java application that uses JFileChooser on Win7. The weird thing is that sometimes (quite often) but not always - drive names look weird in 'Look in:' combo box:
Does anyone have an idea what causes that and how to make it always show proper names?
Those come from system drives like My Computer, Network Neighborhood, etc.
The way I get around it showing the files like that is:
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileView(new FileView() {
#Override
public String getName(File f) {
String name = FileSystemView.getFileSystemView().getSystemDisplayName(f);
// If names is empty use the description
if(name.equals("")) {
name = FileSystemView.getFileSystemView().getSystemTypeDescription(f);
}
return name;
}
});
This way it is always pulling the names being displayed by the file system.
I want to share a little piece of code which explain the not so obvious behavior of JFileChooser.
On Windows there is a difference if you navigate on the filesystem in a CMD session or in the Windows file explorer.
For example you navigate to the root directory of drive c:\.
CMD
rem this will still stay in C:\ as there is no parent directory
cd ..
Windows file explorer
- the parent directory of 'C:\' is 'Computer'
- but 'Computer' is not a real directory and is accessed by an CLSID (Class Identifier
for COM class objects), the incomprehensible '::{20D04FE0-3AEA-1069-A2D8-08002B30309D}'
The code to make this behaviour more clear.
import java.io.File;
import javax.swing.filechooser.FileSystemView;
public class JFileChooserParentDirectory {
public static void main(String[] args) {
// the root directory of drive C:
File file = new File("C:/");
// get a view of the file system
FileSystemView fileSystemView = FileSystemView.getFileSystemView();
// get the parent directory of our file
File parentDir = fileSystemView.getParentDirectory(file);
// get the Windows display name of this parent directory
String displayName = fileSystemView.getSystemDisplayName(parentDir);
// get the Windows type description of this parent directory
String typeDescription = fileSystemView.getSystemTypeDescription(parentDir);
// print out all the different values
String printFormat = "%-50s: %s%n";
System.out.printf(printFormat, "file.getAbsolutePath()", file.getAbsolutePath());
System.out.printf(printFormat, "parentDir.getName()", parentDir.getName());
// this absolute path is related to the directory from which you started the code
System.out.printf(printFormat, "parentDir.getAbsolutePath()", parentDir.getAbsolutePath());
System.out.printf(printFormat, "fileSystemView.getSystemDisplayName(parentDir)", displayName);
System.out.printf(printFormat, "fileSystemView.getSystemTypeDescription(parentDir)", typeDescription);
}
}
This print out.
file.getAbsolutePath() : C:\
parentDir.getName() : ::{20D04FE0-3AEA-1069-A2D8-08002B30309D}
parentDir.getAbsolutePath() : D:\development\stackoverflow\playground\::{20D04FE0-3AEA-1069-A2D8-08002B30309D}
fileSystemView.getSystemDisplayName(parentDir) : Computer
fileSystemView.getSystemTypeDescription(parentDir): System Folder
To solve the problem in the JFileChooser take the solution from #inquisitor.
Related
In my java application,
1. I have relative path of the directory (Directory and files in it are part of the build).
2.The directory contains multiple files.
3. I want to read the file names in the parent directory.
4. Files can change later and are many in number, So I do not know the names of the files and Do not want my code to change if more files are added or removed or renamed
Now as I do not know the names of the files before hand as they may change later (there are multiple files which can vary according to environment). I only know about the relative path of the parent directory of the files.
How do I read the files ?
You can get list of all files of that directory by file.getlistFiles() method of file class.
It returns an array of files.
Even you can define filter for your files, so it returns exactly files that you want.
try {
File f = new File("D:/Programming");
FilenameFilter filter = new FilenameFilter() {
#Override
public boolean accept(File f, String name) {
// We want to find only .c files
return name.endsWith(".c");
}
};
// Note that this time we are using a File class as an array,
// instead of String
File[] files = f.listFiles(filter);
look at this example.
If you want to use relative path, You can use
System.getProperty("user.dir");
String relative Path =System.getProperty("user.dir");
it returns the folder that you put your app in it.
If your folder has some subfolders, you can simply use file.list();
it returns names of all files and folders of your directory .
String [] listOfMyFilesAndFolders =file.list();
you can add these names to your path to access another folders.
You can check your path is a file or is a folder by using
file.isDirectory();
for ( String path: listOfFilesAndFolders ) {
File file = new File(basePath+path);
if ( file.isDirectory() {
// it is a folder and you can use another for loop or recursion to navigate sub directories
} else {
// it is a file and you can do everyThing you want}}
I think that you can use recursion to walk in your sub directories use recursion to read more
I hope helps.
the question is badly asked and the text is misleading.
"I have relative path of the directory (Directory and files in it are part of the build)" means little and nothing, you have to clarify what you mean.
Assuming you get a relative directory (for example "/folder1/folder2") via command line parameter, you basically have 3 choices:
1) start the program with the directory in which the jar is located as the "current directory", so that it can be used as a working directory. This approach requires that when you launch your application via the java -jar myapp.jar command first you prepend a "cd" command to place yourself directly in the directory. The code will look like the #hamidreza75 solution but obviously you will not have the variable "D: / Programming" but directly the relative path of the directory in which to read the files.
launch script
#echo off
cd {jar-folder}
java -jar myapp.jar
java code:
package com.sample.stack;
import java.io.File;
import java.io.FilenameFilter;
public class FileRenamenter {
public static void main(String[] args) {
final String relativePath = "folder1/folder2";
File directory = new File(relativePath);
String[] list = directory.list(new FilenameFilter(){
public boolean accept(File dir, String name) {
// filter condition
return true;
}
});
// echo file list
for (String filePath : list) {
System.out.println(filePath);
}
}
}
2) pass the folder to be controlled via command line parameter, like this:
launch script
#echo off
java -jar {jar-folder}/myapp.jar {jar-folder}
java code (only the "directory" variable changes)
File directory = new File(args[0], relativePath); // note args[0]
3) programmatically find the folder in which the jar is running [very discouraged practice] and then concatenate the relative path:
java code (only the "directory" variable changes):
String jarFolder = ClassLoader.getSystemClassLoader().getResource(".").getPath();
File directory = new File(jarFolder, relativePath); // note jarFolder
I am trying to understand the way Java resolves relative path in while creating a File object.
OS used: Windows
For the below snippet, I am getting an IOException as it cannot find the path:
#Test
public void testPathConversion() {
File f = new File("test/test.txt");
try {
f.createNewFile();
System.out.println(f.getPath());
System.out.println(f.getAbsolutePath());
System.out.println(f.getCanonicalPath());
} catch (Exception e) {
e.printStackTrace();
}
}
My understanding here is, Java treats the path provided as absolute and returns an error when the path does not exist. So it makes sense.
When I update the above code to use relative path:
#Test
public void testPathConversion() {
File f = new File("test/../test.txt");
try {
f.createNewFile();
System.out.println(f.getPath());
System.out.println(f.getAbsolutePath());
System.out.println(f.getCanonicalPath());
} catch (Exception e) {
e.printStackTrace();
}
}
It creates a new file and provides the below output:
test\..\test.txt
C:\JavaForTesters\test\..\test.txt
C:\JavaForTesters\test.txt
In this case, my assumption is, even though the path provided doesn't exist, because the path contains "/../", java treats this as a relative path and creates the file in the user.dir. So this also makes sense.
But if I update the relative path as below:
#Test
public void testPathConversion() {
File f = new File("test/../../test.txt");
try {
f.createNewFile();
System.out.println(f.getPath());
System.out.println(f.getAbsolutePath());
System.out.println(f.getCanonicalPath());
} catch (Exception e) {
e.printStackTrace();
}
}
Then I get IOException: Access is denied.
My questions are:
why "test/../test.txt" is treated as a relative path and creates the file in "user.dir" but"test/../../test.txt" returns an error? Where does it attempt to create the file for the path "test/../../test.txt"?
When the specified relative path is not found, the file seems to be created in the user.dir. So, it appears to me that the below two scenarios does the same thing:
//scenario 1
File f = new File("test/../test.txt");
f.createNewFile();
//scenario 2
File f = new File("test.txt");
f.createNewFile();
So is there a real world case where one would use scenario 1 instead of scenario 2?
I suppose I am missing something obvious here or have fundamentally misunderstood relative paths. I went through the Java docs for File and I am not able to find an explanation for this. There are quite a few questions posted in Stack Overflow regarding relative paths, but the ones I looked up were for specific scenarios and not exactly about how relative paths are resolved.
It will be great if someone could please explain me how this works or point to some related links?
There is a concept of a working directory.
This directory is represented by a . (dot).
In relative paths, everything else is relative to it.
Simply put the . (the working directory) is where you run your program.
In some cases the working directory can be changed but in general this is
what the dot represents. I think this is C:\JavaForTesters\ in your case.
So test\..\test.txt means: the sub-directory test
in my working directory, then one level up, then the
file test.txt. This is basically the same as just test.txt.
For more details check here.
http://docs.oracle.com/javase/7/docs/api/java/io/File.html
http://docs.oracle.com/javase/tutorial/essential/io/pathOps.html
When your path starts with a root dir i.e. C:\ in windows or / in Unix or in java resources path, it is considered to be an absolute path. Everything else is relative, so
new File("test.txt") is the same as new File("./test.txt")
new File("test/../test.txt") is the same as new File("./test/../test.txt")
The major difference between getAbsolutePath and getCanonicalPath is that the first one concatenates a parent and a child path, so it may contain dots: .. or .. getCanonicalPath will always return the same path for a particular file.
Note: File.equals uses an abstract form of a path (getAbsolutePath) to compare files, so this means that two File objects for the same might not be equal and Files are unsafe to use in collections like Map or Set.
The working directory is a common concept across virtually all operating systems and program languages etc. It's the directory in which your program is running. This is usually (but not always, there are ways to change it) the directory the application is in.
Relative paths are ones that start without a drive specifier. So in linux they don't start with a /, in windows they don't start with a C:\, etc. These always start from your working directory.
Absolute paths are the ones that start with a drive (or machine for network paths) specifier. They always go from the start of that drive.
Relative paths can be best understood if you know how Java runs the program.
There is a concept of working directory when running programs in Java. Assuming you have a class, say, FileHelper that does the IO under
/User/home/Desktop/projectRoot/src/topLevelPackage/.
Depending on the case where you invoke java to run the program, you will have different working directory. If you run your program from within and IDE, it will most probably be projectRoot.
In this case $ projectRoot/src : java topLevelPackage.FileHelper it will be src.
In this case $ projectRoot : java -cp src topLevelPackage.FileHelper it will be projectRoot.
In this case $ /User/home/Desktop : java -cp ./projectRoot/src topLevelPackage.FileHelper it will be Desktop.
(Assuming $ is your command prompt with standard Unix-like FileSystem. Similar correspondence/parallels with Windows system)
So, your relative path root (.) resolves to your working directory. Thus to be better sure of where to write files, it's said to consider below approach.
package topLevelPackage
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
public class FileHelper {
// Not full implementation, just barebone stub for path
public void createLocalFile() {
// Explicitly get hold of working directory
String workingDir = System.getProperty("user.dir");
Path filePath = Paths.get(workingDir+File.separator+"sampleFile.txt");
// In case we need specific path, traverse that path, rather using . or ..
Path pathToProjectRoot = Paths.get(System.getProperty("user.home"), "Desktop", "projectRoot");
System.out.println(filePath);
System.out.println(pathToProjectRoot);
}
}
Hope this helps.
On windows and Netbeans you can set the relative path as:
new FileReader("src\\PACKAGE_NAME\\FILENAME");
On Linux and Netbeans you can set the relative path as:
new FileReader("src/PACKAGE_NAME/FILENAME");
If you have your code inside Source Packages
I do not know if it is the same for eclipse or other IDE
Only slightly related to the question, but try to wrap your head around this one. So un-intuitive:
import java.nio.file.*;
class Main {
public static void main(String[] args) {
Path p1 = Paths.get("/personal/./photos/./readme.txt");
Path p2 = Paths.get("/personal/index.html");
Path p3 = p1.relativize(p2);
System.out.println(p3); //prints ../../../../index.html !!
}
}
I went off of peter.petrov's answer but let me explain where you make the file edits to change it to a relative path.
Simply edit "AXLAPIService.java" and change
url = new URL("file:C:users..../schema/current/AXLAPI.wsdl");
to
url = new URL("file:./schema/current/AXLAPI.wsdl");
or where ever you want to store it.
You can still work on packaging the wsdl file into the meta-inf folder in the jar but this was the simplest way to get it working for me.
I don't know what to search for.
I have a external jar library in which there is a class that has all the configurations variables like where to store the log files and such, as public static final variables.
the path for log file config given is "/home/log.cfg".
Now I am working in windows. How do I make a path like this? where to put the cfg file?
The file can still be opened an read if you create the directory home in the root of your drive. Just make sure that the working directory of the application is on the same drive. Java file handling API seems to add the dirve letter to an absolute path if none was specifyed.
javadoc for File#getAbsolutePath
On Microsoft Windows systems, a relative pathname is made absolute by resolving it against the current directory of the drive named by the pathname, if any; if not, it is resolved against the current user directory.
A simple test demonstrates that:
Create a directory under C:\ named home and place some text file inside.
#Test
public void openFile() throws FileNotFoundException, IOException {
File file = new File("/home/log.cfg");
System.out.println(file.getAbsolutePath());
FileInputStream fileInputStream = new FileInputStream("/home/log.cfg");
int c;
while(-1 != (c = fileInputStream.read())) {
System.out.print((char) c);
}
fileInputStream.close();
}
And here is the output:
C:\home\log.cfg
Hello, log.fg!
i want to ask you regardless finding the file path...
I have, or i would have files that will be associated with my app, but i dont know how to find out the file path that initializes opening my app.
For example:
If i click in windows enviroment on excel file "file.xlx", windows will open excel application with this file "file.xls" and i want exactly the same. After my app will be open, i want to know file path that inicializes my app to start...
I hope that my question is understandable and i apologize for my bad english.. :)
Edit:
I try add some another example...
I try describe some logic operations...
1 - nothing is running, only windows - i hope :)
2 - user click on some file that is somewhere in the HDD ( this file can have different name and different location )
3 - this file with some extension has associated start with my app
4 - app automatically find out on whitch file user clicked ( who invoke the launch of my application ) and use this file path on other work...
I think that should be something like when i start console app. with some argument....but this argument i must get from some windows location.
Just like when i click on file.txt and windows will open notepad and notepad will have automatically open this file.txt, or i click on file.dbf and windows will open the foxpro with this file
I want click on file.xxx and my app will open and work with this file automatically, so there i think must be some way how to get this file location on which i clicked...
I hope this help...
Look at the java system properties http://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html, you probably want user.dir
i think what you need is a program like this , this will calculate the existance of your file in side the given directory
package fileSearch;
import java.io.File;
import java.io.FilenameFilter;
public class fileSearch {
/**
* #param args
*/
public static void main(String[] args) {
fileSearch obj = new fileSearch();
obj.finder("program.txt");
for(int i=0;i<obj.finder("C:/Users/hussain.a/Desktop").length;i++)
{
System.out.println(obj.finder("C:/Users/hussain.a/Desktop")[i].getName());
}
}
public File[] finder( String dirName){
File dir = new File(dirName);
return dir.listFiles(new FilenameFilter() {
public boolean accept(File dir, String filename)
{ return filename.endsWith(".txt"); }
} );
}
}
now its up to you to apply to your desired directory , if you want it to exactly like the windows program , then you will have to use root directory every time and pass the file name as a parameter replacing ".txt" in this program
hope it serves , rest is up to you to implement it
I think you can set the os,like the registry,when you installing the app.
String osName = System.getProperty("os.name") ;
I am trying to set the directory path in JFilechooser through something like this(using commons-io ) :
String fileContents = IOUtils.toString(new FileInputStream("path.txt"));
File theDirectory = new File(fileContents);
filechooser = new JFileChooser();
fileChooser.setCurrentDirectory(theDirectory);
filechooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
I'm using getCanonicalPath() to get the path and write in the file path.txt
path = file.getCanonicalPath();
I don't intend to put all my code here,but I'm sure that the program writes and reads the path in path.txt.
I don't get any error,but everytime I run the program it always open JFilechooser in my documents folder.What i am doing wrong?
Try to pass the current directory directly in the constructor:
filechooser = new JFileChooser(theDirectory);
If you consult the API, using the default constructor (i.e. new JFileChooser()):
Constructs a JFileChooser pointing to
the user's default directory. This
default depends on the operating
system. It is typically the "My
Documents" folder on Windows, and the
user's home directory on Unix.
This would seem to account for always opening to My Documents, but this isn't your problem. In fact, your problem lies with setting the current directory (i.e. setCurrentDirectory(theDirectory)):
Sets the current directory. Passing in
null sets the file chooser to point to
the user's default directory. This
default depends on the operating
system. It is typically the "My
Documents" folder on Windows, and the
user's home directory on Unix. If the
file passed in as currentDirectory is
not a directory, the parent of the
file will be used as the
currentDirectory. If the parent is not
traversable, then it will walk up the
parent tree until it finds a
traversable directory, or hits the
root of the file system.
That being said, I'd pay attention to the highlighted text since it appears that you're setting a file as the current directory and not a directory.
In your main class declare
public static String dirpath=".";
private void btnBrowseActionPerformed(java.awt.event.ActionEvent evt) {
JFileChooser jfc = new JFileChooser(dirpath);
dirpath =jfc.getSelectedFile().getAbsolutePath().toString();
}
For select the last directory that you open :
chooser.setCurrentDirectory(lastDirectory);
int r = chooser.showOpenDialog(new JPanel());
if (r == JFileChooser.APPROVE_OPTION) {
fileName = chooser.getSelectedFile().getPath();
lastDirectory = chooser.getSelectedFile();
}
JFileChooser Chooser = new JFileChooser("F:");
if you want to change the directory theb use System.getProperty method
String s=System.getProperty("user.dir"); // changes directory from documents to the user current Directory;
JFileChooser jfc=new JFileChooser(s);