我正在使用第三方库,它基本上创建了一个输出目录,其中包含不同类型的文件和子目录。我希望能够编写单元测试来确认输出是否正确。
我希望能够将lib与RAM磁盘一起使用,这样磁带库就不会以任何方式触及实际的磁盘板。我的想法是让测试运行和清理非常快(丢弃RAM磁盘?)。
我可以使用的两个最突出的选项是Commons VFS和JSR 203。前者对我没用,因为我希望使用java.io. * API而不是Commons VFS类透明地工作。后者没有削减它因为我必须使用JDK 6(它应该是JDK 7的一部分)而且我不知道它是否能与java.io. *无缝地工作(我不会打赌吧。
还有other解决方案,但我不能使用它们的原因与我不能使用Commons VFS相同。由于所涉及的库的复杂性,模拟是不可能的。
在我的linux机器上,我可以轻松地创建一个RAM驱动器并使用java.io. * API,就像我对磁盘上的文件一样。问题是,我希望它是跨平台的,更具体地说,是让磁盘设置成为测试程序的一部分,而不是外部的东西。
那么,有没有办法在Java中注册一个可以与标准java.io. * API一起使用的RAM驱动器?
答案 0 :(得分:6)
那么,有没有办法在Java中注册一个可以与标准java.io. * API一起使用的RAM驱动器?
不使用Java 6或更早版本的JVM。 Java 6及更早版本不提供用于注册文件系统或文件系统类型的任何SPI。因此,要实现一个应用程序将像普通FS一样使用的RAM FS,将需要修改许多java.io.*
类的行为。
我认为您可以做的最好的事情是使用主机操作系统实现的RAM FS。您应该能够从Java访问它,就像它是一个普通的文件系统一样。但是,I / O 将需要系统调用,因此它不会像RAM文件系统保存在JVM管理内存中那么快。
答案 1 :(得分:4)
理论上斯蒂芬是对的。 但我可以建议你一招。您可以实现自己的FileInputStream和FileOutputStream并将它们放入bootclasspath。您的实现将例如实现open(),read()和readBytes()(这是常规FileInputStream中的本机方法。)
这是针对您的问题的纯java解决方案。它的缺点是你必须在单独的JVM实例中运行测试。
答案 2 :(得分:1)
您要克服的基本问题是原始的java.io
API根本不灵活(它们都是指具体的类)。您可以将不同功能放在例如java.io.File
中的唯一方法是扩展基类。
在设计类之后扩展类可能是糟糕的设计(只需查看Properties
类) - 这就是为什么你可能找不到这样做的库。
没有什么可以阻止您自己扩展java.io.File
类,并将所有方法代理到例如Commons VFS API的FileObject
。
修改:但是,根据该方法,有些事情可能会失败 - 例如,使用带有父File
的{{1}}构造函数。
编辑2 :好吧,我会从这样的事情开始:
File
至于为什么public class VirtualFile extends java.io.File {
public static VirtualFile fromFile(File file) {
if (file instanceof VirtualFile) {
return (VirtualFile) file;
} else {
FileSystemManager fsm = new DefaultFileSystemManager();
return fsm.toFileObject(file);
}
}
private final org.apache.commons.vfs.FileObject mProxyFileObject;
public VirtualFile(FileObject proxy) {
super("/tmp/xxxx"); // That part needs some work to be cross-platform.
// However, such a construction will completely
// destroy the expectations that other classes
// have about what a File is.
mProxyFileObject = proxy;
}
public VirtualFile(VirtualFile parent, String child) {
this(parent.mProxyFileObject.resolveFile(child));
}
public VirtualFile(File parent, String child) {
this(fromFile(parent), child);
}
@Override
public boolean canExecute() {
throw new UnsupportedOperationException();
}
@Override
public boolean canRead() {
try {
return mProxyFileObject.isReadable();
} catch (FileSystemException fse) {
// FileSystemException is not a Runtime Exception :(
throw new RuntimeException(fse);
}
}
// Override ALL public methods to throw Exceptions;
// implement or mock only the methods that you need.
}
构造函数无法使用该设置:该构造函数不期望File(File, String)
的实现会破坏类的合同 - 我们在调用File
时会这样做。 (我们无法避免破坏类的合同,因为我们想要使用的虚拟文件没有明确的super("/tmp/xxxx")
等价物)
所以,你有 - 它需要一些重要的工作,并且很有可能图书馆不会按预期工作。