Основная проблема, которую вы хотите преодолеть, заключается в том, что оригинальные java.io
API вообще не являются гибкими (все они относятся к конкретным классам). Единственный способ, которым вы можете добавить различные функции, например java.io.File
, - это расширение базового класса.
Расширение классов после их разработки может быть плохим проектом (просто посмотрите на класс Properties
) - вот почему вы, вероятно, не найдете библиотеку, которая делает это.
Ничто не мешает вам самостоятельно расширять класс java.io.File
и передавать все методы, например, для FileObject
API Commons VFS.
Редактировать : Однако есть вещи, которые, вероятно, потерпят неудачу при таком подходе - например, использование конструкторов File
, которые принимают родительский элемент File
.
Редактировать 2 : Ну, я бы начал с чего-то такого:
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")
. (И мы не можем не нарушать контракт класса, потому что виртуальные файлы, с которыми мы хотим работать, не имеют простого File
эквивалента)
Итак, вот вам - это потребует нетривиальной части работы, и есть большая вероятность того, что библиотека все равно не будет работать так, как ожидалось.