如何在Windows 7上使用NIO库更改Java中的文件权限

问题描述:

我正在尝试编写以特定文件的Path对象开头的代码,并使该文件的所有者不再具有以下权限移动它,删除它或修改它们,但它们仍然可以读取它。还需要确保可以撤消此操作,并且始终保持管理员不受限制的访问权限。如何在Windows 7上使用NIO库更改Java中的文件权限

我的一个主要问题是我无法弄清楚如何获取系统中的用户配置文件名称和组名称。

一个深入的解释将是太棒了。

+0

他们能复制吗? – JD9999

+0

我真的想出了如何得到我想要的结果或多或少。唯一我仍然不确定的是,如果实际上可以删除用户移动文件的权限,并且如果可能,那么该如何执行。 – JereTheJuggler

+0

它很复杂,让我告诉你如何在答案。至少我认为这是有效的,我是唯一的用户和管理员,所以我无法测试它 – JD9999

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); 
    } 

} 
+0

这只会工作一次,并且只适用于由当前JVM启动的移动。 – EJP

+0

我得到的只是当前JVM发起的,但是你的意思是它只能工作一次? – JD9999

+0

从我所知道的事情来看,我无能为力纠正这个问题 – JD9999