Hadoop HDFS 编程

本文详细介绍了使用Hadoop的HDFS进行文件操作时常见的问题及解决办法,包括Configuration配置、FileSystem实例获取等,并提供了完整的代码示例。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值