Hadoop HDFS Wrong FS: hdfs:/ expected file:///

2019-03-28 13:14|来源: 网络

HDFS是一个分布式文件系统,然而对于程序员来说,HDFS就是一个普通文件系统,Hadoop进行的底层封装,程序员按照相应的API来对HDFS上的文件操作,和对本地磁盘文件操作没有太多区别。但是最初接触时可能还是会碰到这样那样的问题。

例如:获取FileSystem实例时会出现

java.lang.NullPointerException
    at org.apache.hadoop.conf.Configuration.get(Configuration.java:382)
    at org.apache.hadoop.conf.Configuration.getBoolean(Configuration.java:570)
    at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:192)
    at hadoop.test.URLCat.copyFileToAnotherFile(URLCat.java:38) //这个是我写的一个方法,报错了
    at hadoop.test.URLCat.main(URLCat.java:83)

代码:

package hadoop.test;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.FsUrlStreamHandlerFactory;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdfs.DistributedFileSystem;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.util.Progressable;

public class URLCat extends Configured {
   
    /×static{
        Configuration.addDefaultResource("hdfs-default.xml");
        Configuration.addDefaultResource("hdfs-site.xml");
        Configuration.addDefaultResource("mapred-default.xml");
        Configuration.addDefaultResource("mapred-site.xml");
    } ×/没有这个static块时就会报上面对错误


    public  void copyFileToAnotherFile(String[] args)
    {
        InputStream in = null;
        OutputStream out = null;
        try {
            String sourceFile = args[0];
            String targetFile = args[1];
            in = new BufferedInputStream(new FileInputStream(sourceFile));
           
            Configuration conf = new Configuration();
            System.out.println(conf);
            System.out.println(URI.create(targetFile)==null);
            System.out.println(conf==null);
            System.out.println(FileSystem.get(URI.create(targetFile),conf)==null);
           
            FileSystem fs = DistributedFileSystem.get(URI.create(targetFile),conf);
            System.out.println(fs);
            out = fs.create(new Path(targetFile),new Progressable(){
                public void progress(){System.out.print(".");}
            });
            IOUtils.copyBytes(in, out, 4096,true);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally
        {
            IOUtils.closeStream(in);
            IOUtils.closeStream(out);
        }
    }
   
    static {
        URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
    }

    public static void displayFile(String[] args)
    {
        InputStream in = null;
            try {
                in = new URL(args[0]).openStream();
                IOUtils.copyBytes(in, System.out, 4096,false);
            } catch (MalformedURLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally
            {
                IOUtils.closeStream(in);
            }
    }
    /**
    * @param args
    */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new URLCat().copyFileToAnotherFile(args);
        //URLCat.displayFile(args);
        //
    }

}

 

原因:Configuration似乎只会加载基本的两个文件,所以需要将其它配置文件手动导入

 Configuration类:  defaultResources.add("hadoop-default.xml");
                                finalResources.add("hadoop-site.xml");

 

 

下面把整个代码到执行过程叙述一下,希望对刚接触hadoop编程的人有帮助:

 

1.需要配置好java环境主要是JAVA_HOME和CLASS_PATH,两个必须要设置

export JAVA_HOME=/usr/lib/jvm/java-6-sun
export PATH=$PATH:$JAVA_HOME/bin
export CLASSPATH=.:/usr/lib/jvm/java-6-sun/lib

 

2在本地编写代码,当然可以用Eclipse工具

 

3设置HADOOP_CLASSPATH

 HADOOP_CLASSPATH指向class文件的根目录,例如包hadoop.test的根目录上/home/hadoop/EclipseWorkspace/TestProject/bin

 

4执行命令hadoop hadoop.test.URLCat /home/hadoop/Documents/test.txt hdfs://192.186.54.1:8020/user/hadoop/test.txt

又出错了:java.lang.IllegalArgumentException: Wrong FS: hdfs://192.186.54.1:8020/user/hadoop/test.txt, expected: hdfs://hadoop1
    at org.apache.hadoop.fs.FileSystem.checkPath(FileSystem.java:310)
    at org.apache.hadoop.hdfs.DistributedFileSystem.checkPath(DistributedFileSystem.java:99)
    at org.apache.hadoop.hdfs.DistributedFileSystem.getPathName(DistributedFileSystem.java:155)
    at org.apache.hadoop.hdfs.DistributedFileSystem.create(DistributedFileSystem.java:195)
    at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:484)
    at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:384)
    at hadoop.test.URLCat.copyFileToAnotherFile(URLCat.java:46)
    at hadoop.test.URLCat.main(URLCat.java:86)
 原因,命令hdfs不能说IP,需要hostname,执行以下命令

 

 hadoop hadoop.test.URLCat /home/hadoop/Documents/test.txt hdfs://hadoop1:8020/user/hadoop/test.txt

 一切OK。

