hadoop学习笔记之hdfs的文件上传下载
实验平台:hadoop2.4.1 Linux系统采用CentOS6.4 编程工具: Linux 下的javaEE
实验初期准备是:将以上开发环境搭建好。这里说一下jar包,导入jar的步骤是:使用WinSCP将文件传入Linux系统,再将文件jar包复制到home目录下。选择build path -->
add Library -->user Library--->new --->hadoop2.4.1(这个就是个包名随便取)-->add External Jar-->会选择要导入jar包即可-->ok-->finish。导入jar包结束。
文件上传到hdfs的代码:
// 上传文件到hdfs系统
public static void main(String[] args) throws IOException {
<span style="font-size:18px;"> //创建Configuration对象 ,是用来处理配置信息,hadoop的配置文件的格式是xml的格式
//在core-site.xml文件中会设置fs.default.name值为hadoop的namenode的地址以及端口号,如hdfs://localhost:9000,即表示namenode是本机,也就是为分布式。
//所以我们在连接hdfs时需要指定连接的地址,也就是hadoop集群中core-site.xml中fs.default.name属性值。
Configuration conf = new Configuration();
//手动为Configuration对象设置fs.default.name属性值、文件的备份数为1
conf.set("fs.defaultFS","hdfs://hadoop01:9000");
conf.set("dfs.replication","1");
//在完成配置信息的设置后,根据配置信息创建FileSystem对象
//注意此处调用的方法是FileSystem的get方法,参数为上面创建的Configuration对象
FileSystem fs = FileSystem.get(conf);
//读入本地的文件,创建FileInputStream
//创建FileInputStream对象,调用其构造方法,参数为本地文件的路径
FileInputStream fis = new FileInputStream("/home/myapp/mytxt");
//创建上传到hdfs分布式文件系统的路径
Path destFile = new Path("hdfs://hadoop01:9000/mytxt");
//调用FileSystem对象的Create()创建hdfs文件写出的输出流,参数为创建的路径
FSDataOutpuStream os = fs.create(destFile);
//从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中
//调用IOUtils的copy()将FileInputStream中的数据copy到FSDataOutputStream中
IOUtils.copy(fis,os)</span>
}
这里在写"hdfs://hadoop01:9000/mytxt"时注意与自己的配置文件保持一致,否则会报错的,不能连接。
异常是: java.net.ConnectException: Call From hadoop/192.168.80.100 to hadoop:9000 failed on connection exception: java.net.ConnectException: Connection refused; For more details see: http://wiki.apache.org/hadoop/ConnectionRefused
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)解决的办法是将其改为与配置文件一致即可。
当时查了很多资料,有什么防火墙没有关闭的,hadoop服务没有启动的,还有的说是将主机名改为IP地址的,官网上也给了几种提示,修改后都不行。没想到居然是将其改为hadoop01即可。这是因为我的配置文件写的也是hadoop01。
文件的下载也是大同小异:
@Test
public void testDownload() throws IllegalArgumentException, IOException{
<span style="font-size:18px;"> Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://hadoop01:9000/");
//get a instance of HDFS FileSystem Client
FileSystem fs = FileSystem.get(conf);
//读入要下载的文件
FSDataInputStream is = fs.open(new Path("hdfs://hadoop01:9000/hdfsClient"));
//下载到本地后的文件路径
FileOutputStream os = new FileOutputStream("/home/hadoop/MyDownLoad.download");
IOUtils.copy(is, os);</span>
}
总结:
对于分布式文件系统的上传、下载与java文件操作是相同的,如果做过java中的文件复制,这个文件的上传和下载是非常好理解的。就是读入文件,再写出文件。
那么对于分布式文件系统的上传要说明的是,当我们选择将文件存储到分布式系统中,要明确文件物理存储是在节点中的,datanode中,如果是单节点,那么一定会找到该文件的物理路径,而且对于小文件是不易用分布式系统来存储,因为他们存储所占用的块的大小依然是128M,如下图:
此处我选择是相同两个文件,分两次上传来测试的结果,常常会将小文件整合成一个合适大小的文件上传到分布式系统中。
由此,我们又得到的结论是:分布式文件系统易传大不易传小。