46

I'm receiving an URL that locates a local file (the fact that I receive an URL is not in my control). The URL is escaped validly as defined in RFC2396. How can I transform this to a Java File object?

Funnily enough, the URL getFile() method returns a String, not a File.

I've created a directory called "/tmp/some dir" (with a spacing character between "some" and "dir"), which is correctly located by the following URL: "file:///tmp/some%20dir" (quotes added for clarity).

How can I convert that URL to a Java File?

To give more detail about my issue, the following prints false:

URL url = new URL( "file:///tmp/some%20dir" );
File f = new File( url.getFile() );
System.out.println( "Does dir exist? " + f.exists() );

While the following (manually replacing "%20" with a space) prints true:

URL url = new URL( "file:///tmp/some%20dir" );
File f = new File( url.getFile().replaceAll( "%20", " " ) );
System.out.println( "Does dir exist? " + f.exists() );

Note that I'm not asking why the first example prints false nor why the second example using my hacky replaceAll prints true, I'm asking how to convert an escaped URL into a Java File object.

EDIT: thanks all, this was nearly a dupe but not exactly.

Stupidly I was looking for a helper method inside the URL class itself.

The following works as expected to get a Java File from a Java URL:

URL url = new URL( "file:///home/nonet/some%20dir" );
File f = new File( URLDecoder.decode( url.getFile(), "UTF-8" ) );
SyntaxT3rr0r
  • 27,745
  • 21
  • 87
  • 120
  • See also http://weblogs.java.net/blog/kohsuke/archive/2007/04/how_to_convert.html for a caveat. – Vadzim Oct 01 '12 at 05:15

3 Answers3

71

The File constructor taking an URI in combination with URL#toURI() should work:

URL url = getItSomehow();
File file = new File(url.toURI());
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Well ... you only answered the part about getting the file from the URL. But hey, its the OP's choice as to which answer he thinks is *most* helpful. – Stephen C Jan 30 '10 at 02:40
  • Loved it too, seems to be the best answer. If only toURI wouldn't throw that nasty URISyntaxException... – Stijn de Witt Mar 11 '11 at 12:25
  • @Stijn: `URLDecoder#decode()` is also not free of checked exceptions. Either way, just add `throws IOException` to the method. – BalusC Mar 11 '11 at 12:31
20
URLDecoder.decode(url);//deprecated
URLDecoder.decode(url, "UTF-8"); //use this instead

See related question How do you unescape URLs in Java?

Community
  • 1
  • 1
Cesar
  • 5,488
  • 2
  • 29
  • 36
  • This method is deprecated. Use this one instead http://stackoverflow.com/questions/213506/java-net-urlencoder-encodestring-is-deprecated-what-should-i-use-instead – Mohamed Taher Alrefaie Jul 25 '13 at 11:32
  • 3
    If the URL is RFC2396-encoded (e.g. it came from `file.toURI()` or `new URI("file", null, file.getPath(), null)`), then **do not** decode it using [URLDecoder](http://docs.oracle.com/javase/7/docs/api/java/net/URLDecoder.html)! For example, if the file were “`main.c++`”, then URLDecoder would decode it as as “`main.c `”. URLDecoder is only used for decoding HTML form submissions. This is mentioned in the bottom of the [URL javadoc](http://docs.oracle.com/javase/7/docs/api/java/net/URL.html). – yonran Jul 25 '13 at 20:23
  • 1
    In case anyone is using Apache Commons IO take a look at FileUtils.toFile(URL) which should decode the URL properly (even if the path contains symbols such as + and &) – pm_ Mar 23 '18 at 12:52
7

AFAIK like this Paths.get(url.toURI()).toFile() is best, starting with Java 7. See also Converting Java file:// URL to File(...) path, platform independent, including UNC paths.

Community
  • 1
  • 1
vorburger
  • 3,439
  • 32
  • 38