Java NIO file path issue
Asked Answered
W

8

56

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.

Winwaloe answered 23/3, 2012 at 5:59 Comment(2)
I wonder why I get the leading character a '/', instead of '\' like in the question. I'm using Windows 10, Java 8, Spring 3.2.14.RELEASE.Hrutkay
The error in our case was from: ClassLoader.getSystemResource("something").getPath() - on windows it was dropping file: from file:/C:/mypathCobia
P
38

The path \C:\Sample\sample.txt must not have a leading \. It should be just C:\Sample\sample.txt

Panne answered 23/3, 2012 at 6:28 Comment(3)
ah... the code i was using to get the errorFile path was adding that leading \. Thanks.Winwaloe
wa~, get a absolute path, and developer must remove a "/" at head, Isn't it a bug in WindowsOS or Path class ?Colloquialism
The same issue I get while executing in jenkins java.nio.file.InvalidPathException: Illegal char <"> at index 0: "--tags at web.TestParallel.testParallel(TestParallel.java:23) Line 23: Results results = Runner.parallel(getClass(), 5, "target/surefire-reports");Didier
S
48

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();
Suzan answered 12/8, 2015 at 6:37 Comment(1)
It's better than the accepted answer because sometimes, it won't be you who will type the path, but you will get it by using something like ClassLoader.getResource() in which case it will automatically add that backslash that he talked about in the accepted answer! +1Movable
P
38

The path \C:\Sample\sample.txt must not have a leading \. It should be just C:\Sample\sample.txt

Panne answered 23/3, 2012 at 6:28 Comment(3)
ah... the code i was using to get the errorFile path was adding that leading \. Thanks.Winwaloe
wa~, get a absolute path, and developer must remove a "/" at head, Isn't it a bug in WindowsOS or Path class ?Colloquialism
The same issue I get while executing in jenkins java.nio.file.InvalidPathException: Illegal char <"> at index 0: "--tags at web.TestParallel.testParallel(TestParallel.java:23) Line 23: Results results = Runner.parallel(getClass(), 5, "target/surefire-reports");Didier
S
18

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;
Sheets answered 27/5, 2014 at 15:13 Comment(1)
@Eric my answer is more generic for any OS specific behaviour. Both are valuable.Sheets
G
17

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.

Gera answered 22/9, 2015 at 16:57 Comment(3)
In the OP the leading character is '\', though I am get the '/' character, like in your answer, any thoughts on why the difference?Hrutkay
Ah, good catch. No, I'm not sure why the difference. I personally saw the /. So, if someone is seeing `, they could modify the regular expression to catch the `.Gera
Could grab the Environment path separator, or use "^[/\\/](.:/)" the character class would match either slash.Harold
C
4

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()
Clinkstone answered 18/1, 2018 at 9:32 Comment(0)
M
1

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

Magalymagan answered 23/3, 2012 at 6:38 Comment(0)
M
0

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:\\"));
Martino answered 14/8, 2013 at 17:36 Comment(2)
This is good, but will only work if the file is on the C drive. Check out my answer for a solution that will work on any drive letter.Gera
What do you mean by Linux-Like Windows? Is it a different distribution of Windows, or is there any configuration in Windows to enable that?Gateshead
I
0

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);
Instar answered 10/4, 2019 at 9:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.