Java代码操作HDFS测试类
1.Java代码操作HDFS需要用到Jar包和Java类
Jar包:
hadoop-common-2.6.0.jar和hadoop-hdfs-2.6.0.jar
Java类:
java.net.URL
org.apache.hadoop.fs.FsUrlStreamHandlerFactory
java.net.URI
org.apache.hadoop.conf.Configuration
org.apache.hadoop.fs.FileSystem
org.apache.hadoop.fs.Path
org.apache.hadoop.io.IOUtils
2.读文件的过程
客户端(client)用FileSystem的open()函数打开文件,DistributedFileSystem用RPC调用名称节点,得到文件的数据块信息。对于每一个数据块,名称节点返回保存数据块的数据节点的地址。
DistributedFileSystem返回FSDataInputStream给客户端,用来读取数据。
客户端调用stream的read()函数开始读取数据。DFSInputStream连接保存此文件第一个数据块的最近的数据节点。
Data从数据节点读到客户端(client),当此数据块读取完毕时,DFSInputStream关闭和此数据节点的连接,然后连接此文件下一个数据块的最近的数据节点。
当客户端读取完毕数据的时候,调用FSDataInputStream的close函数。
在读取数据的过程中,如果客户端在与数据节点通信出现错误,则尝试连接包含此数据块的下一个数据节点。失败的数据节点将被记录,以后不再连接。
3.上代码:
写文件 create
读取文件 open
删除文件delete
创建目录 mkdirs
删除文件或目录 delete
列出目录的内容 listStatus
显示文件系统的目录和文件的元数据信息 getFileStatus
ReadHdfsFile.java
1 import java.io.IOException; 2 import java.io.InputStream; 3 import java.net.URISyntaxException; 4 import java.net.URL; 5 6 import org.apache.hadoop.conf.Configuration; 7 import org.apache.hadoop.fs.FSDataInputStream; 8 import org.apache.hadoop.fs.FSDataOutputStream; 9 import org.apache.hadoop.fs.FileStatus; 10 import org.apache.hadoop.fs.FileSystem; 11 import org.apache.hadoop.fs.FsUrlStreamHandlerFactory; 12 13 import java.net.URI; 14 import org.apache.hadoop.fs.Path; 15 import org.apache.hadoop.io.IOUtils; 16 17 public class ReadHdfsFile { 18 //让Java程序识别HDFS的URL 19 static{ 20 URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory()); 21 } 22 static String fileSystemUri = "hdfs://192.168.211.130:9000"; 23 24 public static void main(String[] args) throws Exception { 25 String fileHdfsPath = "hdfs://192.168.211.130:9000/user/root/metafile2.xml"; 26 String fileHdfsPath2 = "hdfs://192.168.211.130:9000/user/root/metafile.xml"; 27 String fileHdfsPath3 = "hdfs://192.168.211.130:9000/user/root/metafile3.xml"; 28 String fileHdfsPath4 = "hdfs://192.168.211.130:9000/user/root/testCopy.txt"; 29 String localFilePath = "D://test.txt"; 30 String folderHdfsPath = "hdfs://192.168.211.130:9000/bbb"; 31 //mkdir(folderHdfsPath); 32 //readFilePrint(fileHdfsPath); 33 //judgeFileOrFolder(fileHdfsPath2); 34 //rmdir(folderHdfsPath); 35 readFileAndCopy(localFilePath,fileHdfsPath4); 36 readFilePrint(fileHdfsPath4); 37 38 } 39 /** 40 * 打印hdfs上指定的文本文件 41 * @param fileHdfsPath 42 * @throws URISyntaxException 43 * @throws IOException 44 */ 45 private static void readFilePrint(String fileHdfsPath) throws URISyntaxException, IOException { 46 FileSystem fileSystem = getFileSystem(fileSystemUri); 47 FSDataInputStream hdfsInputStream = fileSystem.open(new Path(fileHdfsPath)); 48 49 byte[] ioBuffer = new byte[1024]; 50 int readLen = hdfsInputStream.read(ioBuffer); 51 while(readLen != -1){ 52 System.out.write(ioBuffer, 0, readLen); 53 readLen = hdfsInputStream.read(ioBuffer); 54 } 55 hdfsInputStream.close(); 56 fileSystem.close(); 57 } 58 /** 59 * 得到hdfs文件系统对象 60 * @param fileSystemUri 61 * @return 62 * @throws URISyntaxException 63 * @throws IOException 64 */ 65 private static FileSystem getFileSystem(String fileSystemUri) throws URISyntaxException, 66 IOException { 67 Configuration conf = new Configuration(); 68 conf.set("fs.hdfs.impl",org.apache.hadoop.hdfs.DistributedFileSystem.class.getName()); 69 conf.set("fs.file.impl", org.apache.hadoop.fs.LocalFileSystem.class.getName()); 70 URI uri = new URI(fileSystemUri); 71 final FileSystem fileSystem = FileSystem.get(uri, conf); 72 return fileSystem; 73 } 74 75 /** 76 * 读取文件,调用fileSystem的open(path) 77 * @throws Exception 78 */ 79 private static void readFileAndCopy(String sourceFileHdfsPath,String targetFileHdfsPath) throws Exception { 80 FileSystem fileSystem = getFileSystem(fileSystemUri); 81 //获得这段代码运行的时所处的系统(如果在windows上运行就是Windows本地操作系统) 82 Configuration configuration=new Configuration(); 83 FileSystem locationFileSystem=FileSystem.getLocal(configuration); 84 85 FSDataInputStream inputStream = null; 86 FSDataOutputStream outputStream = null; 87 //输出路径 88 Path outPath = new Path(targetFileHdfsPath); 89 if(sourceFileHdfsPath.startsWith("hdfs://")){ 90 inputStream = fileSystem.open(new Path(sourceFileHdfsPath)); 91 }else{ 92 inputStream = locationFileSystem.open(new Path(sourceFileHdfsPath)); 93 } 94 //打开输出流 95 if(!(fileSystem.exists(outPath))){ 96 outputStream = fileSystem.create(outPath); 97 }else { 98 outputStream = fileSystem.append(outPath); 99 } 100 101 IOUtils.copyBytes(inputStream, outputStream, 1024, false); 102 IOUtils.closeStream(inputStream); 103 } 104 /* 105 各个参数所代表的含义: 106 in: 是FSDataInputStream类的对象,是有关读取文件的类,也就是所谓“输入流” 107 out:是FSDataOutputStream类的对象,是有关文件写入的类,也就是“输出流” 108 4096表示用来拷贝的buffer大小(buffer是缓冲区) 109 false表明拷贝完成后我们并不关闭拷贝源可拷贝目的地 110 上面inputStream和outputStream都是通过FileSystem类 111 fileSystem和fs都是FileSystem类的对象,path和block都是路径Path类的对象 112 然后IOUtils.copyBytes(in, out, 4096, false)方法实现了文件合并及上传至hdfs上 113 */ 114 115 116 /** 117 * 创建目录,调用fileSystem的mkdirs(path) 118 * @throws Exception 119 */ 120 private static void mkdir(String folderHdfsPath) throws Exception { 121 FileSystem fileSystem = getFileSystem(fileSystemUri); 122 fileSystem.mkdirs(new Path(folderHdfsPath)); 123 } 124 125 /** 126 * 删除目录,调用fileSystem的deleteOnExit(path) 127 * @throws Exception 128 */ 129 private static void rmdir(String folderHdfsPath) throws Exception { 130 FileSystem fileSystem = getFileSystem(fileSystemUri); 131 fileSystem.delete(new Path(folderHdfsPath)); 132 } 133 134 /** 135 * 遍历目录,使用FileSystem的listStatus(path) 如果要查看file状态,使用FileStatus对象 136 * @throws Exception 137 */ 138 private static void judgeFileOrFolder(String fileHdfsPath) throws Exception { 139 FileSystem fileSystem = getFileSystem(fileSystemUri); 140 FileStatus[] listStatus = fileSystem.listStatus(new Path(fileHdfsPath)); 141 for (FileStatus fileStatus : listStatus) { 142 String isDir = fileStatus.isDir() ? "目录" : "文件"; 143 String name = fileStatus.getPath().toString(); 144 System.out.println(isDir + " " + name); 145 } 146 } 147 148 }
如果代码中报AccessControlException: Permission denied:
在conf/hdfs-site.xml增加
<property>
<name>dfs.permissions</name>
<value>false</value>
</property>
中文字符集:/etc/sysconfig/i18n
作者:SummerChill 出处:http://www.cnblogs.com/DreamDrive/ 本博客为自己总结亦或在网上发现的技术博文的转载。 如果文中有什么错误,欢迎指出。以免更多的人被误导。 |