我一直在使用Cloudera的hadoop(0.20.2)。 在这个版本中,如果我将文件放入文件系统,但目录结构不存在,它会自动创建父目录:
例如,如果我在 hdfs 中没有目录并输入:
hadoop fs -put myfile.txt /some/non/existing/path/myfile.txt
它将创建所有目录:some、non、existing和path并将文件放入其中。
现在,使用较新的 hadoop (2.2.0) 产品,不会自动创建目录。 与上面相同的命令会产生:
put:`/some/non/existing/path/':没有这样的文件或目录
我有一个解决方法,首先对每个 put 执行 hadoop fs -mkdir,但这不会表现良好。
这个可以配置吗? 有什么建议吗?
现在你应该使用
hadoop fs -mkdir -p <path>
如果目录不存在,则 put 操作不会创建该目录。我们需要在执行 put 操作之前创建目录。
您可以使用以下命令来创建目录。
hdfs dfs -mkdir -p <path>
-p
如果父目录不存在,它将首先创建它。但如果它 已经存在,那么它不会打印错误消息并且会移动 进一步创建子目录。
编者注:警告此答案表明不正确
hadoop fs ...
已弃用,而是使用:hdfs dfs -mkdir ....
将文件放入 hdfs 中不存在的目录中需要两步过程。正如 @rt-vybor 所说,使用 mkdir 的“-p”选项来创建多个缺失的路径元素。但由于OP询问如何将文件放入hdfs,因此以下也执行hdfs put,并注意您还可以(可选)检查put是否成功,并有条件地删除本地副本。
首先在hdfs中创建相关目录路径,然后将文件放入hdfs中。您需要在放入 hdfs 之前检查该文件是否存在。 您可能想记录/显示该文件已成功放入 hdfs。以下结合了所有步骤。
fn=myfile.txt
if [ -f $fn ] ; then
bfn=`basename $fn` #trim path from filename
hdfs dfs -mkdir -p /here/is/some/non/existant/path/in/hdfs/
hdfs dfs -put $fn /here/is/some/non/existant/path/in/hdfs/$bfn
hdfs dfs -ls /here/is/some/non/existant/path/in/hdfs/$bfn
success=$? #check whether file landed in hdfs
if [ $success ] ; then
echo "remove local copy of file $fn"
#rm -f $fn #uncomment if you want to remove file
fi
fi
您可以将其转换为 shell 脚本,采用 hadoop 路径和文件列表(也只创建一次路径),
#!/bin/bash
hdfsp=${1}
shift;
hdfs dfs -mkdir -p /here/is/some/non/existant/path/in/hdfs/
for fn in $*; do
if [ -f $fn ] ; then
bfn=`basename $fn` #trim path from filename
hdfs dfs -put $fn /here/is/some/non/existant/path/in/hdfs/$bfn
hdfs dfs -ls /here/is/some/non/existant/path/in/hdfs/$bfn >/dev/null
success=$? #check whether file landed in hdfs
if [ $success ] ; then
echo "remove local copy of file $fn"
#rm -f $fn #uncomment if you want to remove file
fi
fi
done
put 操作要求目标目录预先存在,因为如果目标目录缺失,则不会自动创建它。 执行put命令之前必须先创建目录。
要在 Hadoop 中创建嵌套目录,可以使用以下命令:
hadoop fs -mkdir -p
或
hdfs dfs -mkdir -p
如果需要删除HDFS中的嵌套目录,可以在rm命令中使用递归-r选项:
hadoop fs -rm -r
或
hdfs dfs -rm -r
这些命令可以让您轻松管理HDFS中的嵌套目录!