如何用HDFS命令或Java/Scala代码设置文件及父目录权限?
解决方案:HDFS权限修改的命令行与代码实现
当然可以实现你的需求!下面分命令行和Java/Scala代码两种方式详细说明:
一、Hadoop FS命令行实现
你已经掌握了修改文件权限的命令,针对目录权限的修改,因为/a已经是全局可读且你没有它的所有权,直接修改其子目录/a/b和/a/b/c即可:
- 修改目标文件权限(和你提到的一致):
hadoop fs -chmod 644 /a/b/c/f1.txt /a/b/c/f2.txt # 或者用通配符批量修改 hadoop fs -chmod 644 /a/b/c/*.txt
- 修改目录
/a/b和/a/b/c的权限为755:
hadoop fs -chmod 755 /a/b /a/b/c
为什么要给目录加
+x?目录的x权限控制用户是否能进入该目录,哪怕文件权限设置正确,如果父目录没有x权限,你依然无法访问里面的文件。755权限对应rwxr-xr-x,刚好满足你需要的全局可进入+可读的要求。
如果后续有递归修改子目录权限的需求,可以加-R参数,但你的场景里直接指定路径更高效。
二、Java代码实现
使用Hadoop的FileSystem API完成权限修改,需要依赖Hadoop客户端jar包:
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.permission.FsPermission; import java.io.IOException; public class HdfsPermissionChanger { public static void main(String[] args) { Configuration conf = new Configuration(); // 若在集群外运行,需指定core-site.xml和hdfs-site.xml路径 // conf.addResource(new Path("/path/to/core-site.xml")); // conf.addResource(new Path("/path/to/hdfs-site.xml")); try (FileSystem fs = FileSystem.get(conf)) { // 1. 修改文件权限为644 Path file1 = new Path("/a/b/c/f1.txt"); Path file2 = new Path("/a/b/c/f2.txt"); FsPermission filePerm = FsPermission.valueOf("644"); fs.setPermission(file1, filePerm); fs.setPermission(file2, filePerm); // 2. 修改目录权限为755 Path dirB = new Path("/a/b"); Path dirC = new Path("/a/b/c"); FsPermission dirPerm = FsPermission.valueOf("755"); fs.setPermission(dirB, dirPerm); fs.setPermission(dirC, dirPerm); System.out.println("权限修改完成!"); } catch (IOException e) { e.printStackTrace(); } } }
三、Scala代码实现
Scala可直接调用Hadoop Java API,写法更简洁:
import org.apache.hadoop.conf.Configuration import org.apache.hadoop.fs.{FileSystem, Path} import org.apache.hadoop.fs.permission.FsPermission object HdfsPermissionChanger extends App { val conf = new Configuration() // 集群外运行需添加配置文件路径 // conf.addResource(new Path("/path/to/core-site.xml")) // conf.addResource(new Path("/path/to/hdfs-site.xml")) val fs = FileSystem.get(conf) try { // 修改文件权限 val filePerm = FsPermission.valueOf("644") List("/a/b/c/f1.txt", "/a/b/c/f2.txt").foreach(path => { fs.setPermission(new Path(path), filePerm) }) // 修改目录权限 val dirPerm = FsPermission.valueOf("755") List("/a/b", "/a/b/c").foreach(path => { fs.setPermission(new Path(path), dirPerm) }) println("权限修改完成!") } catch { case e: Exception => e.printStackTrace() } finally { fs.close() } }
注意:无论用命令行还是代码,你需要拥有修改
/a/b和/a/b/c目录权限的权限(比如是这些目录的所有者,或者有超级用户权限),否则会触发权限不足的错误。
内容的提问来源于stack exchange,提问作者Marsellus Wallace




