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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值