我是Commons VFS的新手,我试图了解如何打开一个嵌套的存档。我在源代码中找到了一个处理这个问题的例子。此测试通过。
@Test
void testTGZ() throws Exception {
FileSystemManager fsManager = VFS.getManager();
String uri = "tgz:file:///c:/data/nested.tgz!/test.tgz";
FileObject archive = fsManager.resolveFile(uri);
FileObject nestedFs = fsManager.createFileSystem(archive);
// List the children of the archive file
FileObject[] children = nestedFs.getChildren();
for (FileObject child : children) {
System.out.println(child.getURI());
}
}
而这个用
就失败了org.apache.commons.vfs2.FileSystemException: Could not find a file provider that can handle file "tgz:file:///C:/data/nested.tar.gz!/test.tar.gz".
@Test
void testTarGZ() throws Exception {
FileSystemManager fsManager = VFS.getManager();
String uri = "tgz:file:///c:/data/nested.tar.gz!/test.tar.gz";
FileObject archive = fsManager.resolveFile(uri);
FileObject nestedFs = fsManager.createFileSystem(archive);
// List the children of the archive file
FileObject[] children = nestedFs.getChildren();
for (FileObject child : children) {
System.out.println(child.getURI());
}
}
除了名字,文件是相同的,所以为什么一个工作,而不是另一个?我做错了什么?
我遇到了同样的问题,经过调试,我能够找到问题的根源。
如果你看一下DefaultFileSystemManager
类中的createFileSystem(FileObject file)
,你会发现它使用了FileTypeMap
类中的getScheme(FileObject file)
方法来检测方案:
/**
* Find the scheme for the provider of a layered file system.
* <p>
* This will check the FileContentInfo or file extension.
* </p>
*
* @return Scheme supporting the file type or null (if unknown).
*/
public String getScheme(final FileObject file) throws FileSystemException {
// Check the file's mime type for a match
final FileContent content = file.getContent();
final String mimeType = content.getContentInfo().getContentType();
if (mimeType != null) {
return mimeTypeMap.get(mimeType);
}
// no specific mime-type - if it is a file also check the extension
if (!file.isFile()) {
return null; // VFS-490 folders don't use extensions for mime-type
}
final String extension = file.getName().getExtension();
return extensionMap.get(extension);
}
当扩展名为tgz
时,mimeType
被求值为null
,并且该方法尝试使用扩展名本身获取方案。在本例中,tgz
从extensionMap
返回,DefaultFileSystemManager
使用该值选择FileProvider
(在本例中为TarFileProvider
)。
当扩展名为tar.gz
时,mimeType
被解析为application/octet-stream
, mimeTypeMap
中没有任何映射,方法返回null
。在此例中,DefaultFileSystemManager
创建文件系统失败,因为没有找到FileProvider
。
解决方案:
可以在创建文件系统时指定FileProvider
:
FileSystemManager manager = VFS.getManager();
// tgz file
String tgz = "file:/C:/data/nested.tgz";
FileObject tgzFileObject = manager.resolveFile(tgz);
FileObject tgzFileSystem = manager.createFileSystem("tgz", tgzFileObject);
// tar.gz file
String targz = "file:/C:/data/nested.tar.gz";
FileObject targzFileObject = manager.resolveFile(targz);
FileObject targzFileSystem = manager.createFileSystem("tgz", targzFileObject);