我的配置文件是ip,而不是hostname,因为没有DNS server帮助解析,但是执行命令仍然得用hostname。

综上:2个地方需要注意。Configuration和hdfs://hostname:port/user/pathtofile/file

相关问答

更多
  • hadoop hdfs的问题[2021-10-30]

    最下面那张图里环境变量设置的那一行多了一个$符号 export JAVA_HOME=/usr/java/jdk1.6.0_35
  • hadoop文件系统apis不提供对S3的支持。 S3的hadoop文件系统apis有两种实现:S3A和S3N。 S3A似乎是首选的实现。 要使用它,你必须做一些事情: 将aws-java-sdk-bundle.jar添加到你的类路径中。 在FileSystem配置中为以下属性创建FileSystem包含值时: fs.s3a.access.key fs.s3a.secret.key 当在S3上指定路径时不使用s3://使用s3a://代替。 注意:创建一个简单的用户并首先尝试使用基本身份验证。 有可能让它 ...
  • 您需要确保在hdfs中创建/ app / hadoop,而不是本地fs。 在检查目录时,使用ls -l检查本地文件系统,该文件系统与hdfs命名空间分开。 尝试hadoop fs -ls / app / hadoop。 如果它不在那里,那么用hadoop fs -mkdir创建它。 - snkherv You need to make sure /app/hadoop is created in hdfs, not the local fs. In your check for the directory ...
  • 对于小文件, copyFromLocalFile()就足够了: fs.copyFromLocalFile(new Path(localFileName), new Path(hdfsFileName)) 对于大文件,使用Apache Commons-IO会更有效率: IOUtils.copyLarge( new FileInputStream(new File(localFileName)), fs.create(new Path(hdfsFileName))) 请记住,本地文件名不应包含协议(因此 ...
  • 据我所知, 在这一行中的sc.textFile("hdfs://quickstart.cloudera:8020/user/spark/InputFile/inputText.txt") hdfs://quickstart.cloudera:8020引用HDFS目录或文件/ user / spark / InputFile /inputText.txt。 在这一行'/home/cloudera/InputFile/inputText.txt'中的sc.textFile("/home/cloudera/Inp ...
  • JobConf conf = new JobConf(getConf(), ...); ... FileInputFormat.setInputPaths(conf, new Path("stored.xls")) ... JobClient.runJob(conf); ... setInputPaths将做到这一点。 JobConf conf = new JobConf(getConf(), ...); ... FileInputFormat.setInputPaths(conf, new Path(" ...
  • 如果您可以执行hadoop version命令并返回正确的信息,则表示Hadoop安装良好。 我认为HDFS配置可能存在问题。 尝试这个: 在本地文件系统中找到core-site.xml文件。 它应该位于/etc/hadoop/conf目录中。 打开core-site.xml文件并找到此属性: fs.defaultFS hdfs://:8020 tr ...
  • 使用HDFS配置参数添加XML文件: Configuration conf = new Configuration(); conf.addResource(new Path("your_hadoop_path/conf/core-site.xml")); conf.addResource(new Path("your_hadoop_path/conf/hdfs-site.xml")); FileSystem fs = FileSystem.get(URI.create(uri),conf); Add th ...
  • 在后台,源文件被拆分为HDFS块,其大小可配置(通常为128 MB,默认为64 MB)。 对于容错,每个块都由HDFS自动复制。 默认情况下,每个块的三个副本将写入三个不同的DataNode。 复制因子是用户可配置的(默认为3)。 DataNode是服务器,它们是物理机器或虚拟机/云实例。 DataNodes构成了Hadoop集群,您可以在其中编写数据并运行MapReduce / Hive / Pig / Impala / Mahout /等。 程式。 DataNodes是Hadoop集群的工作者,Name ...
  • 默认情况下,Hadoop将使用本地模式。 您可能需要在$HADOOP_HOME/conf/core-site.xml中将fs.default.name设置为hdfs://localhost.localdomain:8020/ 。 为此,请将其添加到core-site.xml : fs.default.name hdfs://localhost.localdomain:8020/ Accumulo ...