我正在创建一个命令行应用程序,根据给定的参数,该应用程序需要将一些文件(多个)输出到 ZIP文件或普通文件夹
我的方法是用FileSystem
封装目标(普通文件夹/ ZIP文件)。
我的问题是,除了当前工作目录表示绝对路径之外,我无法成功地为目录创建FileSystem
对象我的硬盘上的strong>:
public class FileSystemWriteTest {
public static void main(String[] args) throws IOException {
Path absolutePath = Paths.get("target", "testpath").toAbsolutePath();
System.out.println(String.format("user.dir before change:\n %s", System.getProperty("user.dir")));
System.setProperty("user.dir", absolutePath.toString());
System.out.println(String.format("changed user.dir:\n %s", System.getProperty("user.dir")));
FileSystem defaultSystem = FileSystems.getDefault();
Path testFilePath = defaultSystem.getPath("test.file");
System.out.println(String.format("expected to be in changed user.dir:\n %s", testFilePath.toAbsolutePath()));
URI uri = absolutePath.toUri();
System.out.println(String.format("URI: %s", uri));
FileSystem localFileSystem =
FileSystems.newFileSystem(uri, Collections.emptyMap());
Path file = localFileSystem.getPath("test.txt");
System.out.println(file.toAbsolutePath());
}
}
输出为:
user.dir before change:
D:\data\scm-workspace\anderes\Test
changed user.dir:
D:\data\scm-workspace\anderes\Test\target\testpath
expected to be in changed user.dir:
D:\data\scm-workspace\anderes\Test\test.file
URI: file:///D:/data/scm-workspace/anderes/Test/target/testpath/
Exception in thread "main" java.lang.IllegalArgumentException: Path component should be '/'
at sun.nio.fs.WindowsFileSystemProvider.checkUri(Unknown Source)
at sun.nio.fs.WindowsFileSystemProvider.newFileSystem(Unknown Source)
at java.nio.file.FileSystems.newFileSystem(Unknown Source)
at java.nio.file.FileSystems.newFileSystem(Unknown Source)
at com.oc.test.filesystem.FileSystemWriteTest.main(FileSystemWriteTest.java:27)
如果我更改为FileSystems.newFileSystem(Path, Classloader)
,则异常更改为:
Exception in thread "main" java.nio.file.ProviderNotFoundException: Provider not found
at java.nio.file.FileSystems.newFileSystem(Unknown Source)
at com.oc.test.filesystem.FileSystemWriteTest.main(FileSystemWriteTest.java:27)
看起来像这样仅适用于常规文件,不适用于目录。
那么如何为 pwd 之外的目录创建FileSystem
对象?
答案 0 :(得分:1)
没有用于创建具有FileSystem
之类的chroot
语义的内置功能。默认文件系统仅支持file:///
作为URI,并且不允许多个实例化。
在这方面,FileSystems.getDefault().getPath("test.file")
会创建相对路径,就像Paths.get("test.file")
一样。为默认文件系统和其他文件系统创建的相对路径之间的区别在于,在未指定其他基本路径的情况下(例如,在调用toAbsolutePath()
或只是尝试打开它们时),解析行为是不同的。但是,针对当前工作目录进行解析不会使它们成为根路径。
实现文件系统不可知操作的最佳解决方案是让代码接收基础Path
对象,以解决相对路径。
例如一个简单的树复制例程可能看起来像:
static void copyTree(Path sourceBase, Path targetBase) throws IOException {
try {
Files.walk(sourceBase).forEach(path -> {
if(Files.isRegularFile(path)) try {
Path target = targetBase.resolve(sourceBase.relativize(path).toString());
if(!Files.isDirectory(target.getParent()))
Files.createDirectories(target.getParent());
Files.copy(path, target, StandardCopyOption.COPY_ATTRIBUTES);
} catch(IOException ex) {
throw new UncheckedIOException(ex);
}
});
} catch(UncheckedIOException ex) {
throw ex.getCause();
}
}
对于此方法,无论是从硬盘驱动器目录复制到另一个硬盘驱动器目录或zip文件系统,还是从zip文件系统复制到硬盘驱动器,还是从zip文件复制到另一个zip文件都没有关系,等
最有趣的部分是调用sourceBase.relativize(path)
,以获取从源基本路径到实际文件的子路径的相对路径。由于相对的Path
实例仍然绑定到特定的文件系统,因此代码在将toString()
传递给targetBase.resolve(…)
之前会调用path.resolve(string)
,以确保它可以在不同的文件系统上工作。请注意,path.resolve(path.getFileSystem().getPath(string))
等效于Path
。如果该方法首先检查两个String
实例是否属于同一个文件系统,则在这种情况下跳过FusionCharts.ready(function() {
var revenueChart1 = new FusionCharts({
type: 'doughnut2d',
renderAt: 'chart-container1',
width: '100%',
height: '350',
dataFormat: 'json',
dataSource: {
"chart": {
"caption": "Caption",
"subCaption": "Sub-caption",
"showValues": "0",
"showLabels": "0",
"showLegend": "1",
"legendPosition": "RIGHT",
"numberPrefix": "$",
"startingAngle": "310",
"showTooltip": "0",
"decimals": "0"
},
"data": [{
"label": "Work place services",
"value": "28504"
}]
}
}).render();
var revenueChart2 = new FusionCharts({
type: 'doughnut2d',
renderAt: 'chart-container2',
width: '100%',
height: '350',
dataFormat: 'json',
dataSource: {
"chart": {
"caption": "Caption",
"subCaption": "Sub-caption",
"showValues": "0",
"showLabels": "0",
"showLegend": "1",
"legendPosition": "RIGHT",
"numberPrefix": "$",
"startingAngle": "310",
"showTooltip": "0",
"decimals": "0"
},
"data": [{
"label": "Work place services",
"value": "28504"
}]
}
}).render();
var revenueChart3 = new FusionCharts({
type: 'doughnut2d',
renderAt: 'chart-container3',
width: '100%',
height: '350',
dataFormat: 'json',
dataSource: {
"chart": {
"caption": "Caption",
"subCaption": "Sub-caption",
"showValues": "0",
"showLabels": "0",
"showLegend": "1",
"legendPosition": "RIGHT",
"numberPrefix": "$",
"startingAngle": "310",
"showTooltip": "0",
"decimals": "0"
},
"data": [{
"label": "Work place services",
"value": "28504"
}]
}
}).render();
});
绕行是合理的。