歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

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

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

Copyright © Linux教程網 All Rights Reserved