HDFS 的 API 操作
1 配置 Windows 下 Hadoop 环境
在 windows 系统需要配置 hadoop 运行环境,否则直接运行代码会出现以下问题:
缺少 winutils.exe
Could not locate executable null \bin\winutils.exe in the hadoop binaries
复制代码
缺少 hadoop.dll
Unable to load native-hadoop library for your platform… using builtin-Java classes where applicable
复制代码
步骤:
第一步:将 hadoop-2.6.0-cdh5.14.0 文件夹拷贝到一个没有中文没有空格的路径下面
第二步:在 windows 上面配置 hadoop 的环境变量: HADOOP_HOME,并将 %HADOOP_HOME%\bin 添加到 path 中
第三步:把 hadoop2.7.5 文件夹中 bin 目录下的 hadoop.dll 文件放到系统盘: C:\Windows\System32 目录
第四步:关闭 windows 重启
无法通过浏览器下载 hdfs 中文件:
主要的原因: window 的 hosts 文件没有配置映射关系
windows 的 hosts 文件: C:\Windows\System32\drivers\etc
在这个文件下, 需要将linux的hosts文件中配置的映射关系, 添加到window的hosts文件中
复制代码
如果 window 的 hosts 文件, 不允许修改, 拉出去, 改完以后, 在拖回来
如果打开这个路径, 发现如果没有 hosts 文件, 找别人借一个过来
打开 CMD 检测 hosts 文件配置是否 OK: ping 别名
2 导入 Maven 依赖
由于 cdh 版本的所有的软件涉及版权的问题,所以并没有将所有的 jar 包托管到 maven 仓库当中去,而是托管在了 CDH 自己的服务器上面,所以我们默认去 maven 的仓库下载不到,需要自己手动的添加 repository 去 CDH 仓库进行下载,以下两个地址是官方文档说明,请仔细查阅
https://www.cloudera.com/documentation/enterprise/release-notes/topics/cdh_vd_cdh5_maven_repo.html
https://www.cloudera.com/documentation/enterprise/release-notes/topics/cdh_vd_cdh5_maven_repo_514x.html
<repositories>
<repository>
<id>cloudera</id>
<url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.6.0-mr1-cdh5.14.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.6.0-cdh5.14.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.6.0-cdh5.14.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-core</artifactId>
<version>2.6.0-cdh5.14.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<!-- <verbal>true</verbal>-->
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>true</minimizeJar>
</configuration>
</execution>
</executions>
</plugin>
<!-- <plugin>
<artifactId>maven-assembly-plugin </artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>cn.itcast.hadoop.db.DBToHdfs2</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>-->
</plugins>
</build>
复制代码
3 使用 url 方式访问数据
// 将HDFS中一个文件拷贝到本地目录下
@Test
public void urlConnect() throws Exception{
//1. 注册HDFS
URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
//2. 获取输入流 : HDFS socket流
InputStream in = new URL("hdfs://node01:8020/a/b/test.txt").openStream();
//3. 获取输出流
FileOutputStream out = new FileOutputStream(new File("E:\\HDFS\\a.txt"));
//3. 获取输出流
IOUtils.copy(in,out);
//4. 释放资源
IOUtils.closeQuietly(out);
IOUtils.closeQuietly(in);
}
复制代码
如果执行出现以下错误,可以参见 1.1 如何解决,也可以不用理会,不会影响程序的执行。记得配置完成环境变量之后重启开发工具
4 使用文件系统方式访问数据
4.1 涉及的主要类
在 Java 中操作 HDFS, 主要涉及以下 Class:
FileSystem fs = FileSystem.get(conf)
复制代码
get
方法从 conf
中的一个参数 fs.defaultFS
的配置值判断具体是什么类型的文件系统
如果我们的代码中没有指定 fs.defaultFS
, 并且工程 ClassPath 下也没有给定相应的配置, conf
中的默认值就来自于 Hadoop 的 Jar 包中的 core-default.xml
默认值为 file:///
, 则获取的不是一个 DistributedFileSystem 的实例, 而是一个本地文件系统的客户端对象
4.2 获取 FileSystem 的几种方式
@Test
public void getFileSystem1() throws Exception{
//1. 获取FileSystem
Configuration conf = new Configuration();
conf.set("fs.defaultFS","hdfs://node01:8020");
FileSystem fileSystem = FileSystem.get(conf);
System.out.println(fileSystem.toString());
}
复制代码
@Test
public void getFileSystem2() throws Exception{
//1. 获取FileSystem
FileSystem fileSystem = FileSystem.get(new URI("hdfs://node01:8020"), new Configuration());
System.out.println(fileSystem);
}
复制代码
@Test
public void getFileSystem3() throws Exception{
//1. 获取FileSystem
Configuration conf = new Configuration();
conf.set("fs.defaultFS","hdfs://node01:8020");
FileSystem fileSystem = FileSystem.newInstance(conf);
System.out.println(fileSystem);
}
复制代码
@Test
public void getFileSystem4() throws Exception{
//1. 获取FileSystem
FileSystem fileSystem = FileSystem.newInstance(new URI("hdfs://node01:8020"), new Configuration());
System.out.println(fileSystem);
}
复制代码
4.3 遍历 HDFS 中所有文件
// 需求1: 遍历hdfs中所有文件
@Test
public void listFilesHDFS() throws Exception{
//1. 获取 fileSystem对象
FileSystem fs = FileSystem.newInstance(new URI("hdfs://node01:8020"), new Configuration());
//2. 执行获取所有的文件
RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);
//3 遍历获取所有的文件
while(listFiles.hasNext()){
LocatedFileStatus fileStatus = listFiles.next();
String path = fileStatus.getPath().toString();
System.out.println(path);
}
//4. 释放资源
fs.close();
}
复制代码
4.4 HDFS 上创建文件夹
//需求2: 在hdfs中创建一个文件夹
@Test
public void mkdirHDFS() throws Exception{
//1. 获取FileSystem对象
Configuration conf = new Configuration();
conf.set("fs.defaultFS","hdfs://node01:8020");
FileSystem fs = FileSystem.newInstance(conf);
//2. 执行操作: 创建文件夹
fs.mkdirs(new Path("/mkdir/test"));
//3. 释放资源
fs.close();
}
复制代码
4.5 下载文件
//需求3: 下载文件: jdk
@Test
public void downLoadHDFS() throws Exception {
//1. 获取FileSystem对象
FileSystem fs = FileSystem.get(new URI("hdfs://node01:8020"), new Configuration());
//2. 执行下载操作: jdk
fs.copyToLocalFile(new Path("/jdk-8u144-linux-x64.tar.gz"),new Path("E:\\HDFS"));
//3. 释放资源
fs.close();
}
复制代码
4.6 HDFS 文件上传
//需求4: 上传文件HDFS中
@Test
public void uploadHDFS() throws Exception{
//1. 获取FileSystem对象
Configuration conf = new Configuration();
conf.set("fs.defaultFS","hdfs://node01:8020");
FileSystem fs = FileSystem.get(conf);
//2. 执行上传 :
fs.copyFromLocalFile(new Path("E:\\HDFS\\jdk-8u144-linux-x64.tar.gz"),new Path("/mkdir/test/"));
//3. 释放资源
fs.close();
}
复制代码
评论