File path issue on windows vs Unix in java - java

In my program, I am reading a resource file for a unit test. I use file path as:
\\\path\\\to\\\file
On my machine(Windows) this runs fine. But on server(Unix), this fails, and I have to change it to: /path/to/file
But Java is supposed to be platform independent. So isn't this behaviour unexpected?

Use FileSystem.getSeparator() or System.getProperty("file.separator") instead of using slashes.
EDIT:
You can get an instance of FileSystem via FileSystems.getDefault (JDK 1.7+)

You can use File.separator to get the appropriate character in a platform-independent way.

Java is platform independent. The file path-es and some system calls are not.
As long as the path is relative, you can use File.separator:
String path = "path" + File.separator + "to" + File.separator + "file";
System.out.println(path); // prints path\to\file on windows
Sometimes it's an option is to provide a Properties file and let the user define path of that actual file. This way full paths are okay too. You can read the properties like this:
Properties props = new Properties();
props.load(new FileInputStream(filePath));
The next question is: how to specify the location of that file? That might be either a file on a relative path. If that's not viable for your app, then you can let the user specify it in a system property:
java ... -DconfigFile=C:\TEMP\asd.txt .... -jar myapp.jar
Then you can access it like this:
// prints C:\TEMP\asd.txt if you specified -DconfigFile=C:\TEMP\asd.txt
System.out.println(System.getProperty("configFile"));

This is the expected behaviour.
Java code compiles on any machine/OS provided you have the right version of Java installed on it.
However, at run time, your code sees only a variable value like another one, which happens to be \path\to\file
When it talks to the file system, it uses that particular value ; the file system then tries to find that path you've given to it ; which is why one syntax works fine on Windows but will not work on Linux.

Better way of doing this is :
val pathUri = Paths.get(".//src//test//res//file.txt").toUri()
val is = FileInputStream((File(pathUri)))

Related

What happen if we put two file separator next to each other?

We know if we want to address a file, we could do it to something like this:
// file_path is the path file to current position of program
String address = file_path + File.separator + "output.txt";
But I made a mistake and set file separator twice, like this:
String address = file_path + File.separator + File.separator + "output.txt";
These code are just an example and I get the file path by Java library which is cross platform and there is not any mistake. I show them like this to show my mistake more clearly.
In fact, I want to rename a text file from a_text.txt to b_text.txt but I set two file separator before these names! something like //b_text.txt not /b_text.txt
In Windows there is no error and file could read or edit, but what about in other Operation Systems like Linux, Mac and Solaris?
Since I don't have those systems, I want to know about it. Although I will solve that mistake as soon as possible but I'm curious to know about it anyway.
As #Yu-LinChen stated, use Path if you're using Java 7 or higher. Everything else will be platform dependent.
Moreover, as the D: suggests you're also using an absolute path, so it will be even more restricted to a certain environment. Consider making the path configurable, e.g. in a properties file, and read the configuration using Path.get(pathFromProperty). This will work with both D:\some\path on Windows and with /some/path on Unix-like systems.

platform independent way to get current java executable path and filename

I need to execute a java application using ProcessBuilder. I also need to use the same java executable in the called process that is being used by the calling application.
Is there a platform independent way to retrieve the current java executable path and file name?
I've seen some code snippets similar to this:
public static boolean isWindows() {
return (System.getProperty("os.name").toLowerCase().indexOf("win") >= 0);
}
public static String getJavaExecutablePath() {
String executable = "java";
if (isWindows()) {
executable = executable + ".exe";
}
File path = new File(System.getProperty("java.home"), "/bin/" + executable);
return path.getAbsolutePath();
}
The above code will probably need to be improved to use File.separator.
Is the above all that is required, or is there something else to consider, for example case sensitivity?
Ideally, there would be a library available for getting the OS path, but that is probably a question for a different forum.
First, the most important thing for your requirement is System.getProperty("java.home"), you've got it already.
Secondly, don't worry about case sensitivity, the path '$JAVA_HOME/bin/java' always be in lower case in every java release, and there are already many other projects depend on this.
Last thing, you don't have to use a '/' or '\' to build the absolute path, consider this:
File path = new File(new File(System.getProperty("java.home"), "bin"), executable);
As you mentioned the File.separator did similar thing, but that is talking about a string, and File talks about file.
Here is a discussion about File path

