1

我们的应用程序使用Commons VFS来读取各种类型的文件。我们使用 VFS 通过其文件扩展名映射提供的自动文件类型检测。

问题:VFS 将 gz 文件(即名称以 结尾的文件.gz)错误分类为常规文件,而不是 GZIP 文件。这可以防止我们使用 VFS 来读取 gz 文件的(解压缩)内容,而无需一些特殊情况的手动破解。

我已将问题追溯到org.apache.commons.vfs2.impl.FileContentInfoFilenameFactory.create(),它调用

FileNameMap fileNameMap = URLConnection.getFileNameMap();
contentType = fileNameMap.getContentTypeFor(name);

content-types.properties这会从当前 Java 安装加载文件。此文件(至少在 Windows 上)包含此映射:

application/octet-stream: \
    description=Generic Binary Stream;\
    file_extensions=.saveme,.dump,.hqx,.arc,.obj,.lib,.bin,.exe,.zip,.gz    

根据源代码,org.apache.commons.vfs2.impl.FileTypeMap允许此映射优先于配置 VFS 的文件扩展名映射。

谁能想到一种方法(a)扩展一个或两个 VFS 类来解决这个问题,或者(b)配置 VFS 和/或 Java 本身以便 VFS 正确分类 gz 文件?

4

1 回答 1

0

创建一个如下所示的类,以覆盖该getContentTypeFor方法FileNameMap并排除麻烦的application/octet-stream条目:

public static class MyFileNameMap implements FileNameMap
{
    private FileNameMap delegate = URLConnection.getFileNameMap();

    @Override
    public String getContentTypeFor( String fileName )
    {
        String contentType = delegate.getContentTypeFor( fileName );
        if( "application/octet-stream".equals( contentType ) )
        {
            // Sun's java classifies zip and gzip as application/octet-stream,
            // which VFS then uses, instead of looking at its extension
            // map for a more specific mime type
            return null;
        }
        return contentType;
    }
}

通过以下方式安装这个新类:

URLConnection.setFileNameMap( new MyFileNameMap() );

现在,当您调用 时FileSystemManager.resolveFile(),VFS 将gz通过回退到其扩展映射来为文件选择正确的文件类型。

注意:这是对当前 JVM 的全局更改,因此如果您正在使用任何其他需要此 mime 类型条目的代码,例如.exe文件,请小心。

于 2013-05-07T19:40:27.457 回答