一 、配置Windows下的Hadoop环境
导入依赖与插件
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-core</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</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>
</plugins>
</build>
二、Java的api操作
1.涉及的主要类
Configuration
该类的对象封装了客户端或者服务器的配置
FileSystem
该类的对象是一个文件系统对象,用于操作文件,通过FileSystem的静态方法get获取对象
1.1获取FileSystem的几种方式
第一种
@Test
public void getFileSystem1() throws IOException {
Configuration configuration = new Configuration();
//设置配置信息,第一个参数是固定的,第二个表示分布式文件系统
configuration.set("fs.defaultFS","hdfs://node01:9000/");
FileSystem fileSystem = FileSystem.get(configuration);
System.out.println(fileSystem);
}
第二种
使用套接字地址和默认配置获取
@Test
public void getFileSystem2() throws URISyntaxException, IOException {
FileSystem fileSystem = FileSystem.get(new URI("hdfs://node01:8020"), new Configuration());
System.out.println(fileSystem);
}
第三种
@Test
public void getFileSystem3() throws IOException {
Configuration configuration = new Configuration();
//设置配置信息,第一个参数是固定的,第二个表示分布式文件系统
configuration.set("fs.defaultFS","hdfs://node01:9000/");
FileSystem fileSystem = FileSystem.newInstance(configuration);
System.out.println(fileSystem);
}
第四种
@Test
public void getFileSystem4() throws IOException, URISyntaxException {
FileSystem fileSystem = FileSystem.newInstance(new URI("hdfs://node01:8020"), new Configuration());
System.out.println(fileSystem);
}
2.遍历HDFS所有文件
@Test
public void fileList() throws URISyntaxException, IOException {
FileSystem fileSystem =
FileSystem.get(new URI("hdfs://node01:9000"), new Configuration());
//获取根目录下所有目录的所有文件
//第一个参数代表所要获取的目前,第二个决定是否递归获取目录里的子目录
//得到迭代器
RemoteIterator<LocatedFileStatus> iterator = fileSystem.listFiles(new Path("/"), true);
while (iterator.hasNext())
{
LocatedFileStatus fileStatus = iterator.next();
//通过fileStatus获取文件相关信息
//获取文件的绝对路径和文件名
System.out.println(fileStatus.getPath()+":"+fileStatus.getPath().getName());
//获取文件的block信息
BlockLocation[] blockLocations = fileStatus.getBlockLocations();
System.out.println(blockLocations.length);
}
}
3.创建目录
默认是可以递归创建目录和文件的
@Test
public void mkdir() throws URISyntaxException, IOException, InterruptedException {
//要注意权限
FileSystem fileSystem = FileSystem.get(new URI("hdfs://node01:9000"), new Configuration(),"root");
//创建目录
fileSystem.mkdirs(new Path("/test/testdir"));
//创建文件
fileSystem.create(new Path("/test/testdir/test.txt"));
fileSystem.close();
}
4.文件下载/上传
//下载文件
@Test
public void download() throws URISyntaxException, IOException {
FileSystem fileSystem = FileSystem.get(new URI("hdfs://node01:9000"), new Configuration());
//获取HDFS输入流
FSDataInputStream inputStream = fileSystem.open(new Path("/test/a.txt"));
//创建一个输入流
FileOutputStream outputStream = new FileOutputStream("a.txt");
IOUtils.copy(inputStream,outputStream);
//关闭流
IOUtils.closeQuietly(inputStream);
IOUtils.closeQuietly(outputStream);
}
也可以调用copyTolocalFile
//下载文件
@Test
public void download2() throws URISyntaxException, IOException {
FileSystem fileSystem = FileSystem.get(new URI("hdfs://node01:9000"), new Configuration());
fileSystem.copyToLocalFile(new Path("/test/a.txt"),new Path("a.txt"));
}
上传文件就是调用copyFromLocalFile
@Test
public void put() throws URISyntaxException, IOException {
FileSystem fileSystem = FileSystem.get(new URI("hdfs://node01:9000"), new Configuration());
//本地路径和目标路径
fileSystem.copyFromLocalFile(new Path("a.txt"),new Path("/test/a.txt"));
}
5.小文件合并
由于 Hadoop 擅长存储大文件,因为大文件的元数据信息比较少,如果 Hadoop 集群当中有大量的小文件,那么每个小文件都需要维护一份元数据信息,会大大的增加集群管理元数据的内存压力,所以在实际工作当中,如果有必要一定要将小文件合并成大文件进行一起处理
我们可以直接使用shell命令来下载合并文件
hdfs dfs -getmerge /config/*.xml ./hello.xml
一般情况下,我们都是将文件合并后再上传HDFS
//合并文件并上传
@Test
public void mergeput() throws URISyntaxException, IOException, InterruptedException {
FileSystem fileSystem =
FileSystem.get(new URI("hdfs://node01:9000"), new Configuration(),"root");
//在HDFS创建文件,获得输出流
FSDataOutputStream outputStream = fileSystem.create(new Path("/mergefileandput.txt"));
//获取本地文件系统
LocalFileSystem localFileSystem = FileSystem.getLocal(new Configuration());
//获取所需要上传的本地文件
FileStatus[] fileStatuses = localFileSystem.listStatus(new Path("test"));
//遍历,合并上传
for (FileStatus fileStatus : fileStatuses) {
//获取每个文件的输入流
FSDataInputStream inputStream = localFileSystem.open(fileStatus.getPath());
IOUtils.copy(inputStream,outputStream);
IOUtils.closeQuietly(inputStream);
}
IOUtils.closeQuietly(outputStream);
localFileSystem.close();
}