I am looking to write and read text files to and from (respectively) a directory different from that of my program. When I specify a directory to write to or read from, should I be using forward slashes or backslashes to identify a file path?
Using forward slashes will make it system independent. I'd stick to that for simplicity.
Consider using java.io.File.separator if you ever display the path to the user. You'd rather not surprise those Windows users. They're a jumpy lot.
I've never found it documented anywhere, but the JDK classes let you use slashes regardless of whether you're on Windows or not. (You can see this in the JDK source, where it explicitly converts path separators for you.)
Officially — and certainly in any UI you're doing — you should use the file.separator system property, which is available via System.getProperty(the list of standard system properties is documented in the docs for System.getProperties):
String sep = System.getProperty("file.separator");
...and also via the static fields They're also available as File.separator (and File.separatorChar).
You can also use the various features of the java.io.File class for combining and splitting paths, and/or the various features of the interfaces and classes in java.nio.file.
You could use either.
If you use / then you only need a single slash.
If you use \, you need to use \\. That is, you need to escape it.
You can also use the resolve() method of the java.nio.Path class to add directories / files to the existing path. That avoids the hassle of using forward or backward slashes. You can then get the absolute path by calling the toAbsolutePath() method followed by toString()
SSCCE:
import java.nio.file.Path;
import java.nio.file.Paths;
public class PathSeperator {
public static void main(String[] args) {
// the path seperator for this system
String pathSep = System.getProperty("path.separator");
// my home directory
Path homeDir = Paths.get(System.getProperty("user.home"));
// lets print them
System.out.println("Path Sep: " + pathSep);
System.out.println(homeDir.toAbsolutePath());
// as it turns out, on my linux it is a colon
// and Java is using forward slash internally
// lets add some more directories to the user.home
homeDir = homeDir.resolve("eclipse").resolve("configuration");
System.out.println("Appending more directories using resolve()");
System.out.println(homeDir);
}
}
You should use /
For example C:/User/...
Related
Lets say I have a directory-structure.
/a/b/c/<unknown name>/d/e/f/<files>
for Windows:
C:\a\b\c\<unknown name>\d\e\f<files>
I know a/b/c is always there and also d/e/f/.
I do not know the directory () between them but I know there is only 1.
Is there a way in Java I can name this path without finding out the name of the 1 unknown directory to access ??
Like so?
/a/b/c/*/d/e/f
Yes, it is possible but probably not as straightforward as you think, you'd use the Files.walk method like follows:
Path root = Paths.get("S:\\Coding\\");
String prefix = "A\\AB";
String suffix = "B\\C";
Path searchRoot = root.resolve(prefix);
System.err.println(searchRoot);
List<Path> paths = Files.walk(searchRoot).filter(f -> f.endsWith(suffix)).collect(Collectors.toList());
paths.forEach(System.out::println);
Outputs:
stderr: S:\Coding\A\AB
stdout: S:\Coding\A\AB\ZZZ\B\C
Lets say you have a dockerized app based on a linux distribution.
You can run this unix command: find . -name d/e/f/yourFilename using Process Builder
This will return the complete filepath to your file which will include the unknown portion. And then you can assign it to a String and use in your Java app.
You can hardcode your search method as indicated in other answers. Or, to stay flexible match against patterns. You would need some pattern language to specify your path:
Shells typically use globbing.
Alternatively you could use regexp to distinguish wanted from unwanted files.
Once you have such a pattern matcher, use a tree walking algorithm (traverse the directory structure recursively), match each absolute path name with your pattern. If it matches, perform some action.
Be aware some globbing seems to exist in Java - see Match path string using glob in Java
I am in the middle of making a Java application which in particular takes a relative file path of the form
String path = "path/to/Plansystem/Xslt/omraade/../../../Kms/Xslt/Rense/Template.xslt"
and reduce / simplify the path expression, so that it provides an equivalent path, but without the double dots. That is, we should obtain this String:
String result = "path/to/Kms/Xslt/Rense/Template.xslt"
Currently, I have defined the following Regular expression:
String parentDirectory = $/\/(?!\.)([\w,_-]*)\.?([\w,_-]*)\/\.\.\//$
I then replace any match with a single slash. This approach seems to work, and I came up with the expression using Regexr.com, but it seems to me that my approach is a little hacky, and I would be surprised if this specific functionality is not available in some well tested, well developed library. Is anyone familiar with such a library?
Edit:
Based on the responses made by rzwitserloot and Andy Turner I realized that the following methods works for me:
public static String slash = "/"
public static final String backslashes = $/\\+/$
static String normalizePath(String first, String... more) {
String pathToReturn = Paths.get(first, more).normalize().toString().replaceAll(backslashes, slash)
return pathToReturn
}
Note that the replacement I make at the end is only due to a specific need I have, where I want to preserve the unix notation (even when running on Windows).
No, don't bother with regular expressions. There's an API for this!
Basic 'dot' removal:
import java.nio.file.Paths;
Paths.get("/Users/Birdie/../../Users/Birdie/workspace/../workspace").normalize()
Will get you a path representing /Users/Birdie/workspace.
You can go further and follow softlinks, even:
Paths.get("/Users/Birdie/../../Users/Birdie/workspace/../workspace").toRealPath()
Use java.nio.Path:
Path path = Paths.get("path/to/Plansystem/Xslt/omraade/../../../Kms/Xslt/Rense/Template.xslt");
Path normalized = path.normalize();
I used the following code to get the path
Path errorFilePath = FileSystems.getDefault().getPath(errorFile);
When I try to move a file using the File NIO, I get the error below:
java.nio.file.InvalidPathException: Illegal char <:> at index 2: \C:\Sample\sample.txt
I also tried using URL.encode(errorFile) which results in the same error.
You need to convert the found resource to URI. It works on all platforms and protects you from possible errors with paths. You must not worry about how full path looks like, whether it starts with '\' or other symbols. If you think about such details - you do something wrong.
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
String platformIndependentPath = Paths.get(classloader.getResource(errorFile).toURI()).toString();
The path \C:\Sample\sample.txt must not have a leading \. It should be just C:\Sample\sample.txt
To make it work on both Windows and Linux\OS X consider doing this:
String osAppropriatePath = System.getProperty( "os.name" ).contains( "indow" ) ? filePath.substring(1) : filePath;
If you want to worry about performance I'd store System.getProperty( "os.name" ).contains( "indow" ) as a constant like
private static final boolean IS_WINDOWS = System.getProperty( "os.name" ).contains( "indow" );
and then use:
String osAppropriatePath = IS_WINDOWS ? filePath.substring(1) : filePath;
To be sure to get the right path on Windows or Linux on any drive letter, you could do something like this:
path = path.replaceFirst("^/(.:/)", "$1");
That says: If the beginning of the string is a slash, then a character, then a colon and another slash, replace it with the character, the colon, and the slash (leaving the leading slash off).
If you're on Linux, you shouldn't end up with a colon in your path, and there won't be a match. If you are on Windows, this should work for any drive letter.
Another way to get rid of the leading separator is to create a new file and convert it to a string then:
new File(Platform.getInstallLocation().getURL().getFile()).toString()
try to use like this C:\\Sample\\sample.txt
Note the double backslashes. Because the backslash is a Java String escape character, you must type two of them to represent a single, "real" backslash.
or
Java allows either type of slash to be used on any platform, and translates it appropriately. This means that you could type. C:/Sample/sample.txt
and it will find the same file on Windows. However, we still have the "root" of the path as a problem.
The easiest solution to deal with files on multiple platforms is to always use relative path names. A file name like Sample/sample.txt
Normal Windows Environment
Disclaimer: I haven't tested this on a normal windows environment.
"\\C:\\" needs to be "C:\\"
final Path errorFilePath = Paths.get(FileSystems.getDefault().getPath(errorFile).toString().replace("\\C:\\","C:\\"));
Linux-Like Windows Environment
My Windows box has a Linux-Like environment so I had to change "/C:/" to be "C:\\".
This code was tested to work on a Linux-Like Windows Environment:
final Path errorFilePath = Paths.get(FileSystems.getDefault().getPath(errorFile).toString().replace("/C:/","C:\\"));
Depending on how are you going to use the Path object, you may be able to avoid using Path at all:
// works with normal files but on a deployed JAR gives "java.nio.file.InvalidPathException: Illegal char <:> "
URL urlIcon = MyGui.class.getResource("myIcon.png");
Path pathIcon = new File(urlIcon.getPath()).toPath();
byte bytesIcon[] = Files.readAllBytes(pathIcon);
// works with normal files and with files inside JAR:
InputStream in = MyGui.class.getClassLoader().getResourceAsStream("myIcon.png");
byte bytesIcon[] = new byte[5000];
in.read(bytesIcon);
I have a property file and under that I have define a property called:
config.folder = C:\myfolder\configfolder
now the problem is that when loading properties, this property returns me the vale like this:
C:myfolderconfigfolder
I want to replace this single forward slash with back slash so it return me the correct directory path. I know this is not compliance with Java.String. If the user use double forward slash I am able to convert but how can I convert single slash.
A better approach is to change the slash from backslash to forward slash, like so:
config.folder = C:/myfolde/configfolder
Java knows how to interpret this structure.
Change it to: config.folder = C:\\myfolder\\configfolder
I will suggest that you start using System Properties for this i.e. file.separator
String fileSeparator = System.getProperty("file.separator");
Now say you got the path as :
String str = "C:/myfolder/configfolder";
String fileSeparator = System.getProperty("file.separator");
str= str.replace("/", fileSeparator);
System.out.println(str);
OUTPUT is :
C:\myfolder\configfolder
This approach might help you implement your program in any OS For Example UNIX with "/" as the file separator for different components of the file path, and for WINDOWS with "\" as the file separator for components of the file path.
Hope this might help in some way.
Regards
the best way to play with the file path literal is to use the system properties i.e.string file separator =System.getProperty ("file.separator") then you can replace it with ur slash to get the file path regards
I am working with files (reading, writing and copying) in my Java application, java.io.File and commons-io were perfect for this kind of tasks.
Right now, I can link to HTML in this way:
Z:\an absolute\path\to\a\file.html
But, I need to provide support for anchors too:
Z:\an absolute\path\to\a\file.html#anchor
keeping the system-independence obtained by using java.io.File. So, I will need to extract the path and the anchor, I wonder whether it will be as easy as searching for a sharp occurrence.
java.io.File includes a constructor that accepts a URI, which can represent all kinds of resources, included URLs and local files (see the rfc). URI's also meets your requirements of supporting anchors, and extracting path information (through instance.getPath()).
File f = new File("Z:\\path\\to\\a\\file.html#anchor");
String anchor = f.toURL().getRef(); //note: toURL is deprecated
If you look at the java source you will see that it is as simple as:
String file = "Z:\\path\\to\\a\\file.html#anchor";
int ind = file.indexOf('#');
String anchor = ind < 0 ? null: file.substring(ind + 1);