Java.io.file constructor to deal with UNC file path - java

When I try to use the JAR file in the UNC path, I find I met a problem. The constructor of java.io.file will always convert a UNC file path to local path.
For example, I try
String dirStr = "file:\\\\dir1\dir2\file.jar!Myclass";
File ff = new File(dirStr);
System.out.println(ff.toString());
I'll get output like: file:\dir1\dir2\file.jar!Myclass. But what I expect to get is file:\\dir1\dir2\file.jar!MyClass.
I tried to add more slashes in the dirStr, but it can't work. Because in the java.io.file, it'll call method to remove duplicated slashes.
And I try to use the URI to create the ff. But the output will be \dir1\dir2\file.jar!Myclass, which is not available to use JAR file successfully. I think the form of JAR must be start with the file: protocol to use parse the string ending with ! in above string \dir1\dir2\file.jar!Myclass.
Is there any way can new File() to get the pathname of File, i.e. ff, like file:\\dir1\dir2\file.jar!MyClass.

Since your input dir String is UNC type, i think you should use Java's URI.
Example code:
URI uri = new URI(dirStr);
System.out.println(uri.toString()); // If you want to get the path as URI
File ff = new File(uri.getPath()); // If you want to access the file.
The other better way is using Path:
URI uri = new URI(dirStr);
Path path = Paths.get(uri); // Or directly Path path = Paths.get(dirStr);
File ff = path.toFile(); // << your file here
path.toUri(); // << your uri path here

The constructor File(String) takes a path, not a URL. Remove the file: part and use two backslashes for every one in the actual filename, to satisfy the compiler's escaping rules. Or use the correct number of forward slashes.

Related

Get path of file without drive letter - Windows 10 / Java 8

