URI is not absolute? - java

I have a File
/user/guest/work/test/src/main/java/Test.java
And a File-Object:
File f = new File("/user/guest/work/test/src/main/java/Test.java");
I need this outputs
System.out.println(f); -> src/main/java/Test.java
System.out.println(f.getAbsolutePath()); -> /user/guest/work/test/src/main/java/Test.java
I tried:
File relativeTo = new File("/user/guest/work/test");
new File(relativeTo.toURI().relativize(f.toURI()));
but it is throwing a
java.lang.IllegalArgumentException: URI is not absolute
at java.io.File.<init>(File.java:416)
at Test.<init>(Test.java:43)
How to get the required output?

relativize returns a URI.
a new File(URI uri) takes...
uri - An absolute, hierarchical URI
You can instead try using the String constructor.
new File(relativeTo.toURI().relativize(f.toURI()).toString());
You have access to that file other ways, however
For example, you can try going through the java.nio.file.Path API instead of java.io.File
Like
Path path = Paths.get("/", "user", "guest", "workspace",
"test", "src", "main", "java", "Test.java");
Path other = ...
Path relPath = other.relativize(path);
// relPath.toString(); // print it
// relPath.toFile(); // get a file

You can use path resolve to relativize file paths
File f = new File("/user/guest/workspace/test/src/main/java/Test.java");
File relativeTo = new File("/user/guest/workspace/test");
System.out.println(new File(relativeTo.toPath().resolve(f.toPath()).toUri()));

Related

How to get absolute directory path from relative path + classloader

I have a class whose constructor receives a relative resources path (language properties files) and the corresponding classloader (the path is relative to the package of the classLoader):
public Language(String relDir, ClassLoader classLoader) {
...
}
Whithin that class I have a method that loads all found resource files (properties files such as MyFile_en_GB.properties), and it doesn't know whow many language resources there will be beforehand. It uses languagesDir as an absolute path for finding the resources.
private void loadLanguages() {
DirectoryStream.Filter<Path> filter = (path) -> {
return Files.isRegularFile(path) & path.getFileName()toString().startsWith("MyFile");
};
try (DirectoryStream<Path> stream = Files.newDirectoryStream(languagesDir, filter)) {
for (Path entry : stream) {
String fileName = entry.getFilename().toString();
...
loadPropertiesFile(filename)
}
} catch (..) {}
}
There, languagesDir works with an absolute path. However, when I tried:
String dir = classLoader.getResource(relDir).toString();
it throws an exception. I guess it is because it expects a file and not a directory
How can I get the absolute path of the resources? Should I try another aproach and work only with relative paths (how to do this)?
edit: About the exception:
classLoader.getResource(relDir) gives a null URL
try to use resourceFile.getName() after change URL to file.
URL resourceURL = classLoader.getResource(..);
File resourceFile = new File(new URL(resourceURL).toURI());
String fullPath = resourceFile.getName();
it throws an exception. I guess it is because it expects a file and
not a directory
If that is the case you can feed files instead directory. To get the absolute path you try as below
String dirPath = "C:\\Softwares";
File dir = new File( dirPath );
for ( String fileName : dir.list() ) {
File file = new File( dirPath + "\\" + fileName );
if ( file.isFile() ) {
// System.out.println( file.getAbsolutePath() );
String dir = classLoader.getResource( file.getAbsolutePath() ).toString();
}
}

How to get absolute path from FileDialog?

I'm creating FileDialog and trying to get a FilePath for FileDialog object.
FileDialog fd = new FileDialog(this, "Open", FileDialog.LOAD);
fd.setVisible(true);
String path = ?;
File f = new File(path);
In this codes, I need to get a absolute FilePath for using with File object.
How can I get filepath in this situation?
You can combine FileDialog.getDirectory() with FileDialog.getFile() to get a full path.
String path = fd.getDirectory() + fd.getFile();
File f = new File(path);
I needed to use the above instead of a call to File.getAbsolutePath() since getAbsolutePath() was returning the path of the current working directory and not the path of the file chosen in the FileDialog.
Check out File.getAbsolutePath():
String path = new File(fd.getFile()).getAbsolutePath();

How to get absolute path with proper character encoding in Java?

