HDFS API 操作实例(二) 目录操作
1. 递归读取文件名
1.1 递归实现读取文件名(scala + listFiles)
/** * 实现:listFiles方法 * 迭代列出文件夹下的文件,只能列出文件 * 通过fs的listFiles方法可以自动实现递归(自带递归)列出文件类型 * 第一个参数是服务器路径,第二个参数是否递归 * @param srcPath */ def listFullFileNames(srcPath: String): List[String] = { val buffer = new ArrayBuffer[String] try { val iterator: RemoteIterator[LocatedFileStatus] = fs.listFiles(new Path(srcPath), true) while (iterator.hasNext) { val fileStatus = iterator.next() buffer.append(fileStatus.getPath.getName) } } finally { this.closeFS(fs) } buffer.toList }
1.2 递归实现读取文件名(scala + listStatus)
/** * 通过fs的listStatus方法可以自动实现递归(自带递归)列出文件类型 * @param srcPath 目录 * @param buffer 全局的 ArrayBuffer * @return */
val buffer = new ArrayBuffer[String]()
def listFullFileNames(srcPath: String, buffer: ArrayBuffer[String]): List[String] = { val fileStatuses: Array[FileStatus] = fs.listStatus(new Path(srcPath)) for (fileStatus <- fileStatuses) { //判断当前迭代对象是否是目录 if (fileStatus.isDirectory) { listFullFileNames(fileStatus.getPath.toString, buffer) } else { buffer.append(fileStatus.getPath.getName) } } buffer.toList }
注意:使用了全局buffer,以至于递归收集文件数目
1.3 列出某个目录读取文件名(scala)
/** 列出具体路径下的所有文件名称 **/ def listFilesNames(finalPath: String): List[String] = { val listStatus = try { fs.listStatus(new Path(finalPath)).map(_.getPath.getName).toList } catch { case e: Exception => Nil } listStatus }
2. 获取文件状态
2.1 HDFS文件的属性获取
def readFileContent(path: String) = { val conf: Configuration = new Configuration() val fs: FileSystem = FileSystem.newInstance(conf) val fileStatus: Array[FileStatus] = fs.listStatus(new Path(path)) for (fileStatue <- fileStatus) { println( s""" | 是否为目录: ${fileStatue.isDirectory} | 是否为文件: ${fileStatue.isFile} | 该文件上次访问时间:${fileStatue.getAccessTime} | 文件块大小: ${fileStatue.getBlockSize} | 文件所属组: ${fileStatue.getGroup} | 文件长度:${fileStatue.getLen} | 文件最后修改时间:${fileStatue.getModificationTime} | 文件所有者:${fileStatue.getOwner} | 文件的路径:${fileStatue.getPath} | 文件的父路径:${fileStatue.getPath.getParent} | 文件的名称:${fileStatue.getPath.getName} | 文件的权限:${fileStatue.getPermission} | 文件副本数:${fileStatue.getReplication} | ${fileStatue.getSymlink} """.stripMargin) } }
2.2 正则表达式获取文件状态
/** * 正则获取文件信息 */ def readStatusGlobStatus() = { val conf: Configuration = new Configuration() // val fs: FileSystem = FileSystem.newInstance(conf) val fs = FileSystem.get(new URI("hdfs://192.xxx.xxx.xxx:9000"), conf, "master") val path = new Path("/user/compass/*/*") // 路径正则表达式 val fileStatus: Array[FileStatus] = fs.globStatus(path) // 文件名数组 for (fileStatue <- fileStatus) { println( s""" | 文件的名称:${fileStatue.getPath.getName} | 文件的路径:${fileStatue.getPath} """.stripMargin) } }
2.3 正则表达式过滤文件
/** * 过滤文件信息 * 过滤出包含compass的路径 */ def readStatusFilterGlobStatus() = { val conf: Configuration = new Configuration() // val fs: FileSystem = FileSystem.newInstance(conf) val fs = FileSystem.get(new URI("hdfs://192.xxx.xxx.xxx:9000"), conf, "master") val path = new Path("/user/compass/*/*") // 路径正则表达式 val fileGlobStatuses = fs.globStatus(path, new PathFilter { override def accept(path: Path): Boolean = { val contidion: String = "compass" path.toString.contains(contidion) } })
注:globStatus 很灵活,内部甚至可以写一些正则表达式,有时候在处理大数据的预处理的时候可能很有效
参考:https://www.cnblogs.com/yinzhengjie/p/9094087.html
我不生产知识 我只是知识的搬运工