Get parent directory's parent directory name in java

I have current working file's directory path I:\apache-tomcat-7.0.40\webapps\ExecutableFileProcess\WEB-INF\classes\PackageName\
I want path like I:\apache-tomcat-7.0.40\webapps\ExecutableFileProcess\. How can I do this in java code?
You better get your App-Path from the ServletContext in Servlet-Containern like Tomcat.
Use
servletContext.getRealPath(".");
// will return 'I:\apache-tomcat-7.0.40\webapps\ExecutableFileProcess\' on win.
// will return '/usr/local/tomcat/webapps/ExecutableFileProcess' on unix.
Have a look at
http://developer.android.com/reference/java/io/File.html#getParentFile()
Applying this twice will probably get you the right directory.
But note that you program might or might not be allowed to go there, based on the settings in the file system and the context your code runs in.
Try this:
Path aPath = Paths.get("I:\\apache-tomcat-7.0.40\\webapps\\ExecutableFileProcess\\WEB-INF\\classes\PackageName\\");
Path parentsParentpath = aPath.getParent().getParent();

Get name of running Jar or Exe

What I need to do is get the name of the running jar/exe file (it would be an EXE on windows, jar on mac/linux). I have been searching around and I can't seem to find out how.
How to get name of running Jar or Exe?
Hope this can help you, I test the code and this return you the full path and the name.
Maybe you want to play a little more with the code and give me some feed back.
File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI());‌
This was found on a similar but not == question on stackoverflow
How to get the path of a running JAR file?
File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI());‌
returns simple path in the compiled application and an error in jar:
URI is not hierarchical
My solution is:
private File getJarFile() throws FileNotFoundException {
String path = Main.class.getResource(Main.class.getSimpleName() + ".class").getFile();
if(path.startsWith("/")) {
throw new FileNotFoundException("This is not a jar file: \n" + path);
}
path = ClassLoader.getSystemClassLoader().getResource(path).getFile();
return new File(path.substring(0, path.lastIndexOf('!')));
}
File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI().g‌​etPath());
Should give you the jar.
as for the exe, as I'm assuming you're using some sort of wrapper, you'll need to know the name of the exe before it's run. Then you could use something like :
Process p = Runtime.getRuntime().exec
(System.getenv("windir") +"\\system32\\"+"tasklist.exe");
Try the following
System.getProperty("java.class.path")
Using Lunch4j you can add an image name for exe file by editing generated xml, you have to change tag value true from false to true

What is the best windows equivalent for /tmp?

I want to improve the cross platform behavior of a java application. However, its test suite currently assumes the existence of the /tmp directory.
What is the best equivalent location on the windows platform? N.B. I most definitely do not want to assume the user has admin rights but I do want it to work on at least XP, Vista & Windows7.
Is there an existing environment variable that would help, and/or a set of preferred locations I could try in order of preference?
The system property java.io.tmpdir can be used for the user's temp directory:
File tmp = new File(System.getProperty("java.io.tmpdir"));
This may be preferred over File.createTempFile (which, in any case, uses the tmpdir system property under the hood) in the instance where you want to search for temp files (for example, cached data from a previous invocation of your application, which sounds like it might be the case from your question).
You can change the value of the system property by providing a runtime override on the command line (a JVM argument): -Djava.io.tmpdir=C:\foo\bar
Note: the "trailing slash" issue descibed in the comments to seth's answer below can be avoided by using the relevant File constructor:
String fileName = "foobar.txt"
String tmpPath = System.getProperty("java.io.tmpdir");
File tmpFile;
tmpFile = new File(tmpPath + File.separator + fileName); //possible problem
tmpFile = new File(new File(tmpPath), fileName); //OK!
Obviously windows also has an DOS environment variable %TEMP% which could be used from any scripts which you have
Why not use java.io.File.createTempFile()?
Windows defines environment variables TEMP and TMP both giving the current user's temporary folder.
Use File.createTempFile("myPrefix","mySuffix").
If you want to insist on doing something that is windows specific you can use the %temp% environment variable.

Categories