如何在Windows 7上使用NIO库更改Java中的文件权限
问题描述:
我正在尝试编写以特定文件的Path对象开头的代码,并使该文件的所有者不再具有以下权限移动它,删除它或修改它们,但它们仍然可以读取它。还需要确保可以撤消此操作,并且始终保持管理员不受限制的访问权限。如何在Windows 7上使用NIO库更改Java中的文件权限
我的一个主要问题是我无法弄清楚如何获取系统中的用户配置文件名称和组名称。
一个深入的解释将是太棒了。
答
File类可以设置读取,写入和执行的文件。要得到它,用户需要使用NIO。
Files类和NIO使用PosixFilePermissions,它根据文件和三个组设置权限:用户,所有者和组。在Windows上,管理员将与系统一起位于一个组中。
要移动它,我们需要我们自己的SecurityManager。移动文件时,NIO使用写入权限。所以我们的SecurityManager必须修改写权限。作为示例,请参阅我的代码。
p.s.虽然FileSystemsProvider是WindowsFileSystemProvider,但FileSystemProviders.getProvider(或类似的方法)会返回该文件。对于每个下载的操作系统,rt.jar可能不同,但如果您在Windows上,则可以认为这是正确的。
PathRestrictor.java
package Testers;
import java.io.IOException;
import java.net.URI;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.AccessMode;
import java.nio.file.CopyOption;
import java.nio.file.DirectoryStream;
import java.nio.file.DirectoryStream.Filter;
import java.nio.file.FileStore;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.FileAttributeView;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.spi.FileSystemProvider;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import sun.nio.fs.WindowsFileSystemProvider;
public class PathRestrictor extends FileSystemProvider{
boolean canRead;
boolean canWrite;
boolean canMove; //This is the tricky one
boolean canOpen;
private Path path;
WindowsFileSystemProvider provider = new WindowsFileSystemProvider();
public PathRestrictor(Path p){
path = p;
canRead = true;
canWrite = true;
canOpen = true;
}
public void setExecuteable(boolean executable){
canOpen = executable;
try {
Files.setPosixFilePermissions(path, getPerms());
} catch (IOException e) {
e.printStackTrace();
}
}
public void setReadable(boolean readable){
canRead = readable;
try {
Files.setPosixFilePermissions(path, getPerms());
} catch (IOException e) {
e.printStackTrace();
}
}
public void setWriteable(boolean writeable){
canWrite = writeable;
try {
Files.setPosixFilePermissions(path, getPerms());
} catch (IOException e) {
e.printStackTrace();
}
}
public void setMoveable(boolean moveable){
canMove = moveable;
MovementSecurityManager manager = new MovementSecurityManager();
if(!moveable)manager.unMoveablePaths.add(path.toString());
else manager.unMoveablePaths.remove(path.toString());
System.setSecurityManager(manager);
}
private Set<PosixFilePermission> getPerms() {
Set<PosixFilePermission> perms = new HashSet<PosixFilePermission>();
perms.add(PosixFilePermission.GROUP_EXECUTE);
perms.add(PosixFilePermission.GROUP_READ);
perms.add(PosixFilePermission.GROUP_WRITE);
if(canRead){
perms.add(PosixFilePermission.OTHERS_READ);
perms.add(PosixFilePermission.OWNER_READ);
}
if(canWrite){
perms.add(PosixFilePermission.OTHERS_WRITE);
perms.add(PosixFilePermission.OWNER_WRITE);
}
if(canOpen){
perms.add(PosixFilePermission.OTHERS_EXECUTE);
perms.add(PosixFilePermission.OWNER_EXECUTE);
}
return perms;
}
@Override
public void checkAccess(Path path, AccessMode... modes) throws IOException {
provider.checkAccess(path, modes);
}
@Override
public void copy(Path source, Path target, CopyOption... options)
throws IOException {
// TODO Auto-generated method stub
provider.copy(source, target, options);
}
@Override
public void createDirectory(Path dir, FileAttribute<?>... attrs)
throws IOException {
provider.createDirectory(dir, attrs);
}
@Override
public void delete(Path path) throws IOException {
provider.delete(path);
}
@Override
public <V extends FileAttributeView> V getFileAttributeView(Path path,
java.lang.Class<V> type, LinkOption... options) {
return provider.getFileAttributeView(path, type, options);
}
@Override
public FileStore getFileStore(Path path) throws IOException {
return provider.getFileStore(path);
}
@Override
public FileSystem getFileSystem(URI uri) {
return provider.getFileSystem(uri);
}
@Override
public Path getPath(URI uri) {
return provider.getPath(uri);
}
@Override
public String getScheme() {
return provider.getScheme();
}
@Override
public boolean isHidden(Path path) throws IOException {
return provider.isHidden(path);
}
@Override
public boolean isSameFile(Path path, Path path2) throws IOException {
return path.toString().equals(path2.toString());
}
@Override
public void move(Path source, Path target, CopyOption... options)
throws IOException {
MovementSecurityManager manager = new MovementSecurityManager();
manager.isMoving = true;
System.setSecurityManager(manager);
provider.move(source, target, options);
}
@Override
public SeekableByteChannel newByteChannel(Path path,
Set<? extends OpenOption> options, FileAttribute<?>... attrs)
throws IOException {
return provider.newByteChannel(path, options, attrs);
}
@Override
public DirectoryStream<Path> newDirectoryStream(Path dir,
Filter<? super Path> filter) throws IOException {
return provider.newDirectoryStream(dir, filter);
}
@Override
public FileSystem newFileSystem(URI uri, Map<String, ?> env)
throws IOException {
return provider.newFileSystem(uri, env);
}
@Override
public <A extends BasicFileAttributes> A readAttributes(Path path,
java.lang.Class<A> type, LinkOption... options) throws IOException {
return provider.readAttributes(path, type, options);
}
@Override
public Map<String, Object> readAttributes(Path path, String attributes,
LinkOption... options) throws IOException {
return provider.readAttributes(path, attributes, options);
}
@Override
public void setAttribute(Path path, String attribute, Object value,
LinkOption... options) throws IOException {
provider.setAttribute(path, attribute, value, options);
}
}
MovementSecurityManager.java
package Testers;
import java.util.HashSet;
import java.util.Set;
public class MovementSecurityManager extends SecurityManager {
public Set<String> unMoveablePaths = new HashSet<String>();
public boolean isMoving = true;
public void checkWrite(String path){
if(unMoveablePaths.contains(path) && isMoving) throw new SecurityException("Cannot move file!");
else super.checkWrite(path);
}
}
他们能复制吗? – JD9999
我真的想出了如何得到我想要的结果或多或少。唯一我仍然不确定的是,如果实际上可以删除用户移动文件的权限,并且如果可能,那么该如何执行。 – JereTheJuggler
它很复杂,让我告诉你如何在答案。至少我认为这是有效的,我是唯一的用户和管理员,所以我无法测试它 – JD9999