一、公用代码提
在操作HDFS之前我们可以获取文件系统对象,由于每次操作都需要获取文件对象,并且结束要关闭文件对象,所以我们可以把这一部分提取出来,作为JUNIT的After及Before部分
1、全局属性定义
//操作hdfs使用的用户名
private static String USER = HdfsTest.class.getName();
//全局文件系统对象
private FileSystem fs = null;
2、 Before
@Before
public void initFileSystem(){
//创建配置对象
Configuration conf = new Configuration();
try {
//获取文件系统对象
fs = FileSystem.get(new URI("hdfs://bigdata111:9000"), conf, USER);
} catch (Exception e) {
System.err.println("获取文件系统失败:"+e.getMessage());
}
}
3、 After
@After
public void close() {
try {
//关闭文件系统
fs.close();
System.out.println("文件系统关闭成功");
} catch (IOException e) {
System.err.println("文件系统关闭失败:"+e.getMessage());
}
}
二、 上传文件
1、 代码
/**
* 上传文件
*/
@Test
public void put(){
try {
fs.copyFromLocalFile(new Path("F:\\软件\\密钥.txt"), new Path("/密钥.txt"));
} catch (IOException e) {
System.err.println("复制失败:"+e.getMessage());
}
}
2、 结果
三、 下载文件
1、 代码
/**
* 下载
*/
@Test
public void download(){
// delSrc: 是否删除源文件 src: 源路径 dst: 目标路径 useRawLocalFileSystem: 校验文件
try {
fs.copyToLocalFile(true, new Path("/密钥.txt"), new Path("F:\\软件\\密钥2.txt"), false);
} catch (IOException e) {
System.err.println("下载失败:"+e.getMessage());
}
}
2、 结果
hdfs中的文件被删除
四、 创建目录
1、 代码
/**
* 创建目录
*/
@Test
public void mkdir(){
try {
fs.mkdirs(new Path("/"+USER+"/test"));
} catch (IOException e) {
System.err.println("目录创建失败:"+e.getMessage());
}
}
2、 结果
五、 删除文件
1、 代码
/**
* 删除文件
*/
@Test
public void delFile(){
try {
// pathString: 删除路径 b: 递归删除
fs.delete(new Path("/"+USER+"/test2"),true);
} catch (IOException e) {
System.err.println("删除目录创建失败:"+e.getMessage());
}
}
2、 结果
删除前
删除后
六、 遍历文件
1、 代码
/**
* 遍历文件,获取详情信息
*/
@Test
public void listFiles(){
try {
// pathString: 路径 recursive: 是否遍历
RemoteIterator<LocatedFileStatus> lfs = fs.listFiles(new Path("/"), true);
while (lfs.hasNext()){
LocatedFileStatus lf = lfs.next();
System.out.println("路径: "+lf.getPath());
System.out.println("大小: "+formatSize(lf.getLen()));
System.out.println("权限: "+lf.getPermission());
System.out.println("访问时间: "+lf.getAccessTime());
System.out.println("备份数: "+lf.getReplication());
System.out.println("是文件: "+(lf.isFile()?"是":"否"));
System.out.println("是目录: "+(lf.isDirectory()?"是":"否"));
BlockLocation[] bls = lf.getBlockLocations();
int i = 1;
for (BlockLocation bl: bls) {
String name = "\t块"+i;
System.out.println(name+"的信息: ");
System.out.println("\t\t偏移量: "+bl.getOffset());
System.out.println("\t\t主机:");
String[] hosts = bl.getHosts();
for(String host : hosts){
System.out.println("\t\t\t"+host);
}
i++;
}
System.out.println("===========黄金分割线===========");
}
} catch (IOException e) {
System.err.println("遍历失败:"+e.getMessage());
}
}
/**
* 将byte数值格式化成方便看的数
* @param byteSize
* @return
*/
private String formatSize(long byteSize){
String[] units = new String[]{"B","BK","MB","GB","TB"};
//保留两位小数
DecimalFormat df = new DecimalFormat("#.00");
int unitIndex = 0;
double res= byteSize;
while (res > 1024){
res = res / 1024.0;
unitIndex++;
}
return df.format(res) + units[unitIndex];
}
2、 结果
七、 IO流上传
1、 代码
/**
* IO流上传
*/
@Test
public void putByIO(){
try {
InputStream is = new FileInputStream(new File("F:\\软件\\密钥.txt"));
OutputStream os = fs.create(new Path("/"+USER+"/123.txt"));
IOUtils.copyBytes(is, os, 5*1024*1024, true);
} catch (Exception e) {
System.err.println("上传失败: "+e.getMessage());
}
}
2、 结果
八、 IO流下载
1、 代码
/**
* IO流下载
*/
@Test
public void getByIO(){
try {
InputStream is = fs.open(new Path("/"+USER+"/123.txt"));
OutputStream os = new FileOutputStream(new File("F:\\软件\\密钥3.txt"));
IOUtils.copyBytes(is, os, 5*1024*1024, true);
} catch (Exception e) {
System.err.println("上传失败: "+e.getMessage());
}
}
2、 结果
九、 使用IO流下载所有块
1、 代码
/**
* 定位读取, 读取所有块
*/
@Test
public void getAllBlock(){
try {
Path path = new Path("/zh-hans_windows_xp_professional_with_service_pack_3_x86_cd_x14-80404.iso");
FileStatus status = fs.getFileStatus(path);
// 文件总大小
long totalSize = status.getLen();
//块的大小
long blockSize = status.getBlockSize();
//当前偏移量
long seek = 0;
//输入流
FSDataInputStream is = fs.open(path);
while (seek < totalSize){
//构造输出流
OutputStream os = new FileOutputStream(new File("F:\\软件\\"+(seek/blockSize)));
is.seek(seek);
//定义缓冲区
byte[] buff = new byte[1024*1024];
if(totalSize - seek >= blockSize) {
for (int i = 0; i < blockSize / (1024*1024); i++) {
is.read(buff);
os.write(buff);
}
}else{
IOUtils.copyBytes(is,os,1024*1024,false);
}
seek += blockSize;
os.close();
}
is.close();
} catch (IOException e) {
System.err.println("获取失败: "+e.getMessage());
}
}
2、 结果
在windows中使用type将文件追加进另一个文件,来合并这些块
打开合并后的文件,检验下载成功