繁体   English   中英

如何在Hadoop上的Java / terminal中指定文件的路径?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM