Java Zip文件系统提供程序:远程驱动器[Windows]上的只读
我有一个问题:如果zip文件位于远程驱动器上(映射与否似乎无关),那么虚拟文件系统是只读的,尽管文件本身不是。我编写了一个简单的示例代码:Java Zip文件系统提供程序:远程驱动器[Windows]上的只读,java,filesystems,zip,java.nio.file,Java,Filesystems,Zip,Java.nio.file,我有一个问题:如果zip文件位于远程驱动器上(映射与否似乎无关),那么虚拟文件系统是只读的,尽管文件本身不是。我编写了一个简单的示例代码: public static void main(String[] args) throws IOException { File workingDir = new File(args[0]); File source = new File(workingDir, "in.zip"); File target = new File(wo
public static void main(String[] args) throws IOException {
File workingDir = new File(args[0]);
File source = new File(workingDir, "in.zip");
File target = new File(workingDir, "out.zip");
Files.copy(source.toPath(), target.toPath(), StandardCopyOption.REPLACE_EXISTING);
try (FileSystem zipfs = FileSystems.newFileSystem(target.toPath(), null)) {
Path pathInZipfile = zipfs.getPath("test.xml");
System.out.println("zipfile writable: " + target.canWrite());
System.out.println("zipFS writable: " + !zipfs.isReadOnly());
Files.delete(pathInZipfile);
System.out.println("File successfully deleted");
} catch (IOException e) {
e.printStackTrace();
}
}
如果workingDir是本地目录,则一切正常。但是,如果它是(映射的)远程驱动器,我会得到:
zipfile writable: true
zipFS writable: false
Exception in thread "main" java.nio.file.ReadOnlyFileSystemException
at com.sun.nio.zipfs.ZipFileSystem.checkWritable(ZipFileSystem.java:155)
at com.sun.nio.zipfs.ZipFileSystem.deleteFile(ZipFileSystem.java:1335)
at com.sun.nio.zipfs.ZipPath.delete(ZipPath.java:655)
at com.sun.nio.zipfs.ZipFileSystemProvider.delete(ZipFileSystemProvider.java:206)
at java.nio.file.Files.delete(Unknown Source)
at zipfs.ZipFS.main(ZipFS.java:23)
我做错什么了吗?不可能吗?有解决方法吗?尝试将
ZipFileSystem
中的私有字段readOnly
设置为false
,并进行反射。尝试将ZipFileSystem
中的私有字段readOnly
设置为false
并进行反射。我遇到了同样的问题,然后查看了JDK代码
调查结果
在ZipFileSystem.java中,有三条相关的行:
zfpath.getFileSystem().provider().checkAccess(zfpath, AccessMode.READ);
if (!Files.isWritable(zfpath))
this.readOnly = true;
zfPath是一个路径对象。Windows文件系统提供程序中的某些内容会阻止对zip存档路径的写入访问。似乎没有多少事情要做
变通办法
我使用的解决方法是:
只要映射的驱动器在zip文件系统之外的上下文中是可写的,这个方法就可以工作。我遇到了同样的问题,我查看了JDK代码 调查结果 在ZipFileSystem.java中,有三条相关的行:
zfpath.getFileSystem().provider().checkAccess(zfpath, AccessMode.READ);
if (!Files.isWritable(zfpath))
this.readOnly = true;
zfPath是一个路径对象。Windows文件系统提供程序中的某些内容会阻止对zip存档路径的写入访问。似乎没有多少事情要做
变通办法
我使用的解决方法是:
只要映射的驱动器在zip文件系统之外的上下文中是可写的,这种方法就可以工作。我们遇到了完全相同的问题,并且已经找到了某种野蛮的解决方案。
FileSystems.newFileSystem(Path)
接受Path
接口,因此可以通过包装真实的Path
实例来满足它
以下是实现必需的FileSystemProvider.checkAccess()的解决方案
:
private静态文件系统createZip(路径zipPath)
抛出异常
{
var fileSystem=zipPath.getFileSystem();
var provider=fileSystem.provider();
返回FileSystems.newFileSystem(
新路径()
{
专用路径(路径路径)
{
返回this==path?zipPath:path;
}
@凌驾
公共文件系统getFileSystem()
{
返回新文件系统()
{
公共集supportedFileAttributeViews()
{
返回fileSystem.supportedFileAttributeViews();
}
@凌驾
公共文件系统提供程序()
{
返回新的FileSystemProvider()
{
@凌驾
公共空集合属性(
路径路径,
字符串属性,
对象值,
链接选项…选项)
抛出IOException
{
setAttribute(路径、属性、值、选项);
}
@凌驾
公共地图属性(
路径路径,
字符串属性,
链接选项…选项)
抛出IOException
{
返回提供者。
读取属性(路径、属性、选项);
}
@凌驾
公共A readAttributes(
路径路径,
类类型,
链接选项…选项)
抛出IOException
{
返回provider.readAttributes(路径、类型、选项);
}
@凌驾
公共文件系统newFileSystem(URI、映射环境)
抛出IOException
{
返回provider.newFileSystem(uri,env);
}
@凌驾
公共目录流newDirectoryStream(
路径目录,
过滤器…属性)
抛出IOException
{
返回provider.newByteChannel(路径、选项、属性);
}
@凌驾
公开无效动议(
路径源,
路径目标,
CopyOption…选项)
抛出IOException
{
移动(路径(源)、路径(目标)、选项);
}
@凌驾
公共布尔isSameFile(路径路径,路径路径2)
抛出IOException
{
返回provider.isSameFile(路径(path),路径(path2));
}
@凌驾
公共布尔值isHidden(路径)
抛出IOException
{
返回provider.ishiden(路径(path));
}
@凌驾
公共字符串getScheme()
{
返回provider.getScheme();
}
@凌驾
公共路径getPath(URI)
{
返回provider.getPath(uri);
}
@凌驾
公共文件系统getFileSystem(URI)
{
返回provi