CopyOnWriteFSProvider.java
net.minecraft.util.filefix.virtualfilesystem.CopyOnWriteFSProvider
信息
- 全限定名:net.minecraft.util.filefix.virtualfilesystem.CopyOnWriteFSProvider
- 类型:public class
- 包:net.minecraft.util.filefix.virtualfilesystem
- 源码路径:src/main/java/net/minecraft/util/filefix/virtualfilesystem/CopyOnWriteFSProvider.java
- 起始行号:L39
- 继承:FileSystemProvider
- 职责:
TODO
字段/常量
-
SCHEME- 类型:
String - 修饰符:
public static final - 源码定位:
L40 - 说明:
TODO
- 类型:
-
DUMMY_DIRECTORY_VIEW- 类型:
BasicFileAttributeView - 修饰符:
private static final public public public - 源码定位:
L41 - 说明:
TODO
- 类型:
-
fs- 类型:
CopyOnWriteFileSystem - 修饰符:
private final - 源码定位:
L56 - 说明:
TODO
- 类型:
内部类/嵌套类型
net.minecraft.util.filefix.virtualfilesystem.CopyOnWriteFSProvider.ChannelFactory- 类型:
interface - 修饰符:
private - 源码定位:
L337 - 说明:
TODO
- 类型:
构造器
public CopyOnWriteFSProvider(CopyOnWriteFileSystem fileSystem) @ L58
- 构造器名:CopyOnWriteFSProvider
- 源码定位:L58
- 修饰符:public
参数:
- fileSystem: CopyOnWriteFileSystem
说明:
TODO
方法
下面的方法块按源码顺序生成。
public String getScheme() @ L62
- 方法名:getScheme
- 源码定位:L62
- 返回类型:String
- 修饰符:public
参数:
- 无
说明:
TODO
public FileSystem newFileSystem(URI uri, Map<String,?> env) @ L67
- 方法名:newFileSystem
- 源码定位:L67
- 返回类型:FileSystem
- 修饰符:public
参数:
- uri: URI
- env: Map<String,?>
说明:
TODO
public FileSystem getFileSystem(URI uri) @ L72
- 方法名:getFileSystem
- 源码定位:L72
- 返回类型:FileSystem
- 修饰符:public
参数:
- uri: URI
说明:
TODO
public Path getPath(URI uri) @ L77
- 方法名:getPath
- 源码定位:L77
- 返回类型:Path
- 修饰符:public
参数:
- uri: URI
说明:
TODO
public SeekableByteChannel newByteChannel(Path path, Set<?extends OpenOption> options, FileAttribute<?>... attrs) @ L82
- 方法名:newByteChannel
- 源码定位:L82
- 返回类型:SeekableByteChannel
- 修饰符:public
参数:
- path: Path
- options: Set<?extends OpenOption>
- attrs: FileAttribute<?>…
说明:
TODO
public FileChannel newFileChannel(Path path, Set<?extends OpenOption> options, FileAttribute<?>... attrs) @ L87
- 方法名:newFileChannel
- 源码定位:L87
- 返回类型:FileChannel
- 修饰符:public
参数:
- path: Path
- options: Set<?extends OpenOption>
- attrs: FileAttribute<?>…
说明:
TODO
private synchronized <C> C newChannel(Path path, Set<?extends OpenOption> options, FileAttribute<?>[] attrs, CopyOnWriteFSProvider.ChannelFactory<C> channelFactory) @ L92
- 方法名:newChannel
- 源码定位:L92
- 返回类型:
C - 修饰符:private synchronized
参数:
- path: Path
- options: Set<?extends OpenOption>
- attrs: FileAttribute<?>[]
- channelFactory: CopyOnWriteFSProvider.ChannelFactory
说明:
TODO
private static boolean wantsWrite(Set<?extends OpenOption> options) @ L125
- 方法名:wantsWrite
- 源码定位:L125
- 返回类型:boolean
- 修饰符:private static
参数:
- options: Set<?extends OpenOption>
说明:
TODO
public synchronized DirectoryStream<Path> newDirectoryStream(Path dir, Filter<?super Path> filter) @ L129
- 方法名:newDirectoryStream
- 源码定位:L129
- 返回类型:DirectoryStream
- 修饰符:public synchronized
参数:
- dir: Path
- filter: Filter<?super Path>
说明:
TODO
public synchronized void createDirectory(Path dir, FileAttribute<?>... attrs) @ L158
- 方法名:createDirectory
- 源码定位:L158
- 返回类型:void
- 修饰符:public synchronized
参数:
- dir: Path
- attrs: FileAttribute<?>…
说明:
TODO
public synchronized void delete(Path path) @ L175
- 方法名:delete
- 源码定位:L175
- 返回类型:void
- 修饰符:public synchronized
参数:
- path: Path
说明:
TODO
public void copy(Path source, Path target, CopyOption... options) @ L195
- 方法名:copy
- 源码定位:L195
- 返回类型:void
- 修饰符:public
参数:
- source: Path
- target: Path
- options: CopyOption…
说明:
TODO
public synchronized void move(Path source, Path target, CopyOption... options) @ L200
- 方法名:move
- 源码定位:L200
- 返回类型:void
- 修饰符:public synchronized
参数:
- source: Path
- target: Path
- options: CopyOption…
说明:
TODO
public boolean isSameFile(Path path, Path path2) @ L251
- 方法名:isSameFile
- 源码定位:L251
- 返回类型:boolean
- 修饰符:public
参数:
- path: Path
- path2: Path
说明:
TODO
public boolean isHidden(Path path) @ L256
- 方法名:isHidden
- 源码定位:L256
- 返回类型:boolean
- 修饰符:public
参数:
- path: Path
说明:
TODO
public FileStore getFileStore(Path path) @ L261
- 方法名:getFileStore
- 源码定位:L261
- 返回类型:FileStore
- 修饰符:public
参数:
- path: Path
说明:
TODO
public synchronized void checkAccess(Path path, AccessMode... modes) @ L266
- 方法名:checkAccess
- 源码定位:L266
- 返回类型:void
- 修饰符:public synchronized
参数:
- path: Path
- modes: AccessMode…
说明:
TODO
public synchronized <V extends FileAttributeView> V getFileAttributeView(Path path, Class<V> type, LinkOption... options) @ L279
- 方法名:getFileAttributeView
- 源码定位:L279
- 返回类型:
V - 修饰符:public synchronized
参数:
- path: Path
- type: Class
- options: LinkOption…
说明:
TODO
public synchronized <A extends BasicFileAttributes> A readAttributes(Path path, Class<A> type, LinkOption... options) @ L310
- 方法名:readAttributes
- 源码定位:L310
- 返回类型: A
- 修饰符:public synchronized
参数:
说明:
TODO
public Map<String,Object> readAttributes(Path path, String attributes, LinkOption... options) @ L322
- 方法名:readAttributes
- 源码定位:L322
- 返回类型:Map<String,Object>
- 修饰符:public
参数:
- path: Path
- attributes: String
- options: LinkOption…
说明:
TODO
public void setAttribute(Path path, String attribute, Object value, LinkOption... options) @ L327
- 方法名:setAttribute
- 源码定位:L327
- 返回类型:void
- 修饰符:public
参数:
- path: Path
- attribute: String
- value: Object
- options: LinkOption…
说明:
TODO
public synchronized CopyOnWriteFSPath getRealPath(CopyOnWriteFSPath path) @ L332
- 方法名:getRealPath
- 源码定位:L332
- 返回类型:CopyOnWriteFSPath
- 修饰符:public synchronized
参数:
- path: CopyOnWriteFSPath
说明:
TODO
代码
public class CopyOnWriteFSProvider extends FileSystemProvider {
public static final String SCHEME = "x-mc-copy-on-write";
private static final BasicFileAttributeView DUMMY_DIRECTORY_VIEW = new BasicFileAttributeView() {
@Override
public String name() {
return "basic";
}
@Override
public BasicFileAttributes readAttributes() {
return DummyFileAttributes.DIRECTORY;
}
@Override
public void setTimes(FileTime lastModifiedTime, FileTime lastAccessTime, FileTime createTime) throws IOException {
}
};
private final CopyOnWriteFileSystem fs;
public CopyOnWriteFSProvider(CopyOnWriteFileSystem fileSystem) {
this.fs = fileSystem;
}
@Override
public String getScheme() {
return "x-mc-copy-on-write";
}
@Override
public FileSystem newFileSystem(URI uri, Map<String, ?> env) throws IOException {
throw new UnsupportedOperationException();
}
@Override
public FileSystem getFileSystem(URI uri) {
throw new UnsupportedOperationException();
}
@Override
public Path getPath(URI uri) {
throw new UnsupportedOperationException();
}
@Override
public SeekableByteChannel newByteChannel(Path path, Set<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException {
return this.newChannel(path, options, attrs, Files::newByteChannel);
}
@Override
public FileChannel newFileChannel(Path path, Set<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException {
return this.newChannel(path, options, attrs, FileChannel::open);
}
private synchronized <C> C newChannel(
Path path, Set<? extends OpenOption> options, FileAttribute<?>[] attrs, CopyOnWriteFSProvider.ChannelFactory<C> channelFactory
) throws IOException {
CopyOnWriteFSPath cowPath = CopyOnWriteFSPath.asCow(path);
if (options.contains(StandardOpenOption.DELETE_ON_CLOSE)) {
throw new UnsupportedOperationException("DELETE_ON_CLOSE is not supported by CowFS");
} else {
return (C)(switch (this.fs.fileTree().byPathOrNull(cowPath)) {
case null -> {
if (!options.contains(StandardOpenOption.CREATE) && !options.contains(StandardOpenOption.CREATE_NEW)) {
throw new CowFSNoSuchFileException(cowPath.toString());
}
DirectoryNode directoryNode = this.fs.fileTree().directoryByPath(Objects.requireNonNull(cowPath.getParent()));
Path tempFile = this.fs.createTemporaryFilePath();
C result = channelFactory.newChannel(tempFile, options, attrs);
FileNode child = new FileNode(cowPath, tempFile, true);
directoryNode.addChild(child);
yield result;
}
case FileNode fileNode -> {
if (wantsWrite(options)) {
fileNode.ensureCopy();
}
yield channelFactory.newChannel(fileNode.storagePath(), options, attrs);
}
case DirectoryNode var14 -> throw new CowFSFileSystemException(cowPath + ": not a regular file");
default -> throw new MatchException(null, null);
});
}
}
private static boolean wantsWrite(Set<? extends OpenOption> options) {
return options.contains(StandardOpenOption.WRITE) || !options.contains(StandardOpenOption.READ) && options.contains(StandardOpenOption.APPEND);
}
@Override
public synchronized DirectoryStream<Path> newDirectoryStream(Path dir, Filter<? super Path> filter) throws IOException {
CopyOnWriteFSPath cowPath = CopyOnWriteFSPath.asCow(dir);
DirectoryNode directoryNode = this.fs.fileTree().directoryByPath(cowPath);
final List<Path> result = new ArrayList<>();
for (Node childNode : directoryNode.children()) {
Path path = childNode.path();
if (filter.accept(path)) {
result.add(path);
}
}
return new DirectoryStream<Path>() {
{
Objects.requireNonNull(CopyOnWriteFSProvider.this);
}
@Override
public void close() {
}
@Override
public Iterator<Path> iterator() {
return result.iterator();
}
};
}
@Override
public synchronized void createDirectory(Path dir, FileAttribute<?>... attrs) throws IOException {
CopyOnWriteFSPath cowPath = CopyOnWriteFSPath.asCow(dir);
CopyOnWriteFSPath parent = cowPath.getParent();
if (parent == null) {
throw new CowFSFileAlreadyExistsException(cowPath.toString());
} else {
DirectoryNode parentFolder = this.fs.fileTree().directoryByPath(parent);
String folderName = Objects.requireNonNull(cowPath.getFileName()).toString();
if (parentFolder.getChild(folderName) != null) {
throw new CowFSFileAlreadyExistsException(cowPath.toString());
} else {
parentFolder.addChild(new DirectoryNode(cowPath));
}
}
}
@Override
public synchronized void delete(Path path) throws IOException {
CopyOnWriteFSPath cowPath = CopyOnWriteFSPath.asCow(path);
Node node = this.fs.fileTree().byPath(cowPath);
if (node.parent == null) {
throw new CowFSFileSystemException("Can't remove root");
} else {
String name = Objects.requireNonNull(node.name());
if (node instanceof DirectoryNode directoryNode) {
if (!directoryNode.children().isEmpty()) {
throw new CowFSDirectoryNotEmptyException(cowPath.toString());
}
} else if (node instanceof FileNode fileNode) {
fileNode.deleteCopy();
}
node.parent.removeChild(name);
}
}
@Override
public void copy(Path source, Path target, CopyOption... options) throws IOException {
throw new UnsupportedOperationException();
}
@Override
public synchronized void move(Path source, Path target, CopyOption... options) throws IOException {
CopyOnWriteFSPath sourceCow = CopyOnWriteFSPath.asCow(source);
CopyOnWriteFSPath targetCow = CopyOnWriteFSPath.asCow(target);
if (sourceCow.isRoot()) {
throw new CowFSFileSystemException(sourceCow + ": can't move root directory");
} else {
boolean replaceExisting = false;
for (CopyOption option : options) {
if (option.equals(StandardCopyOption.ATOMIC_MOVE)) {
throw new AtomicMoveNotSupportedException(sourceCow.toString(), targetCow.toString(), "CowFs does not support atomic move");
}
if (option.equals(StandardCopyOption.REPLACE_EXISTING)) {
replaceExisting = true;
}
}
Node sourceNode = this.fs.fileTree().byPathOrNull(sourceCow);
if (sourceNode == null) {
throw new CowFSNoSuchFileException(sourceCow.toString());
} else {
CopyOnWriteFSPath parent = targetCow.toAbsolutePath().getParent();
if (parent == null) {
throw new CowFSFileAlreadyExistsException(targetCow.toString());
} else if (this.fs.fileTree().byPathOrNull(parent) instanceof DirectoryNode folderTarget) {
String newName = Objects.requireNonNull(targetCow.getFileName()).toString();
Node oldChild = folderTarget.getChild(newName);
if (oldChild != null) {
if (oldChild.equals(sourceNode)) {
return;
}
if (!replaceExisting) {
throw new CowFSFileAlreadyExistsException(targetCow.toString());
}
folderTarget.removeChild(newName);
}
Objects.requireNonNull(sourceNode.parent).removeChild(Objects.requireNonNull(sourceNode.name()));
sourceNode.setPath(targetCow);
folderTarget.addChild(sourceNode);
} else {
throw new CowFSNoSuchFileException(targetCow.toString());
}
}
}
}
@Override
public boolean isSameFile(Path path, Path path2) {
throw new UnsupportedOperationException();
}
@Override
public boolean isHidden(Path path) {
throw new UnsupportedOperationException();
}
@Override
public FileStore getFileStore(Path path) {
throw new UnsupportedOperationException();
}
@Override
public synchronized void checkAccess(Path path, AccessMode... modes) throws IOException {
CopyOnWriteFSPath cowPath = CopyOnWriteFSPath.asCow(path);
Node node = this.fs.fileTree().byPath(cowPath);
Path checkPath = switch (node) {
case DirectoryNode var9 -> this.fs.tmpDirectory();
case FileNode file -> file.storagePath();
default -> throw new MatchException(null, null);
};
checkPath.getFileSystem().provider().checkAccess(checkPath, modes);
}
@Override
public synchronized <V extends FileAttributeView> @Nullable V getFileAttributeView(Path path, Class<V> type, LinkOption... options) {
final CopyOnWriteFSPath cowPath = CopyOnWriteFSPath.asCow(path);
return (V)(switch (this.fs.fileTree().byPathOrNull(cowPath)) {
case null -> type == BasicFileAttributeView.class ? new BasicFileAttributeView() {
{
Objects.requireNonNull(CopyOnWriteFSProvider.this);
}
@Override
public String name() {
return "basic";
}
@Override
public BasicFileAttributes readAttributes() throws IOException {
throw new CowFSNoSuchFileException(cowPath.toString());
}
@Override
public void setTimes(FileTime lastModifiedTime, FileTime lastAccessTime, FileTime createTime) throws IOException {
throw new CowFSNoSuchFileException(cowPath.toString());
}
} : null;
case DirectoryNode var9 -> type == BasicFileAttributeView.class ? DUMMY_DIRECTORY_VIEW : null;
case FileNode file -> Files.getFileAttributeView(file.storagePath(), type, options);
default -> throw new MatchException(null, null);
});
}
@Override
public synchronized <A extends BasicFileAttributes> A readAttributes(Path path, Class<A> type, LinkOption... options) throws IOException {
CopyOnWriteFSPath cowPath = CopyOnWriteFSPath.asCow(path);
Node node = this.fs.fileTree().byPath(cowPath);
return (A)(switch (node) {
case DirectoryNode var9 -> DummyFileAttributes.DIRECTORY;
case FileNode file -> Files.readAttributes(file.storagePath(), type, options);
default -> throw new MatchException(null, null);
});
}
@Override
public Map<String, Object> readAttributes(Path path, String attributes, LinkOption... options) {
throw new UnsupportedOperationException();
}
@Override
public void setAttribute(Path path, String attribute, Object value, LinkOption... options) {
throw new UnsupportedOperationException();
}
public synchronized CopyOnWriteFSPath getRealPath(CopyOnWriteFSPath path) throws CowFSNoSuchFileException {
return this.fs.fileTree().byPath(path.toAbsolutePath()).path;
}
@FunctionalInterface
private interface ChannelFactory<C> {
C newChannel(Path path, Set<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException;
}
}引用的其他类
-
- 引用位置:
参数/方法调用/返回值 - 关联成员:
CopyOnWriteFSPath.asCow()
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
DirectoryNode()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
FileNode()
- 引用位置:
-
CowFSDirectoryNotEmptyException
- 引用位置:
构造调用 - 关联成员:
CowFSDirectoryNotEmptyException()
- 引用位置:
-
CowFSFileAlreadyExistsException
- 引用位置:
构造调用 - 关联成员:
CowFSFileAlreadyExistsException()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
CowFSFileSystemException()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
CowFSNoSuchFileException()
- 引用位置: