Appearance
创建Maven工程,引入依赖,注意版本号保持和Hadoop安装的版本一致。
xml
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>3.2.3</version>
</dependency>
在D盘新建user.txt
文件,使用java代码上传到HDFS中
java
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
public static void main(String[] args) throws IOException {
// 创建一个配置对象
Configuration conf = new Configuration();
// 指定HDFS地址
conf.set("fs.defaultFS","hdfs://192.168.133.101:9000");
// 获取操作HDFS的对象
FileSystem fileSystem = FileSystem.get(conf);
// 获取HDFS文件系统的输出流
FSDataOutputStream fos = fileSystem.create(new Path("/user.txt"));
// 获取本地文件输出流
FileInputStream fis = new FileInputStream("D:\\user.txt");
// 上传文件
IOUtils.copyBytes(fis,fos,1024,true);
}
执行代码,发现报错,提示权限拒绝,说明windows中的这个用户没有权限向HDFS中写入数据。
解决办法有两个,第一种是去掉hdfs的用户权限检验机制,通过在hdfs-site.xml中配置dfs.permissions.enabled为false即可;第二种是把代码打包到linux中执行。这里为了测试方便,我们采用第一种方法
shell
[root@bigdata01 hadoop-3.2.3]# sbin/stop-all.sh #先停止Hadoop集群
[root@bigdata01 hadoop-3.2.3]# vi etc/hadoop/hdfs-site.xml
修改后的文件内容如下
xml
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>bigdata01:50090</value>
</property>
<property>
<name>dfs.permissions.enabled</name>
<value>false</value>
</property>
</configuration>
然后再重新运行Hadoop,执行代码测试能够正常执行。
slf4j日志配置
我们在执行代码的时候会发现输出了很多红色的警告信息,虽然不影响代码执行,但是看起来很碍眼。
xml
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.3</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>2.0.3</version>
</dependency>
resource目录下新建log4j.properties
文件
properties
log4j.rootLogger=info,stdout
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
log4j.logger.org.apache.hadoop.util.NativeCodeLoader=ERROR
IDEA报错解决
java
[WARN ] 2022-10-11 21:36:13,655 method:org.apache.hadoop.util.Shell.<clinit>(Shell.java:693)
Did not find winutils.exe: {}
java.io.FileNotFoundException: java.io.FileNotFoundException: HADOOP_HOME and hadoop.home.dir are unset. -see https://wiki.apache.org/hadoop/WindowsProblems
at org.apache.hadoop.util.Shell.fileNotFoundException(Shell.java:548)
at org.apache.hadoop.util.Shell.getHadoopHomeDir(Shell.java:569)
at org.apache.hadoop.util.Shell.getQualifiedBin(Shell.java:592)
出现以上错误不要慌,windows也需要安装Hadoop才能用,直接复制错误搜索安装步骤安装Hadoop即可,输入hadoop version
出现以下字符代表正常
shell
PS D:\Desktop> hadoop version
Hadoop 3.2.3
Source code repository https://github.com/apache/hadoop -r abe5358143720085498613d399be3bbf01e0f131
Compiled by ubuntu on 2022-03-20T01:18Z
Compiled with protoc 2.5.0
From source with checksum 39bb14faec14b3aa25388a6d7c345fe8
This command was run using /D:/develop/hadoop-3.2.3/share/hadoop/common/hadoop-common-3.2.3.jar
文件上传与下载
java
public static void main(String[] args) throws IOException {
// 创建一个配置对象
Configuration conf = new Configuration();
// 指定HDFS地址
conf.set("fs.defaultFS","hdfs://192.168.133.101:9000");
// 获取操作HDFS的对象
FileSystem fileSystem = FileSystem.get(conf);
// 调用文件上传与下载方法
put(fileSystem);
get(fileSystem);
}
文件上传
java
private static void put(FileSystem fileSystem) throws IOException {
// 获取HDFS文件系统的输出流
FSDataOutputStream fos = fileSystem.create(new Path("/user.txt"));
// 获取本地文件输出流
FileInputStream fis = new FileInputStream("D:\\user.txt");
// 上传文件:通过工具类把输入流拷贝到输出流里面,实现本地文件上传到HDFS
IOUtils.copyBytes(fis,fos,1024,true);
}
文件下载
java
private static void get(FileSystem fileSystem) throws IOException {
// 获取HDFS文件系统的输出流
FSDataInputStream fis = fileSystem.open(new Path("/README.txt"));
// 获取本地文件输出流
FileOutputStream fos = new FileOutputStream("D:\\README.txt");
IOUtils.copyBytes(fis,fos,1024,true);
}
文件删除
目录也可以删除,如果需要递归删除,第二个参数需要设置为true,如果是删除文件或空目录,第二个参数会被忽略
java
private static void del(FileSystem fileSystem) throws IOException {
// 目录也可以删除,如果需要递归删除,第二个参数需要设置为true,如果是删除文件或空目录,第二个参数会被忽略
boolean flag = fileSystem.delete(new Path("/user.txt"), true);
if (flag) {
System.out.println("删除成功");
}else {
System.err.println("删除失败");
}
}