package com.wdw.hdfs;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.io.IOUtils;
import org.junit.Before;
import org.junit.Test;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
/**
练习hdfs的客户端api
*/
public class Demo {
FileSystem fs =null;
Configuration configuration = null;
@Before
public void before() throws IOException {
configuration = new Configuration();
configuration.set("fs.defaultFS","hdfs://qianfeng01/");
fs = FileSystem.get(configuration);
}
/**
* 测试:获取指定的文件的状态信息(元数据)
*/
@Test
public void testFileStatus() throws IOException {
/**
* 指定hdfs上的一个文件路径
*/
Path path = new Path("/abc/");
/**
* 调用系统的listLocatedStatus方法,与namenode进行通信,会返回指定路径的文件状态信息
*/
RemoteIterator<LocatedFileStatus> filestatus = fs.listLocatedStatus(path);
/**
* 迭代取出里面的内容
*/
while(filestatus.hasNext()){
LocatedFileStatus next = filestatus.next();
System.out.println("所属组:"+next.getGroup());
System.out.println("拥有者:"+next.getOwner());
System.out.println("块大小:"+next.getBlockSize());
System.out.println("最后一次访问时间:"+next.getAccessTime());
System.out.println("文件总长度:"+next.getLen());
System.out.println("副本数:"+next.getReplication());
System.out.println("文件路径:"+next.getPath());
/**
* 获取文件的所有块信息
* 比如:文件有两个块,那么数组中应该有两个块元素信息
*/
BlockLocation[] blockLocations = next.getBlockLocations();
for (BlockLocation loc:blockLocations){
/**
* 一个块的信息
*/
System.out.println("当前块的主机列表:"+Arrays.toString(loc.getHosts()));
System.out.println("当前块的长度:"+loc.getLength());
System.out.println("当前块的名称列表:"+Arrays.toString(loc.getNames()));
System.out.println("当前块的长度:"+Arrays.toString(loc.getTopologyPaths()));
System.out.println("------------------黄金分割线-------------------------");
}
System.out.println("----------------一个文件结束--------------------");
}
}
/**
* 使用IOUtils工具类来进行下载操作
*/
@Test
public void testIOUtilsDown() throws IOException {
/**
* 指定hdfs上的一个要下载的文件,获取输入流对象
*
* 会请求namenode,进行读取操作,校验通过,会返回一个输入流对象
*/
FSDataInputStream fsin = fs.open(new Path("/input1/eeeeee"));
/**
* 指定本地文件系统的一个路径,获取输出流对象
*/
FileOutputStream fos = new FileOutputStream("D:/w.avi");
/**
* 使用工具类进行拷贝操作
*/
IOUtils.copyBytes(fsin,fos,configuration);
IOUtils.closeStream(fsin);
IOUtils.closeStream(fos);
System.out.println("下载成功");
}
/**
* 使用IOUtils工具类来进行上传操作
*/
@Test
public void testIOUtilsUP() throws IOException {
/**
* 获取一个字节输入流,用于指定本地磁盘的一个文件
*/
FileInputStream fis = new FileInputStream("D:/data/01.csv");
/**
* 指定hdfs上的一个路径
*/
Path hdfsPath = new Path("/input1/eeeeee");
/**
* 调用系统对象的create方法 与namenode进行rpc协议通信,要求创建一个文件,
* 成功校验后会返回一个输出流对象
*/
FSDataOutputStream fsout = fs.create(hdfsPath);
/**
* 调用IOUtils工具类里的复制流的方法
* 将输入流里的数据,复制到输出流里
*/
IOUtils.copyBytes(fis,fsout,configuration);
/**
* 关闭输入输出流对象
*/
IOUtils.closeStream(fis);
IOUtils.closeStream(fsout);
System.out.println("上传成功");
}
/**
* 测试:对hdfs系统上的文件进行重命名操作
*/
@Test
public void testRename() throws IOException {
/**
* 要指定一个hdfs上的文件名
*/
Path oldpath = new Path("/abc/e");
/**
* 指定一个新的名字
*/
Path newpath = new Path("/abc/eeeeee");
/**
* 调用rename方法
*/
fs.rename(oldpath,newpath);
fs.close();
System.out.println("重命名成功");
}
/**
* 测试: 在hdfs上远程删除一个目录
*/
@Test
public void testDelete() throws IOException {
/**
* 在hdfs上指定一个要删除的目录
*/
Path hdfsPath = new Path("/bbbb");
/**
* 调用系统对象的删除目录的方法
*/
fs.delete(hdfsPath,true);
fs.close();
System.out.println("删除成功");
}
/**
* 测试: 在hdfs上远程创建一个目录
*/
@Test
public void testMkdir() throws IOException {
/**
* 在hdfs上指定一个要创建的目录
*/
Path hdfsPath = new Path("/data");
/**
* 调用系统对象的创建目录的方法
*/
fs.mkdirs(hdfsPath);
fs.close();
System.out.println("创建成功");
}
/**
* 测试 从hdfs文件系统上下载一个文件到本地文件系统
*
*
* 修改win平台的域名映射文件
* C:\Windows\System32\drivers\etc\hosts
*
*/
@Test
public void testDownload() throws IOException {
/**
* 1. 获取配置对象
*/
Configuration configuration = new Configuration();
configuration.set("fs.defaultFS","hdfs://hadoop001/");
/**
* 2. 获取分布式文件系统对象
*/
FileSystem fileSystem = FileSystem.get(configuration);
/**
* 3. 指定一个hdfs上的路径
*/
Path hdfsPath = new Path("/input/VERSION");
/**
* 4. 指定一个本地文件系统的路径
*/
Path localPath = new Path("D:/a");
/**
* 5. 调用文件系统对象的下载方法
*/
fileSystem.copyToLocalFile(hdfsPath,localPath);
fileSystem.close();
System.out.println("下载成功");
}
/**
* 测试一下,把本地的文件上传到hdfs中
*/
@Test
public void testUploadFile() throws IOException {
/**
* 1. 获取配置对象
*/
Configuration conf = new Configuration();
conf.set("fs.defaultFS","hdfs://192.168.10.101:8020");
System.setProperty("HADOOP_USER_NAME","root");
/**
* 2. 获取分布式文件系统对象
*/
FileSystem fs = FileSystem.get(conf);
/**
* 3.指定一个本地文件系统的一个文件路径
*/
Path localPath = new Path("D:/data/01.csv");
/**
* 4.指定一个hdfs系统的一个文件路径
*/
Path hdfsPath = new Path("/input4/input5/");
/**
* 5. 调用系统对象的上传方法
*/
fs.copyFromLocalFile(localPath,hdfsPath);
fs.close();
System.out.println("上传成功");
}
/**
* 测试一下FileSystem的子类,
* 1. 本地文件系统对象:org.apache.hadoop.fs.LocalFileSystem
* 2. 分布式文件系统对象:org.apache.hadoop.hdfs.DistributedFileSystem 此对象可以和namenode进行通信
*/
@Test
public void testFileSystem() throws IOException {
/**
* 获取hdfs的默认配置信息 core-default.xml hdfs-default.xml mapred-default.xml yarn-default.xml
* 构造器里的逻辑 封装了读取这些信息的操作
*/
Configuration conf = new Configuration();
/**
* 修改属性fs.defaultFS的默认值file:/// 为hdfs://ip:port
*/
conf.set("fs.defaultFS","hdfs://192.168.10.101:8020");
/**
* 获取文件对象,使用FileSystem的静态方法get()
*
* get方法就是用于在本地的内存中创建一个分布式文件系统对象,根本没有连接namenode
*/
FileSystem fileSystem = FileSystem.get(conf);
/**
* 打印一下对象的类型
*/
System.out.println(fileSystem.getClass().getName());
}
}
stschqlxzwsl
最新推荐文章于 2024-09-06 20:24:50 发布