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

原文地址:https://www.cnblogs.com/yyy-blog/p/10525804.html