如何在hadoop的java/terminal中指定文件的路径?

oipij1gg  于 2021-05-29  发布在  Hadoop
关注(0)|答案(2)|浏览(403)

我正在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)中却不是
感谢您的帮助
更新:我后来发现“/5”文件夹是在本地系统中搜索的,而不是在hdfs中,如果我在本地文件系统中创建一个名为localhost:9000“根下,即/localhost:9000 and put“/5”代码将运行,但在本例中,数据是从hadoop外部获取的,就像我根本不使用hadoop一样。那么,这是编程中的一个错误,即我应该使用hadoop io包而不是java io包来处理hdfs而不是本地文件系统,还是另一个问题。?

oyt4ldly

oyt4ldly1#

hdfs的默认目录是/localhost:9000/,hadoop在那里找不到您的输入文件;刚刚过去/localhost:9000/:

$hadoop fs -put $LOCAL_PATH_OF_INPUT_FILE:/5 /localhost:9000/
$hadoop jar hipi.jar "/5" "/processWOH" 1

祝你好运!

d7v8vwbk

d7v8vwbk2#

问题是,正如我前面所说的,java io(即文件类、路径类……)将路径视为本地文件系统中的路径,而hadoop io(文件系统类、路径类……)将路径视为hdfs中的路径。
请看这里:读/写从/在hdfs
使用文件系统api向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);
    }
}

第二步:导出jar文件,从终端运行代码,将示例文件写入hdfs:

[training@localhost ~]$ hadoop jar HdfsWriter.jar com.hadoop.hdfs.writer.HdfsWriter sample.txt /user/training/HdfsWriter_sample.txt

第三步:验证文件是否写入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);
    }
}

第五步:导出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是一个抽象类,它表示一个通用的文件系统。大多数hadoop文件系统实现都可以通过filesystem对象进行访问和更新。要创建hdfs的示例,可以调用filesystem.get()方法。get()方法将查看分配给类路径上hadoop配置文件的fs.defaultfs参数的uri,并选择要示例化的文件系统类的正确实现。hdfs的fs.defaultfs参数具有hdfs://.
一旦创建了filesystem类的示例,hdfswriter类就调用create()方法在hdfs中创建一个文件。create()方法返回一个outputstream对象,可以使用普通的JavaI/o方法对其进行操作。类似地,hdfsreader调用open()方法在hdfs中打开一个文件,该方法返回一个inputstream对象,可用于读取文件的内容。
文件系统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"));

相关问题