java fs.default.name_HDFS API文件上传,fs.default.name配置的关键性

Exception in thread "main" java.lang.IllegalArgumentException: Wrong FS: hdfs://master:9000/index.html, expected:

file:///

at org.apache.hadoop.fs.FileSystem.checkPath(FileSystem.java:390)

at org.apache.hadoop.fs.RawLocalFileSystem.pathToFile(RawLocalFileSystem.java:55)

at org.apache.hadoop.fs.LocalFileSystem.pathToFile(LocalFileSystem.java:61)

at org.apache.hadoop.fs.LocalFileSystem.exists(LocalFileSystem.java:51)

at org.apache.hadoop.fs.FileUtil.checkDest(FileUtil.java:355)

at org.apache.hadoop.fs.FileUtil.copy(FileUtil.java:211)

at org.apache.hadoop.fs.FileUtil.copy(FileUtil.java:163)

at org.apache.hadoop.fs.LocalFileSystem.copyFromLocalFile(LocalFileSystem.java:67)

at org.apache.hadoop.fs.FileSystem.copyFromLocalFile(FileSystem.java:1178)

at com.lango.mapreduce.example.chainmapper.Test.fsCopy(Test.java:32)

at com.lango.mapreduce.example.chainmapper.Test.main(Test.java:25)

1、Wrong FS: hdfs://master:9000/index.html, expected:file:///

a、解决方案:复制core-site.xml和hdfs-site.xml到当前工程下

因为是访问远程的HDFS, 需要通过URI来获得FileSystem:

hadoop需要把集群上的core-site.xml和hdfs-site.xml放到当前工程下(eclipse工作目录的bin文件夹下面)

注意:

在我的Eclipse工作目录中没有找到bin文件夹。

e437b01f99124a8c13b71b1cce5c86e9.png

网上资料说“生成的class文件在项目目录中的bin目录下”,具体说法见下段参考资料:

生成的class文件在你的项目目录中的bin目录下,进入你的项目目录,可以看到一个.classpath文件,其中源文件地址,class文件存放地址,以及环境变量都是在这里面配置的,当然你可以通过myeclipse的界面配置,不过配置完成后都是修改的这个文件,这个就是配置源文件存放地址,这些是将哪个目录的那个jar包导入到path中这个是生成的class文件存放到哪,其中目录可以为绝对目录,相对目录是相对当前目录来说的,也就是项目目录本身

所以,我觉得bin目录就是我目录结构中的build/classes文件。因此,拷贝core-site.xml和hdfs-site.xml到build/classes目录中。

再次运行之前的代码:

package com.lango.mapreduce.example.chainmapper;

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;

import org.apache.hadoop.fs.FileSystem;

import org.apache.hadoop.fs.Path;

public class FsTest {

public static void main(String[] args) throws IOException {

Configuration conf = new Configuration();

FileSystem fs = FileSystem.get(conf);

Path src = new Path("C:/Users/lango/Desktop/core-site.xml");

Path dst = new Path("hdfs://master:9000/qj");

fs.copyFromLocalFile(src, dst);

}

}

运行通过。文件成功上传,问题解决。

2、问题引申:通过几种对文件操作方式的比较,来总结对于把文件上传到远程客户端什么是最关键的因素。

b、拷贝core-site.xml和hdfs-site.xml到当前工程下,修改目标路径形式为如下形式:

//注意和“Path dst = new Path("hdfs://master:9000/qj");”形式区分

Path dst = new Path("/qj");

整体代码如下:

package com.lango.mapreduce.example.chainmapper;

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;

import org.apache.hadoop.fs.FileSystem;

import org.apache.hadoop.fs.Path;

public class CopyToHDFS {

public static void main(String[] args) throws IOException {

Configuration conf = new Configuration();

FileSystem fs = FileSystem.get(conf);

fs.copyFromLocalFile(new Path("/home/wqj/opt/140702152709log.txt"), new Path("/qj"));

}

}

程序运行正常,文件上传成功。

c、不拷贝core-site.xml和hdfs-site.xml到当前工程下。配置

conf.set("fs.default.name", "hdfs://master:9000");

直接使用FileSystem类实现上传,代码如下:

package com.lango.mapreduce.example.chainmapper;

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;

import org.apache.hadoop.fs.FileSystem;

import org.apache.hadoop.fs.Path;