Windows 10
Java 8
When I call getCanonicalPath on a File object, I get a string like this
C:\data\processed\Test.xml
How do I get the same string but without C:\ and if possible also with / instead of \?
You can use NIO.2 API and its objects Path and Paths which is a abstraction over a file system.
Path path = Paths.get("C:\\data\\processed\\Test.xml");
You can also get Path from File using File::toPath. Actually, you need to get all the names in the path:
File file = new File("C:\\data\\processed\\Test.xml");
Path path = file.toPath();
int count = path.getNameCount(); // the count of names
path = path.subpath(0, count); // all the names
Alternatively (thanks to #Holger) using Path:relativize (you find a relative path to the root C:/ which is all the names.
File file = new File("C:\\data\\processed\\Test.xml");
Path path = file.toPath();
path = path.getRoot().relativize(path);
Here are some relevant methods:
path.getRoot() returns C:\
path.getNameCount() returns the number of name elements in the path (3 in this case)
path.getName(0) returns data, path.getName(1) returns processed etc...
path.subpath(fromInclusive, toExclusive) returns a relative Path that is a subsequence of the name elements of this path.
path.relativize(path) returns a relative path to a parameter.
The object Path represents an abstraction of the actual path. If you want to replace \ with / as a String, you might need to use String::replace.
String stringPath = path.toString().replace('\\', '/');
System.out.println(path); // data\processed\Test.xml
System.out.println(stringPath); // data/processed/Test.xml
Here is a short answer:
File file = new File("c:\\tmp\\abc.txt"); //file =C:\tmp\abc.txt
String filePath= file.getCanonicalPath(); //path= C:\tmp\abc.txt
String str=filePath.replace('\\', '/'); //str= C:/tmp/abc.txt
java.net.URI uri= new java.net.URI(str); //uri= C:/tmp/abc.txt
uri.getPath(); //uri.getPath() = /tmp/abc.txt

Java parse File-path with different working directory

I have a file which contain several paths, like . (relative) or /Users/...../ (absolut). I need to parse the paths that are relative to the directory of the file that contains the paths and not the working-directory and create correct File-instances. I can not change the working directory of the Java-Program, since this would alter the behaviour of other components and i also have to parse several files. I don't think public File(String parent, String child)does what i want, but i may be wrong. The documentation is quite confusing.
Example:
file xy located under /system/exampleProgram/config.config has the following content:
.
/Users/Name/file
./extensions
i want to resolve these to:
/system/exampleProgram/
/Users/Name/file
/system/exampleProgram/file/
So, I am going to assume that you have access to the path of the file you opened (either via File.getAbsolutePath() if it was a File descriptor or via a regex or something)...
Then to translate your relative paths into absolute paths, you can create new File descriptions with your opened file, like so:
File f = new File(myOpenedFilePath);
File g = new File(f, "./extensions");
String absolutePath = g.getCanonicalPath();
When you create a file with a File object and a String, Java treats the String as a path relative to the File given as a first argument. getCanonicalPath will get rid of all the redundant . and .. and such.
Edit: as Leander explained in the comments, the best way to determine whether the path is relative or not (and thus whether it should be transformed or not) is to use file.isAbsolute().
Sounds like you probably want something like
File fileContainingPaths = new File(pathToFileContainingPaths);
String directoryOfFileContainingPaths =
fileContainingPaths.getCanonicalFile().getParent();
BufferedReader r = new BufferedReader(new FileReader(fileContainingPaths));
String path;
while ((path = r.readLine()) != null) {
if (path.startsWith(File.separator)) {
System.out.println(path);
} else {
System.out.println(directoryOfFileContainingPaths + File.separator + path);
}
}
r.close();
Don't forget the getCanonicalFile(). (You might also consider using getAbsoluteFile()).

Create directory at given path in Java - Path with space

I have my java code like below-
string folderName = "d:\my folder path\ActualFolderName";
File folder = new File( folderName );
folder.mkdirs();
So here as given directory path has space in it. folder created is d:\my, not the one I am expecting.
Is there any special way to handle space in file/folder paths.
You should us \\ for path in java. Try this code
String folderName = "D:\\my folder path\\ActualFolderName";
File folder = new File( folderName );
folder.mkdirs();
Or use front-slashes / so your application will be OS independent.
String folderName = "D:/my folder path1/ActualFolderName";
Unless you are running a really old version of Java, use the Path API from JDK7:
Path p = Paths.get("d:", "my folder path", "ActualFolderName");
File f = p.toFile();
It will take care of file separators and spaces for you automatically, regardless of OS.
Following alternatives should work in Windows:
String folderName = "d:\\my\\ folder\\ path\\ActualFolderName";
String folderName = "\"d:\\my folder path\\ActualFolderName\"";
You need to escape your path (use \\ in your path instead of \) and you also need to use String, with an uppercase S, as the code you posted does not compile. Try this instead, which should work:
String folderName = "D:\\my folder path\\ActualFolderName";
new File(folderName).mkdirs();
If you are getting your folder name from user input (ie.not hardcoded in your code), you don't need to escape, but you should ensure that it is really what you expect it is (print it out in your code before creating the File to verify).
If your are still having problems, you might want to try using the system file separator character, which you can get with System.getProperty(file.separator) or accesing the equivalent field in the File class. Also check this question.
You need to escape path seprator:
String folderName = "D:\\my folder path\\ActualFolderName";
File file = new File(folderName);
if (!file.exists()) {
file.mkdirs();
}
First of all, the String path you have is incorrect anyway as the backslash must be escaped with another backslash, otherwise \m is interpreted as a special character.
How about using a file URI?
String folderName = "d:\\my folder path\\ActualFolderName";
URI folderUri = new URI("file:///" + folderName.replaceAll(" ", "%20"));
File folder = new File(folderUri);
folder.mkdirs();

Convert URL to normal windows filename Java

Is there a way to convert this:
/C:/Users/David/Dropbox/My%20Programs/Java/Test/bin/myJar.jar
into this?:
C:\Users\David\Dropbox\My Programs\Java\Test\bin\myJar.jar
I am using the following code, which will return the full path of the .JAR archive, or the /bin directory.
fullPath = new String(MainInterface.class.getProtectionDomain()
.getCodeSource().getLocation().getPath());
The problem is, getLocation() returns a URL and I need a normal windows filename.
I have tried adding the following after getLocation():
toString() and toExternalForm() both return:
file:/C:/Users/David/Dropbox/My%20Programs/Java/Test/bin/
getPath() returns:
/C:/Users/David/Dropbox/My%20Programs/Java/Test/bin/
Note the %20 which should be converted to space.
Is there a quick and easy way of doing this?
The current recommendation (with JDK 1.7+) is to convert URL → URI → Path. So to convert a URL to File, you would say Paths.get(url.toURI()).toFile(). If you can’t use JDK 1.7 yet, I would recommend new File(URI.getSchemeSpecificPart()).
Converting file → URI: First I’ll show you some examples of what URIs you are likely to get in Java.
-classpath URLClassLoader File.toURI() Path.toUri()
C:\Program Files file:/C:/Program%20Files/ file:/C:/Program%20Files/ file:///C:/Program%20Files/
C:\main.c++ file:/C:/main.c++ file:/C:/main.c++ file:///C:/main.c++
\\VBOXSVR\Downloads file://VBOXSVR/Downloads/ file:////VBOXSVR/Downloads/ file://VBOXSVR/Downloads/
C:\Résume.txt file:/C:/R%c3%a9sume.txt file:/C:/Résume.txt file:///C:/Résume.txt
\\?\C:\Windows (non-path) file://%3f/C:/Windows/ file:////%3F/C:/Windows/ InvalidPathException
Some observations about these URIs:
The URI specifications are RFC 1738: URL, superseded by RFC 2396: URI, superseded by RFC 3986: URI. (The WHATWG also has a URI spec, but it does not specify how file URIs should be interpreted.) Any reserved characters within the path are percent-quoted, and non-ascii characters in a URI are percent-quoted when you call URI.toASCIIString().
File.toURI() is worse than Path.toUri() because File.toURI() returns an unusual non-RFC 1738 URI (gives file:/ instead of file:///) and does not format URIs for UNC paths according to Microsoft’s preferred format. None of these UNC URIs work in Firefox though (Firefox requires file://///).
Path is more strict than File; you cannot construct an invalid Path from “\.\” prefix. “These prefixes are not used as part of the path itself,” but they can be passed to Win32 APIs.
Converting URI → file: Let’s try converting the preceding examples to files:
new File(URI) Paths.get(URI) new File(URI.getSchemeSpecificPart())
file:///C:/Program%20Files C:\Program Files C:\Program Files C:\Program Files
file:/C:/Program%20Files C:\Program Files C:\Program Files C:\Program Files
file:///C:/main.c++ C:\main.c++ C:\main.c++ C:\main.c++
file://VBOXSVR/Downloads/ IllegalArgumentException \\VBOXSVR\Downloads\ \\VBOXSVR\Downloads
file:////VBOXSVR/Downloads/ \\VBOXSVR\Downloads \\VBOXSVR\Downloads\ \\VBOXSVR\Downloads
file://///VBOXSVR/Downloads \\VBOXSVR\Downloads \\VBOXSVR\Downloads\ \\VBOXSVR\Downloads
file://%3f/C:/Windows/ IllegalArgumentException IllegalArgumentException \\?\C:\Windows
file:////%3F/C:/Windows/ \\?\C:\Windows InvalidPathException \\?\C:\Windows
Again, using Paths.get(URI) is preferred over new File(URI), because Path is able to handle the UNC URI and reject invalid paths with the \?\ prefix. But if you can’t use Java 1.7, say new File(URI.getSchemeSpecificPart()) instead.
By the way, do not use URLDecoder to decode a file URL. For files containing “+” such as “file:///C:/main.c++”, URLDecoder will turn it into “C:\main.c  ”! URLDecoder is only for parsing application/x-www-form-urlencoded HTML form submissions within a URI’s query (param=value&param=value), not for unquoting a URI’s path.
2014-09: edited to add examples.
String path = "/c:/foo%20bar/baz.jpg";
path = URLDecoder.decode(path, "utf-8");
path = new File(path).getPath();
System.out.println(path); // prints: c:\foo bar\baz.jpg
The current answers seem fishy to me.
java.net.URL.getFile
turns a file URL such as this
java.net.URL = file:/C:/some/resource.txt
into this
java.lang.String = /C:/some/resource.txt
so you can use this constructor
new File(url.getFile)
to give you the Windows path
java.io.File = C:\some\resource.txt
As was mentioned - getLocation() returns an URL. File can easily convert an URI to a path so for me the simpliest way is just use:
File fullPath = new File(MainInterface.class.getProtectionDomain().
getCodeSource().getLocation().toURI());
Of course if you really need String, just modify to:
String fullPath = new File(MainInterface.class.getProtectionDomain().
getCodeSource().getLocation().toURI()).toString();
You don't need URLDecoder at all.
The following code is what you need:
String path = URLDecoder.decode("/C:/Users/David/Dropbox/My%20Programs/Java/Test/bin/", "UTF-8");
System.out.println(new File(path).getPath());
Hello confused people from the future. There is a nuance to the file path configuration here. The path you are setting for TESSDATA_PREFIX is used internally by the C++ tesseract program, not by the java wrapper. This means that if you're using windows you will need to replace the leading slash and replace all other forward slashes with backslashes. A very hacky workaround looks like this:
URL pathUrl = this.getClass().getResource(TESS_DATA_PATH);
String pathStr = pathUrl.getPath();
// hack to get around windows using \ instead of /
if (SystemUtils.IS_OS_WINDOWS) {
pathStr = pathStr.substring(1);
pathStr = pathStr.replaceAll("/", "\\\\");
}

Convert URL to AbsolutePath

Is there any easy way to convert a URL that contains to two-byte characters into an absolute path?
The reason I ask is I am trying to find resources like this:
URL url=getClass().getResources("/getresources/test.txt");
String path=url.toString();
File f=new File(path);
The program can't find the file. I know the path contain '%20' for all spaces which I could convert but my real problem is I'm using a japanese OS and when the program jar file is in a directory with japanese text (for example デスクトップ) I get the URL-encoding of the directory name,
like this:
%e3%83%87%e3%82%b9%e3%82%af%e3%83%88%e3%83%83%e3%83%97
I think I could get the UTF-8 byte codes and convert this into the proper characters to find the file, but I'm wondering if there is an easier way to do this. Any help would be greatly appreciated.
nt
URL url = getClass().getResource("/getresources/test.txt");
File f = new File(url.toURI());
If you were interested in getting Path from URL, you can do:
Path p = Paths.get(url.toURI());
File has a constructor taking an argument of type java.net.URI for this case:
File f = new File(url.toURI());
Another option for those who use Java 11 or later:
Path path = Path.of(url.toURI());
or as a string:
String path = Path.of(url.toURI()).toString();
Both methods above throw a URISyntaxException that can be safely ignored if the URL is guaranteed to be a file URL.

Categories