hdfs java读写hdfs demo

windows环境配置:


1.下载winutils的windows版本

  GitHub上,有人提供了winutils的windows的版本,

项目地址是:https://github.com/srccodes/hadoop-common-2.2.0-bin,直接下载此项目的zip包,下载后是文件名是hadoop-common-2.2.0-bin-master.zip,

2016-12-14更新

在hadoop2.7.x版本里,请使用:https://github.com/SweetInk/hadoop-common-2.7.1-bin

随便解压到一个目录,将加压出来的bin文件夹覆盖hadoop压缩包解压出来的bin目录。

2.配置环境变量

  增加用户变量HADOOP_HOME,值是下载的zip包解压的目录,然后在系统变量path里增加%HADOOP_HOME%\bin 。

3、压缩包里的hadoop.dll,并拷贝到c:\windows\system32目录中。


如果下载的版本与hadoop不对应,或者windows环境没配置好,会报错:

1、java.io.IOException: (null) entry in command string: null chmod 0644

2、java.lang.UnsatisfiedLinkError: org.apache.hadoop.io.nativeio.NativeIO


实例代码:



package filedemo;

import java.io.FileInputStream;
import java.net.URI;
import java.util.Iterator;
import java.util.Map.Entry;

import org.apache.commons.io.IOUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.BlockLocation;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.LocatedFileStatus;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.RemoteIterator;
import org.junit.Before;
import org.junit.Test;

public class HdfsUtil {
	
	FileSystem fs=null;
	
	//@Before 是junit 测试框架
	@Before
	public void init() throws Exception{
		
		/*
		 * 
		 * 注意注意注意
		 * windows上eclipse上运行,hadoop的bin文件下windows环境编译的文件和hadoop版本关系紧密
		 * 如果报错,或者api无效,很可能是bin下hadoop文件问题
		 * 
		 */
		
		//读取classpath下的core/hdfs-site.xml 配置文件,并解析其内容,封装到conf对象中
		//如果没有会读取hadoop里的配置文件
		Configuration conf=new Configuration();
		
		//也可以在代码中对conf中的配置信息进行手动设置,会覆盖掉配置文件中的读取的值
		//设置文件系统为hdfs。如果设置这个参数,那么下面的方法里的路径就不用写hdfs://hello110:9000/
		//conf.set("fs.defaultFS", "hdfs://hello110:9000/");
		
		//根据配置信息,去获取一个具体文件系统的客户端操作实例对象
		fs=FileSystem.get(new URI("hdfs://hadoop1:9000/"), conf,"hadoop");
		
		Iterator> iterator = conf.iterator();
		while(iterator.hasNext()){
			Entry ent=iterator.next();
			System.out.println(ent.getKey()+"  :  "+ent.getValue());
		}
		
		System.out.println("-----------------/hdfs-site.xml 文件读取结束----------------");
	}
	
	@Test
	public void listFiles() throws Exception{
		
		//RemoteIterator 远程迭代器
		RemoteIterator listFiles = fs.listFiles(new Path("/"), true);
		
		while(listFiles.hasNext()){
			LocatedFileStatus file = listFiles.next();
			Path path = file.getPath();
			//String fileName=path.getName();
			System.out.println(path.toString());
			System.out.println("权限:"+file.getPermission());
			System.out.println("组:"+file.getGroup());
			System.out.println("文件大小:"+file.getBlockSize());
			System.out.println("所属者:"+file.getOwner());
			System.out.println("副本数:"+file.getReplication());
			
			BlockLocation[] blockLocations = file.getBlockLocations();
			for(BlockLocation bl:blockLocations){
				System.out.println("块起始位置:"+bl.getOffset());
				System.out.println("块长度:"+bl.getLength());
				String[] hosts = bl.getHosts();
				for(String h:hosts){
					System.out.println("块所在DataNode:"+h);
				}
				
			}
			
			System.out.println("*****************************************");
			
		}
		
		System.out.println("-----------------华丽的分割线----------------");
		
		FileStatus[] listStatus = fs.listStatus(new Path("/"));
		
		for(FileStatus status:listStatus){
			String name=status.getPath().getName();
			System.out.println(name+(status.isDirectory()?" is Dir":" is File"));
		}
	}
	