public class CopyToHDFS {

public static void main(String[] args) throws IOException {

Configuration conf = new Configuration();

conf.set("fs.default.name", "hdfs://master:9000");

FileSystem fs = FileSystem.get(conf);

fs.copyFromLocalFile(new Path("/home/wqj/opt/140702152709log.txt"), new Path("/qj"));

}

}

运行通过,文件上传到远程HDFS上成功。

d、拷贝core-site.xml和hdfs-site.xml到当前工程下。直接使用FileSystem类实现上传,代码如下:

package com.lango.mapreduce.example.chainmapper;

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;

import org.apache.hadoop.fs.FileSystem;

import org.apache.hadoop.fs.Path;

import org.apache.hadoop.hdfs.DistributedFileSystem;

public class FsTest {

public static void main(String[] args) throws IOException {

Configuration conf = new Configuration();

FileSystem  fs = FileSystem.get(conf);

fs.copyFromLocalFile(new Path("C:/Users/lango/Desktop/core-site.xml"), new Path("/qj-dfs"));

}

}

运行通过,文件成功上传。

e、不拷贝core-site.xml和hdfs-site.xml到当前工程下。直接使用FileSystem类实现上传,代码和b完全相同。

和b做对比,有一个奇妙的现象。

a1b9c3095c29e79124c756b806998b52.png

我们上传的文件它并没有被上传到远程HDFS中,而是跑到本地Eclipse工作目录所在根目录E盘下了。并且可看见文件的存放形式:.qj.crc和qj。

Eclipse控制台输出日志信息如下:

八月 12, 2014 2:47:41 下午 org.apache.hadoop.util.NativeCodeLoader 

WARNING: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable

运行通过,文件未成功上传到远程HDFS中,而是被上传到Eclipse工作目录所在根目录下了。

f、不拷贝core-site.xml和hdfs-site.xml到当前工程下。直接使用DistributedFileSystem类实现上传,代码如下:

package com.lango.mapreduce.example.chainmapper;

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;

import org.apache.hadoop.fs.FileSystem;

import org.apache.hadoop.fs.Path;

import org.apache.hadoop.hdfs.DistributedFileSystem;

public class FsTest {

public static void main(String[] args) throws IOException {

Configuration conf = new Configuration();

conf.set("fs.default.name", "hdfs://master:9000");

DistributedFileSystem fs = (DistributedFileSystem) FileSystem.get(conf);

Path src = new Path("C:/Users/lango/Desktop/core-site.xml");

Path dst = new Path("/qj-dfs");

fs.copyFromLocalFile(src, dst);

}

}

运行通过,文件成功上传。

注意:在d中,若省略“

conf.set("fs.default.name", "hdfs://master:9000");

”则程序报错。报错信息

Exception in thread "main" java.lang.ClassCastException: org.apache.hadoop.fs.LocalFileSystem cannot be cast to org.apache.hadoop.hdfs.DistributedFileSystem

at com.lango.mapreduce.example.chainmapper.FsTest.main(FsTest.java:16)

解决方案:拷贝core-site.xml和hdfs-site.xml到当前工程下。整体代码不改变,代码如下:

package com.lango.mapreduce.example.chainmapper;

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;

import org.apache.hadoop.fs.FileSystem;

import org.apache.hadoop.fs.Path;

import org.apache.hadoop.hdfs.DistributedFileSystem;

public class FsTest {

public static void main(String[] args) throws IOException {

Configuration conf = new Configuration();

//        省略fs.default.name配置

//        conf.set("fs.default.name", "hdfs://master:9000");

DistributedFileSystem fs = (DistributedFileSystem) FileSystem.get(conf);

Path src = new Path("C:/Users/lango/Desktop/core-site.xml");

Path dst = new Path("/qj-dfs");

fs.copyFromLocalFile(src, dst);

}

}

运行通过,文件上传成功。

通过上面一系列自己都觉得很晕的比较之后,感觉,无论怎么变,它们之间的最大区别就在于

fs.default.name属性的配置

conf.set("fs.default.name", "hdfs://master:9000");

综上所述:

无论我们是在代码中对"fs.default.name"进行配置,还是直接拷贝core-site.xml和hdfs-site.xml到当前工程下,最终我们的目的都是要实现对fs.default.name的配置。

只有对fs.default.name成功配置后,我们才能成功上传文件到远程客户端。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值