如何配置Commons VFS以自动检测gz文件

时间:2013-05-07 19:36:58

标签: java apache-commons-vfs

我们的应用程序使用Commons VFS来读取各种类型的文件。我们使用VFS提供的自动文件类型检测,通过其file extension mapping

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

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

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

这将从当前Java安装加载文件content-types.properties。此文件(至少在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文件的方法?

1 个答案:

答案 0 :(得分:0)

创建如下所示的类,以覆盖getContentTypeFor的{​​{1}}方法并排除麻烦的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() ); 时,VFS会选择FileSystemManager.resolveFile()文件的正确文件类型,方法是退回到其扩展程序图。

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