	//比较低层的写法
	@Test
	public void upload() throws Exception{
		
		System.out.println("-----------------upload----------------");
		
		Path path = new Path("/testdata/testFs.txt");
		FSDataOutputStream os = fs.create(path);
		
		FileInputStream is = new FileInputStream("d:/testFS.txt");
		
		IOUtils.copy(is, os);
	}
	
	//封装好的方法
	@Test
	public void upload2() throws Exception{
		
		System.out.println("-----------------upload2----------------");
		//hdfs dfs -copyFromLocal 从本地拷贝命令
		fs.copyFromLocalFile(new Path("d:/testFS-2.txt"), new Path("/testdata/testFs6.txt"));
		//如果windows-hadoop环境不行,可以用下面的api,最后的true是:用java的io去写。
		//fs.copyToLocalFile(false, new Path("d:/testFS-2.txt"), new Path("/testdata/testFs6.txt"), true);
		fs.close();
		
	}
	
	@Test
	public void download() throws Exception{
		
		//hdfs dfs -copyToLocal 拷贝到本地命令
		fs.copyToLocalFile(new Path("/testdata/testFs6.txt") , new Path("d:/testFS3.txt"));
		//如果windows-hadoop环境不行,可以用下面的api,最后的true是:用java的io去写。
		//fs.copyToLocalFile(false, new Path("/testdata/testFs6.txt"), new Path("d:/testFS3.txt"), true);
		
	}
	
	@Test
	public void mkdir() throws Exception{
		
		System.out.println("-----------------mkdir----------------");
		
		fs.mkdirs(new Path("/testdata/a123"));
		fs.mkdirs(new Path("/testdata/a124"));
	}
	
	@Test
	public void rm() throws Exception{
		//true:如果是目录也会删除。false,遇到目录则报错
		fs.delete(new Path("hdfs://hello110:9000/testdata/a124"), true);
	}
	
}




package filedemo;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;

import org.apache.commons.io.IOUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.junit.Before;
import org.junit.Test;


/**
 * 用流的方式来操作hdfs上的文件
 * 可以实现读取指定偏移量范围的数据
 * @author
 *
 */
public class HdfsStreamAccess {
	
	FileSystem fs = null;
	Configuration conf = null;
	
	@Before
	public void init() throws Exception{
		
		conf = new Configuration();
		//拿到一个文件系统操作的客户端实例对象
//		fs = FileSystem.get(conf);
		//可以直接传入 uri和用户身份
		fs = FileSystem.get(new URI("hdfs://mini1:9000"),conf,"hadoop");
	}
	

	/**
	 * 通过流的方式上传文件到hdfs
	 * @throws Exception
	 */
	@Test
	public void testUpload() throws Exception {
		
		FSDataOutputStream outputStream = fs.create(new Path("/angelababy.love"), true);
		FileInputStream inputStream = new FileInputStream("c:/angelababy.love");
		
		IOUtils.copy(inputStream, outputStream);
		
	}
	
	
	/**
	 * 通过流的方式获取hdfs上数据
	 * @throws Exception
	 */
	@Test
	public void testDownLoad() throws Exception {
		
		FSDataInputStream inputStream = fs.open(new Path("/angelababy.love"));		
		
		FileOutputStream outputStream = new FileOutputStream("d:/angelababy.love");
		
		IOUtils.copy(inputStream, outputStream);
		
	}
	
	
	@Test
	public void testRandomAccess() throws Exception{
		
		FSDataInputStream inputStream = fs.open(new Path("/angelababy.love"));
	
		inputStream.seek(12);
		
		FileOutputStream outputStream = new FileOutputStream("d:/angelababy.love.part2");
		
		IOUtils.copy(inputStream, outputStream);
		
		
	}
	
	
	
	/**
	 * 显示hdfs上文件的内容
	 * @throws IOException 
	 * @throws IllegalArgumentException 
	 */
	@Test
	public void testCat() throws IllegalArgumentException, IOException{
		
		FSDataInputStream in = fs.open(new Path("/angelababy.love"));
		
		IOUtils.copy(in, System.out);
		
	}
	
	
	
	
	
}



你可能感兴趣的:(大数据)