1. 参数说明
-
FileSystem: 文件系统的抽象基类
① FileSystem的实现取决于fs.defaultFS的配置
② 有两种实现:
LocalFileSystem: 本地文件系统 fs.defaultFS=file:///
DistributedFileSystem: 分布式文件系统 fs.defaultFS=hdfs://xxx:9000
③ 声明用户身份:
FileSystem fs = FileSystem.get(new URI(“hdfs://hadoop101:9000”), conf, “wuyik”); -
Configuration : 功能是读取配置文件中的参数
Configuration在读取配置文件的参数时,根据文件名,从类路径按照顺序读取配置文件,先读取 xxx-default.xml,再读取xxx-site.xml
Configuration类一加载,就会默认读取8个配置文件,将8个配置文件中所有属性,读取到一个Map集合中,也提供了set(name,value),来手动设置用户自定义的参数! -
FileStatus
代表一个文件的状态(文件的属性信息) -
offset和length
offset是偏移量: 指块在文件中的起始位置
length是长度,指块大小举例:sts.zip 390M length offset blk1: 0-128M 128M 0 blk2: 128M-256M 128M 128M ... blk4: 384M-390M 6M 384M
-
LocatedFileStatus
LocatedFileStatus是FileStatus的子类,除了文件的属性,还有块的位置信息。
2. 创建客户端对象
public void init() throws IOException, URISyntaxException, InterruptedException {
// 创建一个客户对象
Configuration conf = new Configuration();
//此方式需要配置core-site.xml
// FileSystem fs = FileSystem.get(conf);
//此方式使用默认用户登录
fs = FileSystem.get(new URI("hdfs://hadoop101:9000"), conf);
// FileSystem fs = FileSystem.get(new URI("hdfs://hadoop101:9000"), conf, "wuyik");
}
3. 创建目录
public void testMkdir() throws IllegalArgumentException, IOException {
//创建目录
fs.mkdirs(new Path("/eclipse1"));
}
4. 上传文件
public void testUpload() throws IllegalArgumentException, IOException {
//文件的上传
fs.copyFromLocalFile(false, true, new Path("e:/ex/video.zip"), new Path("/"));
}
5. 文件的下载
public void testDownload() throws IllegalArgumentException, IOException {
//文件的下载
fs.copyToLocalFile(false, new Path("/wcinput1"), new Path("e:/ex/"), false);
}
6. 文件的删除
public void testDelete() throws IllegalArgumentException, IOException {
//文件的删除
//第二个参数设置是否递归
fs.delete(new Path("/eclipse1"), true);
}
7. 文件的重命名
public void testRename() throws Exception {
//文件的重命名
fs.rename(new Path("/eclipse"), new Path("/eclipsedir"));
}
8. 判断文件是否为文件/文件夹
public void testIsFileDirectory() throws Exception {
Path path = new Path("/wcinput");
// //判断文件是否为文件/文件夹
// 使用isDirectory(path)、fs.isFile(path)方法
// System.out.println("是否为文件夹:" + fs.isDirectory(path));
// System.out.println("是否为文件:" + fs.isFile(path));
// 使用getFileStatus(path)方法
// FileStatus status = fs.getFileStatus(path);
// System.out.println(status.getPath().getName() + "是否为文件夹:" + status.isDirectory());
// System.out.println(status.getPath().getName() + "是否为文件:" + status.isFile());
//使用listStatus(path)方法 适用于查看目录下的多个文件/文件夹
FileStatus[] list = fs.listStatus(path);
for (FileStatus status : list) {
Path filePath = status.getPath();
System.out.println(filePath.getName() + "是否为文件夹:" + status.isDirectory());
System.out.println(filePath.getName() + "是否为文件:" + status.isFile());
}
}
9. 查看文件详情
public void testGetBlockInfomation() throws Exception {
Path path = new Path("/idea.rar");
RemoteIterator<LocatedFileStatus> listLocatedStatus = fs.listLocatedStatus(path);
while(listLocatedStatus.hasNext()) {
LocatedFileStatus status = listLocatedStatus.next();
//调用status的方法来查看文件信息
System.out.println(status.getGroup());
System.out.println(status.getOwner());
//显示块信息
BlockLocation[] blockLocations = status.getBlockLocations();
for (BlockLocation blockLocation : blockLocations) {
System.out.println(blockLocation);
}
}
}
10. 上传自定义大小的文件
public void testCustomUpLoad() throws Exception {
//声明两个Path和两个文件系统
Path srcPath = new Path("e:/ex/java-core.pdf");
Path destPath = new Path("/java-core.pdf");
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop101:9000"), conf);
FileSystem localFs = FileSystem.get(new Configuration());
//通过本地文件系统的输入流读取文件
FSDataInputStream is = localFs.open(srcPath);
//通过HDFS的分布式文件系统的输出流写入文件
FSDataOutputStream os = fs.create(destPath, true);
//流的拷贝(10M)
//1k
byte[] buffer = new byte[1024];
for (int i = 0; i < 1024 * 10; i++) {
is.read(buffer);
os.write(buffer);
}
//关闭流
IOUtils.closeStream(os);
IOUtils.closeStream(is);
}
11. 下载自定义大小的文件
public void testCustomDownLoad() throws Exception {
//声明两个Path和两个文件系统
Path srcPath = new Path("/java-core.pdf");
Path destPath = new Path("e:/ex/java.pdf");
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop101:9000"), conf);
FileSystem localFs = FileSystem.get(new Configuration());
//通过HDFS的分布式文件系统的输入流读取文件
FSDataInputStream is = fs.open(srcPath);
//通过本地文件系统的输出流写入文件
FSDataOutputStream os = localFs.create(destPath, true);
//流的拷贝(10M)
//1k
byte[] buffer = new byte[1024];
for (int i = 0; i < 1024 * 10; i++) {
is.read(buffer);
os.write(buffer);
}
//关闭流
IOUtils.closeStream(os);
IOUtils.closeStream(is);
}
12. 实现大文件的下载(下载多个块)
public void init() throws IOException, URISyntaxException, InterruptedException {
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop101:9000"), conf);
FileSystem localFs = FileSystem.get(new Configuration());
}
public void testFirstBlock() throws Exception {
//声明两个Path和两个文件系统
Path srcPath = new Path("/video.zip");
Path destPath = new Path("e:/ex/firstBlock");
//通过HDFS的分布式文件系统的输入流读取文件
FSDataInputStream is = fs.open(srcPath);
//通过本地文件系统的输出流写入文件
FSDataOutputStream os = localFs.create(destPath, true);
//流的拷贝(128M)
//1k
byte[] buffer = new byte[1024];
for (int i = 0; i < 1024 * 128; i++) {
is.read(buffer);
os.write(buffer);
}
//关闭流
IOUtils.closeStream(os);
IOUtils.closeStream(is);
}
public void testSecondBlock() throws Exception {
//声明两个Path和两个文件系统
Path srcPath = new Path("/video.zip");
Path destPath = new Path("e:/ex/secondBlock");
//通过HDFS的分布式文件系统的输入流读取文件
FSDataInputStream is = fs.open(srcPath);
//通过本地文件系统的输出流写入文件
FSDataOutputStream os = localFs.create(destPath, true);
is.seek(1024 * 1024 * 128);
//流的拷贝(128M)
//1k
byte[] buffer = new byte[1024];
for (int i = 0; i < 1024 * 128; i++) {
is.read(buffer);
os.write(buffer);
}
//关闭流
IOUtils.closeStream(os);
IOUtils.closeStream(is);
}
public void testFinalBlock() throws Exception {
//声明两个Path和两个文件系统
Path srcPath = new Path("/video.zip");
Path destPath = new Path("e:/ex/finalBlock");
//通过HDFS的分布式文件系统的输入流读取文件
FSDataInputStream is = fs.open(srcPath);
//通过本地文件系统的输出流写入文件
FSDataOutputStream os = localFs.create(destPath, true);
is.seek(1024 * 1024 * 128 * 2);
//流的拷贝
//使用IOUtils中的copyBytes
//copyBytes(输入流,输出流,4096,是否关流)
IOUtils.copyBytes(is, os, 4096, true);
}
调用以上三个方法在本地目录下载了三个文件,最后通过cmd窗口进行文件的合并
secondBlock >> firstBlock
finalBlock >> firstBlock
执行完毕,更改firstBlock的扩展名,即完成了大文件的下载。