• 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

  • 相关阅读:
    Rust入坑指南:亡羊补牢
    antirez:Redis6真的来了
    代码检查又一利器:ArchUnit
    【译】浅谈SOLID原则
    Rust入坑指南:鳞次栉比
    【译】什么才是优秀的代码
    Elasticsearch从入门到放弃:文档CRUD要牢记
    【译】利用Lombok消除重复代码
    Netty 中的心跳检测机制
    Netty 中的异步编程 Future 和 Promise
  • 原文地址:https://www.cnblogs.com/yyy-blog/p/10525804.html
Copyright © 2020-2023  润新知