I'd like to get the absolute path of a file, so that I can use it further to locate this file. I do it the following way:
File file = new File(Swagger2MarkupConverterTest.class.getResource(
"/json/swagger.json").getFile());
String tempPath = file.getAbsolutePath();
String path = tempPath.replace("\\", "\\\\");
The path irl looks like this:
C:\\Users\\Michał Szydłowski\\workspace2\\swagger2markup\\bin\\json\\swagger.json
However, since it contains Polish characters and spaces, what I get from getAbsolutPath is:
C:\\Users\\Micha%c5%82%20Szyd%c5%82owski\\workspace2\\swagger2markup\\bin\\json\\swagger.json
How can I get it to do it the right way? This is problematic, because with this path, it cannot locate the file (says it doesn't exist).
The URL.getFile call you are using returns the file part of a URL encoded according to the URL encoding rules. You need to decode the string using URLDecoder before giving it to File:
String path = Swagger2MarkupConverterTest.class.getResource(
"/json/swagger.json").getFile();
path = URLDecoder.decode(path, "UTF-8");
File file = new File(path);
From Java 7 onwards you can use StandardCharsets.UTF_8
path = URLDecoder.decode(path, StandardCharsets.UTF_8);
The simplest way, that doesn't involve decoding anything, is this:
URL resource = YourClass.class.getResource("abc");
Paths.get(resource.toURI()).toFile();
// or, equivalently:
new File(resource.toURI());
It doesn't matter now where the file in the classpath physically is, it will be found as long as the resource is actually a file and not a JAR entry.
URI uri = new File(Swagger2MarkupConverterTest.class.getResource(
"/json/swagger.json").getFile()).toURI();
File f = new File(uri);
System.out.println(f.exists());
You can use URI to encode your path, and open File by URI.
You can use simply
File file = new File("file_path");
String charset = "UTF-8";
BufferedReader reader = new BufferedReader(new InputStreamReader(
new FileInputStream(file), charset));
give the charset at the time of read the file.

How to get the parent folder of a folder

Let's say we have:
String path = "D:\aaa\bbb\ccc"
I wonder if there is a function to modify quickly path to:
D:\aaa\bbb\ or D:\aaa\
I tried to use Paths with no luck:
path = "D:\\aaa\\bbb\\ccc";
pathNew = java.nio.file.Paths.get(path).subpath(0,2).toString();
println "${pathNew}"
Gives the next console result:
aaa\bbb
You can do:
String path = "D:\\aaa\\bbb\\ccc";
File parent = new File(path).getParentFile();
System.out.println(parent);
String parentStr = new File(path).getParent();
System.out.println(parentStr);
Prints:
D:\aaa\bbb
D:\aaa\bbb
You can do like this:
Path p1 = Paths.get("D:\\aaa\\bbb\\ccc");
Path p2 = p1.getParent();
....
try this
Path path = Paths.get("your path");
Path parentPath = path.getParent();
File path = new File("D:\aaa\bbb\ccc");
path.getParentFile(); // Returns "D:\aaa\bbb\"
path.getParentFile().getParentFile(); // Returns D:\aaa\"
File parent = new File("D:\\aaa\\bbb\\ccc").getParent();
System.out.println(parent);

Can I compose two file paths without needing their toString() methods?

Imagine I have a 'base' path object, denoting a directory, and a 'relative' path object denoting some file within the base.
I would expect that code to look somewhat like
AbsolutePath base = new AbsolutePath("/tmp/adirectory");
RelativePath relativeFilePath = new RelativePath("filex.txt");
AbsolutePath absoluteFile = base.append( relativeFilePath );
But in the Java API (which I don't yet know very well) I find only File, with which I can do nothing better than
File base = new File("/tmp/adirectory");
File relativeFilePath = new File("filex.txt");
File absoluteFile = base.toString()
+ File.separator
+ relativeFilePath.toString();
Is there a better way?
The closest you can get with java.io.File is the File(File, String) constructor:
File base = ...;
File relative = ...;
File combined = new File(base, relative.toString());
If you can use the Path class introduced in Java 7, then you can use the resolve() method, which does exactly what you want:
Path base = ...;
Path relative = ...;
Path combined = base.resolve(relative);
Please note that if base is not an absolute path, then combined won't be absolute either! If you need an absolute path, then for a File you'd use getAbsoluteFile() and for a Path you'd use toAbsoutePath().
Yes. new File(base, "filex.txt") will create a file names "filex.txt" in the directory base.
There is no need to create a relativeFilePath File instance with just the relative name if what you want to do is make it relative to another directory than the current one.
how about:
File base = new File("/tmp/adirectory");
File absoluteFile = new File(base, "filex.txt");
EDIT: Too late #JB Nizet pipped me at the post...
The File class has some constructors which may be of interest to you:
File base = new File("/tmp/adirectory");
File absolute = new File(base, "filex.txt");
File absolute2 = new File("/tmp/adirectory", "filex.txt");

Categories