[ 
https://issues.apache.org/jira/browse/VFS-443?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13496963#comment-13496963
 ] 

Joerg Schaible commented on VFS-443:
------------------------------------

Hi Greg,

actually I think this is not the proper action. Your code should be the obvious 
solution, but it fails, because it simply demonstrates a fundamental problem 
with VFS' URL handling:

{code}
public void testFileNameWithSpaces() throws VirtualFileSystemException, 
URISyntaxException, IOException
{
  final File file = new File("target", "a name.txt");
  final String fileURL = file.toURI().toURL().toExternalForm();
  assertEquals(file.getAbsoluteFile(), new File(file.toURI().getPath()));
  assertEquals(file.getAbsoluteFile(), new File(new 
URL(fileURL).toURI().getPath()));

  final FileSystemManager manager = VFS.getManager();
  final FileObject fo = manager.resolveFile(fileURL);
  assertEquals(file.getAbsoluteFile(), new File(new 
URL(fo.getURL().toExternalForm()).toURI().getPath()));
}

public void testFileNameWithCharacters() throws VirtualFileSystemException, 
URISyntaxException, IOException
{
  final File file = new File("target", "+# %&.txt");
  final String fileURL = file.toURI().toURL().toExternalForm();
  assertEquals(file.getAbsoluteFile(), new File(file.toURI().getPath()));
  assertEquals(file.getAbsoluteFile(), new File(new 
URL(fileURL).toURI().getPath()));

  try {
    new FileOutputStream(file).close();
    assertTrue(file.exists());

    final FileSystemManager manager = VFS.getManager();
    final FileObject fo = manager.resolveFile(fileURL);
    assertTrue(fo.exists());
    assertEquals(file.getAbsoluteFile(), new File(new 
URL(fo.getURL().toExternalForm()).toURI().getPath()));
  } finally {
    file.delete();
  }
}
{code}

Formally URLs are defined as subset of an URI in RFC 2396. However, 
java.net.URL has a long and sad story and the class does not ensure that the 
URL instance complies to this RFC. Even worse, the direct conversion between 
File and URL was never implemented properly and it will never be corrected, 
because too much code relies on the bad behavior (i.e. tries to fix the result 
afterwards). Therefore the JDK documents to do a proper conversion like in my 
unit test above using temporary URIs (see Javadoc for URL and URI).

However, VFS fails here badly. The first test above fails in the last line with 
a URISyntaxException, because the URL returned from FileObject is no longer 
compliant - although a compliant URL was provided to VFS. The last assert in 
the second test fails, because the URL is truncated; VFS does no proper URL 
encoding/decoding.

                
> Need an easy way to convert from a FileObject to a File
> -------------------------------------------------------
>
>                 Key: VFS-443
>                 URL: https://issues.apache.org/jira/browse/VFS-443
>             Project: Commons VFS
>          Issue Type: Bug
>    Affects Versions: 2.0
>            Reporter: Nicholas Allen
>            Assignee: Gary Gregory
>             Fix For: 2.1
>
>
> I've seen the reasons why Apache does not want to provide an easy way to 
> convert from a FileObject to a java.io.File and those reasons make sense - 
> however, I think that some things are being overlooked and there are still 
> valid reasons for needing to convert from a FileObject to a File.
> Firstly, I would like to always use Apache VFS for everything I do - even if 
> I know it's only on the local file system. The reasons for this are:
> 1. it makes the code more flexible (it might start of being local file system 
> and then as specs change it could become a requirement to work over http or 
> inside zip files for example). 
> 2. The API is nicer to use than the java.io.File and it's easier to write 
> cross platform code using it (file separator is always "/" etc).
> So if I work with Apache VFS for local file system use I would like to be 
> able to get back to a java.io.File in case I need to interface with same 
> other library. I would like a method that converted to a File or null if not 
> possible. This would allow me to take an alternate action (eg copy file to 
> local temp file if it's not already a local file). There's no need to copy 
> the file if it is already local.
> The simplest fix for this is to just make the getLocalFile() method in 
> LocalFile public. Once the user knows it's a LocalFile object it makes sense 
> to call this method to obtain the java.io.File. So I could write a method 
> like this:
> /**
>     * If the supplied {@link FileObject} represents a local file then this 
> returns that, otherwise
>     * returns null.
>     */
>    public File getLocalFile(final FileObject fileObject)
>    {
>       if (fileObject instanceof LocalFile)
>       {
>          final LocalFile localFile = (LocalFile)fileObject;
>          return localFile.getLocalFile();
>       }
>       return null;
>    }

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to