[英]How to specify path of a file in java/terminal on Hadoop?
我正在Hadoop2上运行任务:
$hadoop jar hipi.jar "/5" "/processWOH" 1
hipi.jar:jar文件名
“ / 5”:输入文件夹名称
“ / processWOH”:输出文件夹名称
我在路径/localhost:9000/5/LC814000.tif中遇到异常:
Error: java.io.FileNotFoundException: /localhost:9000/5/LC814000.tif (No such file or directory)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at java.io.FileInputStream.<init>(FileInputStream.java:93)
at ProcessWithoutHIPI.ProcessRecordReaderWOH.getCurrentKey(ProcessRecordReaderWOH.java:81)
at ProcessWithoutHIPI.ProcessRecordReaderWOH.getCurrentKey(ProcessRecordReaderWOH.java:1)
at org.apache.hadoop.mapred.MapTask$NewTrackingRecordReader.getCurrentKey(MapTask.java:507)
at org.apache.hadoop.mapreduce.task.MapContextImpl.getCurrentKey(MapContextImpl.java:70)
at org.apache.hadoop.mapreduce.lib.map.WrappedMapper$Context.getCurrentKey(WrappedMapper.java:81)
at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:145)
at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:764)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:340)
at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:167)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:422)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1548)
at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:162)
我认为(我不确定)路径中添加了额外的“ / localhost:9000”的问题,但是我不知道它是如何添加的(由hadoop,java代码...)。
注意:此jar文件在hadoop外部运行良好,但在hadoop(hdfs)中却不是
任何帮助表示赞赏
更新:正如我后来发现的那样,在本地系统中而不是在hdfs中搜索“ / 5”文件夹,并且如果我在本地文件系统中在根(即/ localhost:9000)下创建名称为“ localhost:9000”的文件夹,并放入“ / 5“代码将运行,但是在这种情况下,数据将从hadoop中获取,就像我根本不使用hadoop一样。 那么这是编程中的错误吗,即我应该使用hadoop io软件包而不是java io软件包来处理hdfs而不是本地文件系统,否则这是另一个问题。
hdfs的默认目录为/ localhost:9000 /,hadoop在此处找不到您的输入文件; 刚过去在/ localhost:9000 /中:
$hadoop fs -put $LOCAL_PATH_OF_INPUT_FILE:/5 /localhost:9000/
$hadoop jar hipi.jar "/5" "/processWOH" 1
祝好运!
问题是,正如我早先所说的那样,Java IO(即文件类,路径类,...)将路径视为本地文件系统,而Hadoop Io(文件系统类,路径类,...)将路径视为HDFS。
请在此处查看: 从HDFS中读取/写入
使用FileSystem API读写数据到HDFS
从Hadoop分布式文件系统(HDFS)读取数据或将数据写入Hadoop分布式文件系统(HDFS)可以通过多种方式完成。 现在,让我们开始使用FileSystem API在HDFS中创建和写入文件,然后是从HDFS读取文件并将其写回到本地文件系统的应用程序。
步骤1:下载测试数据集后,我们可以编写一个应用程序以从本地文件系统读取文件,并将内容写入Hadoop分布式文件系统。
package com.hadoop.hdfs.writer;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.util.Tool;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.util.ToolRunner;
public class HdfsWriter extends Configured implements Tool {
public static final String FS_PARAM_NAME = "fs.defaultFS";
public int run(String[] args) throws Exception {
if (args.length < 2) {
System.err.println("HdfsWriter [local input path] [hdfs output path]");
return 1;
}
String localInputPath = args[0];
Path outputPath = new Path(args[1]);
Configuration conf = getConf();
System.out.println("configured filesystem = " + conf.get(FS_PARAM_NAME));
FileSystem fs = FileSystem.get(conf);
if (fs.exists(outputPath)) {
System.err.println("output path exists");
return 1;
}
OutputStream os = fs.create(outputPath);
InputStream is = new BufferedInputStream(new FileInputStream(localInputPath));
IOUtils.copyBytes(is, os, conf);
return 0;
}
public static void main( String[] args ) throws Exception {
int returnCode = ToolRunner.run(new HdfsWriter(), args);
System.exit(returnCode);
}
}
步骤2:导出Jar文件并从终端运行代码以将示例文件写入HDFS:
[training@localhost ~]$ hadoop jar HdfsWriter.jar com.hadoop.hdfs.writer.HdfsWriter sample.txt /user/training/HdfsWriter_sample.txt
步骤3:验证文件是否已写入HDFS并检查文件的内容:
[training@localhost ~]$ hadoop fs -cat /user/training/HdfsWriter_sample.txt
步骤4:接下来,我们编写一个应用程序来读取我们刚刚在Hadoop分布式文件系统中创建的文件,并将其内容写回到本地文件系统中:
package com.hadoop.hdfs.reader;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
public class HdfsReader extends Configured implements Tool {
public static final String FS_PARAM_NAME = "fs.defaultFS";
public int run(String[] args) throws Exception {
if (args.length < 2) {
System.err.println("HdfsReader [hdfs input path] [local output path]");
return 1;
}
Path inputPath = new Path(args[0]);
String localOutputPath = args[1];
Configuration conf = getConf();
System.out.println("configured filesystem = " + conf.get(FS_PARAM_NAME));
FileSystem fs = FileSystem.get(conf);
InputStream is = fs.open(inputPath);
OutputStream os = new BufferedOutputStream(new FileOutputStream(localOutputPath));
IOUtils.copyBytes(is, os, conf);
return 0;
}
public static void main( String[] args ) throws Exception {
int returnCode = ToolRunner.run(new HdfsReader(), args);
System.exit(returnCode);
}
}
步骤5:导出Jar文件并从终端运行代码以将示例文件写入HDFS:
[training@localhost ~]$ hadoop jar HdfsReader.jar com.hadoop.hdfs.reader.HdfsReader /user/training/HdfsWriter_sample.txt /home/training/HdfsReader_sample.txt
步骤6:验证文件是否被写回到本地文件系统中:
[training@localhost ~]$ hadoop fs -cat /user/training/HdfsWriter_sample.txt
FileSystem是代表通用文件系统的抽象类。 可以通过FileSystem对象访问和更新大多数Hadoop文件系统实现。 要创建HDFS实例,请调用FileSystem.get()方法。 FileSystem.get()方法将在类路径上查看分配给Hadoop配置文件的fs.defaultFS参数的URI,然后选择要实例化的FileSystem类的正确实现。 HDFS的fs.defaultFS参数值为hdfs://。
创建FileSystem类的实例后,HdfsWriter类将调用create()方法在HDFS中创建文件。 create()方法返回一个OutputStream对象,可以使用常规Java I / O方法对其进行操作。 类似地,HdfsReader调用方法open()在HDFS中打开文件,该文件返回一个InputStream对象,该对象可用于读取文件的内容。
FileSystem API广泛。 为了演示API中可用的其他一些方法,我们可以向我们创建的HdfsWriter和HdfsReader类添加一些错误检查。
要在调用create()之前检查文件是否存在,请使用:
boolean exists = fs.exists(inputPath);
要检查路径是否是文件,请使用:
boolean isFile = fs.isFile(inputPath);
要重命名已经存在的文件,请使用:
boolean renamed = fs.rename(inputPath, new Path("old_file.txt"));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.