In the File class there are two strings, separator and pathSeparator.
What's the difference? When should I use one over the other?
If you mean File.separator and File.pathSeparator then:
File.pathSeparator is used to separate individual file paths in a list of file paths. Consider on windows, the PATH environment variable. You use a ; to separate the file paths so on Windows File.pathSeparator would be ;.
File.separator is either / or \ that is used to split up the path to a specific file. For example on Windows it is \ or C:\Documents\Test
java.io.File class contains four static separator variables. For better understanding, Let's understand with the help of some code
separator: Platform dependent default name-separator character as String. For windows, it’s ‘\’ and for unix it’s ‘/’
separatorChar: Same as separator but it’s char
pathSeparator: Platform dependent variable for path-separator. For
example PATH or CLASSPATH variable list of paths separated by ‘:’ in
Unix systems and ‘;’ in Windows system
pathSeparatorChar: Same as pathSeparator but it’s char
Note that all of these are final variables and system dependent.
Here is the java program to print these separator variables.
FileSeparator.java
import java.io.File;
public class FileSeparator {
public static void main(String[] args) {
System.out.println("File.separator = "+File.separator);
System.out.println("File.separatorChar = "+File.separatorChar);
System.out.println("File.pathSeparator = "+File.pathSeparator);
System.out.println("File.pathSeparatorChar = "+File.pathSeparatorChar);
}
}
Output of above program on Unix system:
File.separator = /
File.separatorChar = /
File.pathSeparator = :
File.pathSeparatorChar = :
Output of the program on Windows system:
File.separator = \
File.separatorChar = \
File.pathSeparator = ;
File.pathSeparatorChar = ;
To make our program platform independent, we should always use these separators to create file path or read any system variables like PATH, CLASSPATH.
Here is the code snippet showing how to use separators correctly.
//no platform independence, good for Unix systems
File fileUnsafe = new File("tmp/abc.txt");
//platform independent and safe to use across Unix and Windows
File fileSafe = new File("tmp"+File.separator+"abc.txt");
You use separator when you are building a file path. So in unix the separator is /. So if you wanted to build the unix path /var/temp you would do it like this:
String path = File.separator + "var"+ File.separator + "temp"
You use the pathSeparator when you are dealing with a list of files like in a classpath. For example, if your app took a list of jars as argument the standard way to format that list on unix is: /path/to/jar1.jar:/path/to/jar2.jar:/path/to/jar3.jar
So given a list of files you would do something like this:
String listOfFiles = ...
String[] filePaths = listOfFiles.split(File.pathSeparator);
Related
I am making an HTTP Server in Java so that (on start) it finds all files in a directory (and it's sub-directories) and adds them to the server. But when getting the path of a file and trying to give it to HttpServer.createContext(), it throws a java.lang.IllegalArgumentException: Illegal value for path or protocol. (with the string argument, say "\folder/index.html"). To get this value, I used
file.getParent().substring(24) + "/" + file.getName()
I used substring because I had to exclude the folder the web server is in. The illegal character is the backslash. I have tried extending File to change separator and separatorChar, but that only created 2 new variables. While using String.replace() didn't seem to have any effect. Is there a different method than File.getParent or File.getPath that I can use, or is there a way to use String.replace that I am not seeing?
EDIT:
String.replace() seems to be the best answer... But I am not completely sure how to use it.
EDIT 2: For some reason the backslash isn't showing up, so I changed it.
You have to use the java System.getProperty.
Notice that, in this context, "file.separator" is a key which we are
using to get this property from current system executing the java VM.
Insteady of using a slash (/), you should choose a platform agnostic file separator, as an example it should be:
String separator = System.getProperty("file.separator");
System.out.println(separator);
// unix / , windows \
Have a look at Paths.get(...)
Try Paths.get(".") // current working directory.
Or tell it, on which path it should start:
Use System.getProperty("user.dir"), for current loged in user, home directory.
String pathStr = "/";
Path homeDir = Paths.get(System.getProperty("user.dir"))
Getting from the user directory into the data directory: homeDir.get("data")
Path dataPath = Paths.get(System.getProperty("user.dir"));
File dataFile = dataPath.toFile();
Now use operations on dataFile, to check what files and directories there are, on that location of the file system.
I do not own a Windows copy, but would like to know the behavior and recommended usage in Java for representing a path such as \autoexec.bat under Windows?
Semantically, such a path would represent the file autoexec.bat on the root of any file system. Thus it would need to be resolved against a path representing a disk drive (such as C:\) before representing a file. In that sense, it is not absolute. However, it also does not have a root component, I suppose.
Can such path be created when running the JVM on Windows? If so, what would getRoot() and isAbsolute() return?
I tried the following code using Memory File System, but this throws InvalidPathException: “path must not start with separator at index 1: \truc”. Does this faithfully reflect the behavior under Windows, or is it a quirk of this specific library?
try (FileSystem fs = MemoryFileSystemBuilder.newWindows().build()) {
final Path truc = fs.getPath("\\truc");
LOGGER.info("Root: {}.", truc.getRoot());
LOGGER.info("Abs: {}.", truc.isAbsolute());
LOGGER.info("Abs: {}.", truc.toAbsolutePath());
}
Such paths are valid in the Windows terminal, or at least they were last time I used Windows (a long time ago). It would be handy to create such path in order to mark that the path is “absolute” (in the sense of starting with a backslash, thus not relative to a folder), but still leave the path without a driver letter specified. Then such a path can be (later) resolved to C:\autoexec.bat or D:\autoexec.bat or …
In Windows, \\ refers to the current drive which is C:\ in my case.
Not sure how the MemoryFileSystemBuilder works but the following code
File file = new File("\\test.txt");
final Path truc = file.toPath();
System.out.println("Root: " + truc.getRoot().toString());
System.out.println("Abs: " + truc.isAbsolute());
System.out.println("Abs: " + truc.toAbsolutePath().toString());
gives the below output
Root: \
Abs: false
Abs: C:\test.txt
I am working in a java code that was designed to run on windows and contains a lot of references to files using windows style paths "System.getProperty("user.dir")\trash\blah". I am in charge to adapt it and deploy in linux. Is there an efficient way to convert all those paths(\) to unix style (/) like in "System.getProperty("user.dir")/trash/blah". Maybe, some configuration in java or linux to use \ as /.
My approach is to use the Path object to hold the path information, handle concatenate and relative path. Then, call Path's toString() to get the path String.
For converting the path separator, I preferred to use the apache common io library's FilenameUtils. It provides the three usefule functions:
String separatorsToSystem(String path);
String separatorsToUnix(String path);
String separatorsToWindows(String path)
Please look the code snippet, for relative path, toString, and separator changes:
private String getRelativePathString(String volume, Path path) {
Path volumePath = Paths.get(configuration.getPathForVolume(volume));
Path relativePath = volumePath.relativize(path);
return FilenameUtils.separatorsToUnix(relativePath.toString());
}
I reread your question and realize you likely don't need help writing paths. For what you're trying to do I am not able to find a solution. When I did this in a project recently I had to take time to convert all paths. Further, I made the assumption that working out of the "user.home" as a root directory was relatively sure to include write access for that user running my application. In any case, here are some path problems I addressed.
I rewrote the original Windows code like so:
String windowsPath = "C:\temp\directory"; //no permission or non-existing in osx or linux
String otherWindowsPath = System.getProperty("user.home") + "\Documents\AppFolder";
String multiPlatformPath = System.getProperty("user.home") + File.separator + "Documents" + File.separator + "AppFolder";
If you're going to be doing this in a lot of different places, perhaps write a utility class and override the toString() method to give you your unix path over and over again.
String otherWindowsPath = System.getProperty("user.home") + "\Documents\AppFolder";
otherWindowsPath.replace("\\", File.separator);
Write a script, replace all "\\" with a single forward slash, which Java will convert to the respected OS path.
Below is a path to my Windows directory. Normally the path should have \ instead of // but both seem to work.
String WinDir = "C://trash//blah//blah";
Same for a Linux path. The normal should have a / instead of //. The below and above snippet work fine and will grab the contents of the files specified.
String LinuxDir = "//foo//bar//blah"
So, both use strange declarations of file paths, but both seem to work fine. Elaboration please.
For example,
File file = new File(WinDir);`
file.mkdir();`
Normally, when specifying file paths on Windows, you would use backslashes. However, in Java, and many other places outside the Windows world, backslashes are the escape character, so you have to double them up. In Java, Windows paths often look like this: String WinDir = "C:\\trash\\blah\\blah";. Forward slashes, on the other hand, do not need to be doubled up and work on both Windows and Unix. There is no harm in having double forward slashes. They do nothing to the path and just take up space (// is equivalent to /./). It looks like someone just did a relpace of all backslashes into forward slashes. You can remove them. In Java, there is a field called File.separator (a String) and File.separatorChar (a char), that provide you with the correct separator (/ or \), depending on your platform. It may be better to use that in some cases: String WinDir = "C:" + File.separator + "trash" + File.separator + "blah" + File.separator + "blah";
With java.nio.path, you even better get an independent OS path without any concern about path delimiter.
public class PathsGetMethod {
public static void main(String[] args) {
Path path = Paths.get("C:\\Users\\conta\\OneDrive\\", "desktop", "data");
System.out.println(path);
//C:\Users\conta\OneDrive\desktop\data
}
}
I need to use windows file path to do some operation on files but i am getting invalid escape sequence error.
File f = new File("C:\test");
the system accepts only " \\ " or "/" but if I copy file path from windows it is with "\".
how can i solve this issue
Use File.separator in place of "".
File f = new File("C:"+File.separator+"test");
File.separator returns "" and it is not treated as an escape character.
If your file test.txt is saved in folder D:/MyFloder/MyPrograms you can do something like this
File f = new File("D:"+File.seperator+"MyFloder"+File.separator+"MyPrograms"+File.separator+"test.txt");
EDIT
You don't need to worry about OS
For Unix : File.separator = /
For Windows : File.separator = \
\ is the escape character in Java Strings. Use \\ instead.
"C:\\test" resolves to the String C:\test
You can use \\ or / but / is better because it is OS-independent.
Replace the single backslash in the path with a double backslash or a single forward slash to solve your issue.
Internally, Java will convert it to the file seperator of the OS
File f = new File("C:\\test"); is correct.
You are not creating a File with the path "C:\\test" here. You are creating a File with the path "C:\test". The \\-to-\ conversion happens when you compile the program - by the time your program is running, the double backslashes are gone.
The same for String - String s = "C:\\test"; does not create a string with two backslashes, only one.
You can think of it this way: the string does not actually have two backslashes, but you have to write it that way to put it in your code.
You might be wondering why that is - it's because backslashes are used to insert special characters in strings. When you type \t in a string it inserts a tab, for example. If you want to insert a backslash, then t, you type \\t.
you can use '/' (as in Linux) in paths since Windows XP, so forget about \
Use java.nio.file.Path instead of java.io, you'll not have problem with escape sequence character :
import java.nio.file.Path;
import java.nio.file.Paths;
Path path = Paths.get("C:\test");