【问题标题】:Hadoop concatenate files recursively maintaining directory structureHadoop连接文件递归维护目录结构
【发布时间】:2016-10-03 16:07:48
【问题描述】:

我想在一个目录下添加2个目录的文件,同时保持目录结构。

我有目录 1 和目录 2,每个目录都有大约 80 个子目录,结构如下所示。

HDFS 上的目录 1:

  • /user/hadoop/1/abc/file11
  • /user/hadoop/1/def/file12
  • /user/hadoop/1/ghi/file13
  • /user/hadoop/1/jkl/file14
  • /user/hadoop/1/mno/file15

HDFS 上的目录 2:

  • /user/hadoop/2/abc/file26
  • /user/hadoop/2/ghi/file27
  • /user/hadoop/2/mno/file28

我想将 dir 1 的 file11 和 dir 2 的文件 26 合并到一个目录下,dir 1 的文件 13 和 dir 27 等等。 目标目录是目录 1。

从 dir 2 添加到 dir 1 的文件应该与子目录的路径匹配。

期望的输出:

  • /user/hadoop/1/abc/file11 , /user/hadoop/1/abc/file26
  • /user/hadoop/1/def/file12
  • /user/hadoop/1/ghi/file13 , /user/hadoop/1/ghi/file27
  • /user/hadoop/1/jkl/file14
  • /user/hadoop/1/mno/file15 , /user/hadoop/1/mno/file28

感谢任何帮助。

【问题讨论】:

  • 你想复制/user/hadoop/1/abc/file11和/user/hadoop/2/abc/file26在同一目录/user/hadoop/1/abc/下吗?其他人也一样?到目前为止,您尝试过什么?
  • 如果您对答案没问题,请标记“所有者接受”并投票

标签: file hadoop path filesystems hdfs


【解决方案1】:

使用org.apache.hadoop.fs.FileUtil API

您会通过以下 API 获得 FileSystem

 final FileSystem fs = FileSystem.get(conf);
  • 复制

    公共静态布尔副本(文件系统 srcFS, 路径 [] 源文件, 文件系统 dstFS, 路径 dst, 布尔删除源, 布尔覆盖, 配置文件) 抛出 IOException 抛出: IO异常

此方法在文件系统之间复制文件。

  • 替换文件 FileUtil.replaceFile(File src, File target) 也应该可以工作

请参阅此方法的文档“将 src 文件移动到目标指定的名称。”

在任何一种情况下,您都需要通过在第三个之后的比较来列出您的公共文件夹 /user/hadoop/2/abc/ /user/hadoop/1/abc/斜线字符以及它们是否将复制源与目标匹配或根据您的要求开发逻辑(这个我将留给您:-))

复制到所需目标后:您可以使用以下示例方法在流程中看到它们

/**
         * Method listFileStats.
         * 
         * @param destination
         * @param fs
         * @throws FileNotFoundException
         * @throws IOException
         */
        public static void listFileStats(final String destination, final FileSystem fs) throws FileNotFoundException, IOException {
            final FileStatus[] statuss = fs.listStatus(new Path(destination));
            for (final FileStatus status : statuss) {
///below log are sl4j you can use other loggers..
                LOG.info("--  status {}    ", status.toString());
            }
        }

【讨论】:

  • 我在线程“main”中遇到异常 java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory at org.apache.hadoop.conf.Configuration.(Configuration.java: 146) 我的 bin/hadoop 类路径中有 commons-logging-1.1.1.jar: 和 commons-logging-api-1.0.4.jar
  • 请注意,所提出的问题与这个 classnotfound 错误之间没有关系。这与您的 hadoop 类路径有关。在执行你的 java 文件时。
  • 请您详细说明您提供的解决方案。我想知道如何检查 dir 2 的 abc 或 ghi 或 mno 是否存在于 dir 1 中,即检查到第三个斜杠
  • 关于以字符串为例:str = "/a/d/c" 使用 str.split("/");
【解决方案2】:

我正在为目录 2 下的每个文件获取一个唯一的文件名,并将其添加到目录 1 下的正确子目录中。 以下是脚本:

for file in $(hadoop fs -ls /user/hadoop/2/* | grep -o -e "/user/hadoop/2/.*") ; do

subDir=$(echo $file | cut -d '/' -f 5)
fileName=$(echo $file | cut -d '/' -f 6)
uuid=$(uuidgen)
newFileName=$fileName"_"$uuid

    hadoop fs -cp $file /user/hadoop/1/$subDir/$newFileName
done

【讨论】:

    猜你喜欢
    • 2019-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-07
    • 1970-01-01
    相关资源
    最近更新 更多