3 HDFS的客户端操作
3.1 客户端环境准备
步骤1:安装hadoop3.1.3到Windows系统
解压编译好的hadoop包,解压到无空格非中文路径。
步骤2:配置环境变量
HADOOP_HOME=/windows下hadoop的家目录
PATH=%HADOOP_HOME%/bin
步骤3:查看windows下hadoop是否可以使用
打开cmd输入hadoop;然后重启电脑
步骤4:创建一个maven工程,导入依赖
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.12.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>3.1.3</version>
</dependency>
</dependencies>
步骤5:添加日志依赖
在/src/main/resources目录下创建一个log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error" strict="true" name="XMLConfig">
<Appenders>
<!-- 类型名为Console,名称为必须属性 -->
<Appender type="Console" name="STDOUT">
<!-- 布局为PatternLayout的方式,
输出样式为[INFO] [2018-01-22 17:34:01][org.test.Console]I'm here -->
<Layout type="PatternLayout"
pattern="[%p] [%d{yyyy-MM-dd HH:mm:ss}][%c{10}]%m%n" />
</Appender>
</Appenders>
<Loggers>
<!-- 可加性为false -->
<Logger name="test" level="info" additivity="false">
<AppenderRef ref="STDOUT" />
</Logger>
<!-- root loggerConfig设置 -->
<Root level="info">
<AppenderRef ref="STDOUT" />
</Root>
</Loggers>
</Configuration>
3.2 HDFS的API操作
创建文件夹
@Test
public void testMkdir() throws URISyntaxException, IOException, InterruptedException {
//创建hdfs文件系统对象
FileSystem fileSystem = FileSystem.get(
new URI("hdfs://hadoop102:9820"),
new Configuration(),
"atguigu");
//操作hdfs文件系统
fileSystem.mkdirs(new Path("/jjj"));
//关闭hdfs
fileSystem.close();
}
创建hdfs文件系统对象,其中URI是hdfs的资源地址,选择9820端口。
configuration是配置文件,默认是集群配置的文件;可以在idea中新建配置文件(如hdfs-site.xml);可以在代码中编辑配置项。
设置文件副本数
设置配置文件中配置项的优先级:
代码 > idea中配置文件 > 集群配置文件
集群默认副本数是3
在/src/main/resources目录下创建一个hdfs-site.xml
<configuration>
<!-- nn web端访问地址-->
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
</configuration>
这时创建文件,副本数就是2了。
在代码中修改配置项的hdfs副本数
@Test
public void testReplication() throws URISyntaxException, IOException, InterruptedException {
Configuration configuration = new Configuration();
configuration.set("dfs.replication", "1");
FileSystem fileSystem = FileSystem.get(
new URI("hdfs://hadoop102:9820"),
configuration,
"atguigu");
fileSystem.create(new Path("/test2.md"));
fileSystem.close();
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LH4g5zp3-1603002915333)(hdfs.assets/image-20201012200806318.png)]
①文件上传
为了简单操作,将创建hdfs对象放到Before中,将关闭hdfs放到After中;将FileSystem作为参数提取出来
FileSystem fs;
@Before
public void createHDFS() throws URISyntaxException, IOException, InterruptedException {
fs = FileSystem.get(new URI("hdfs://hadoop102:9820"), new Configuration(), "atguigu");
}
@After
public void close() throws IOException {
fs.close();
}
@Test
public void testCopyFromLocalFile() throws IOException {
fs.copyFromLocalFile(new Path("d:/file1.txt"), new Path("/File1.md"));
}
②文件下载
// 2 执行下载操作
// boolean delSrc 指是否将原文件删除
// Path src 指要下载的文件路径
// Path dst 指将文件下载到的路径
// boolean useRawLocalFileSystem 是否开启文件校验
fs.copyToLocalFile(false, new Path("/banzhang.txt"), new Path(“e:/banhua.txt”), true);
//默认不删除原文件,默认不开启文件校验(下载到本地还有一个校验文件)
@Test
public void testCopyToLocalFile() throws IOException {
fs.copyToLocalFile(new Path("/README.txt"), new Path("d:/"));
}
//这样就没有删除原文件,也不会下载校验文件到本地。
@Test
public void testCopyToLocalFile() throws IOException {
fs.copyToLocalFile(false, new Path("/README.txt"), new Path("d:/"), true);
}
③文件更名和移动
移动的同时可以改名
@Test
public void testMoveFile() throws IOException {
fs.rename(new Path("/File1.md"), new Path("/dir/file2.md"));
}
④HDFS文件详情
RemoteIterator Iterator = fs.listFiles(Path path, boolean b);
boolean是否递归显示文件信息。返回一个迭代器
@Test
public void testFileDetail() throws IOException {
//返回一个文件列表的迭代器
RemoteIterator<LocatedFileStatus> locatedFileStatusRemoteIterator = fs.listFiles(new Path("/"), false);
while (locatedFileStatusRemoteIterator.hasNext()){
System.out.println("===================================");
System.out.println(locatedFileStatusRemoteIterator.next());
}
}
/*输出结果
HdfsLocatedFileStatus{path=hdfs://hadoop102:9820/README.txt; isDirectory=false; length=1366; replication=3; blocksize=134217728; modification_time=1602469037365; access_time=1602505180131; owner=atguigu; group=supergroup; permission=rw-rw-rw-; isSymlink=false; hasAcl=false; isEncrypted=false; isErasureCoded=false}
*/
查看locatedFileStatusRemoteIterator.next()内的部分信息。
@Test
public void testFileDetail() throws IOException {
RemoteIterator<LocatedFileStatus> locatedFileStatusRemoteIterator = fs.listFiles(new Path("/"), false);
while (locatedFileStatusRemoteIterator.hasNext()){
System.out.println("===================================");
LocatedFileStatus fileStatus = locatedFileStatusRemoteIterator.next();
//获取文件名
System.out.println(fileStatus.getPath().getName());
//获取文件长度
System.out.println(fileStatus.getLen());
//获取文件权限
System.out.println(fileStatus.getPermission());
//获取文件分组
System.out.println(fileStatus.getGroup());
//获取文件存储的块信息
BlockLocation[] blockLocations = fileStatus.getBlockLocations();
for (BlockLocation blockLocation : blockLocations) {
String[] hosts = blockLocation.getHosts();
System.out.println(Arrays.toString(hosts));
}
}
}
⑤HDFS文件和文件夹判断
@Test
public void testFileDetail1() throws IOException {
FileStatus[] fileStatuses = fs.listStatus(new Path("/"));
for (FileStatus fileStatus : fileStatuses) {
System.out.println("============================");
//获取文件名
System.out.println(fileStatus.getPath().getName());
//获取文件长度
System.out.println(fileStatus.getLen());
//获取文件权限
System.out.println(fileStatus.getPermission());
//获取文件分组
System.out.println(fileStatus.getGroup());
//获取文件存储的块的大小(只能获得大小)
System.out.println(fileStatus.getBlockSize());
}
}
HdfsLocatedFileStatus{path=hdfs://hadoop102:9820/tmp/hadoop-yarn/staging/history/done_intermediate/atguigu/job_1602462434358_0001.summary; isDirectory=false; length=442; replication=3; blocksize=134217728; modification_time=1602462463740; access_time=1602462463704; owner=atguigu; group=supergroup; permission=rwxrwx—; isSymlink=false; hasAcl=false; isEncrypted=false; isErasureCoded=false}
HdfsLocatedFileStatus{path=hdfs://hadoop102:9820/README.txt; isDirectory=false; length=1366; replication=3; blocksize=134217728; modification_time=1602469037365; access_time=1602469037082; owner=atguigu; group=supergroup; permission=rw-r–r--; isSymlink=false; hasAcl=false; isEncrypted=false; isErasureCoded=false}
父类:FileStatus
子类:RemoteIterator,有块信息的一些api