我们的应用程序使用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文件的方法?
答案 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
文件),请务必小心。