目录
2.读取HDFS文件(Hadoop提供的FileSystem实现)
本地访问HDFS最主要的方式是HDFS提供的Java API,其它的访问方式都是建立在这些API之上。 其中,最常用的是FileSystem类,它也是命令行 hadoop fs 的实现。
------------本文笔记整理自《Hadoop海量数据处理:技术详解与项目实战》范东来
需要引入的Jar包:hadoop-common-2.9.2.jar
1.读取HDFS文件(java.net.URL实现)
该功能实现的HDFS命令:
hadoop fs -cat /user/hadoop/words.txt
package com.hdfs.client;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import org.apache.hadoop.fs.FsUrlStreamHandlerFactory;
import org.apache.hadoop.io.IOUtils;
/*
* 读取文件
*/
public class MyCat {
static {
//静态代码块:使Java程序识别Hadoop的HDFS url
URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
}
public static void main(String[] args) throws MalformedURLException ,IOException {
/*
* 访问方式:hadoop jar MyCat.jar com.hdfs.client.MyCat hdfs://master:9000/user/hadoop/words.txt
* 结果:屏幕输出words.txt文件中的内容
*/
InputStream in = null;
try {
//用URL对象打开数据流
in = new URL(args[0]).openStream();
//输出到系统屏幕
IOUtils.copyBytes(in, System.out, 4096, false);
} finally {
IOUtils.closeStream(in);
}
}
}
1.将MyCat类右键导出为 JAR file,命名为:"MyCat.jar";
2.利用Windows的cmd或者PowerShell(推荐)将JAR文件上传到Linux服务器
命令如下:(在JAR文件目录下执行)
scp MyCat.jar root@remoteIP:~/myJars/hdfs/
(其中remoteIP为远程服务器IP)
3.启动hadoop,执行JAR
命令如下:(在JAR文件目录下执行,且HDFS的/user/hadoop/words.txt存在)
hadoop jar MyCat.jar com.hdfs.client.MyCat hdfs://master:9000/user/hadoop/words.txt
运行结果:控制台输出words.txt的文件内容
2.读取HDFS文件(Hadoop提供的FileSystem实现)
该功能实现的HDFS命令:
hadoop fs -cat /user/hadoop/words.txt
package com.hdfs.client;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
/*
* 读取HDFS文件
* FileSystem扮演输入流的角色
*/
public class FileSystemCat {
public static void main(String[] args) throws IOException {
//HDFS文件路径
String uri = "hdfs://master:9000/user/hadoop/words.txt";
//Configuration对象封装了HDFS客户端和集群的配置,静态加载模式
Configuration conf = new Configuration();
//工厂方法获取FileSystem实例
FileSystem fs = FileSystem.get(URI.create(uri), conf);
InputStream in = null;
try {
//获取输入流,InputStream子类FSDataInputStream
in = fs.open(new Path(uri));
//输出到系统屏幕
IOUtils.copyBytes(in, System.out, 4096, false);
} finally {
IOUtils.closeStream(in);
}
}
}
1.将FileSystemCat类右键导出为 JAR file,命名为:"FileSystemCat.jar";
2.利用Windows的cmd或者PowerShell(推荐)将JAR文件上传到Linux服务器
命令如下:(在JAR文件目录下执行)
scp FileSystemCat.jar root@remoteIP:~/myJars/hdfs/
(其中remoteIP为远程服务器IP)
3.启动hadoop,执行JAR
命令如下:(在JAR文件目录下执行)
hadoop jar FileSystemCat.jar com.hdfs.client.FileSystemCat
运行结果:控制台输出words.txt的文件内容
3.向HDFS写入文件
该功能实现的HDFS命令:
hadoop fs -copyFromLocal /home/hadoop/words.txt /user/hadoop/words.txt
package com.hdfs.client;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
/*
* 拷贝本地文件内容到HDFS文件
* FileSystem扮演输出流的角色
*/
public class FileCopyFromLocal {
public static void main(String[] args) throws IOException{
//本地文件路径
String source = "/home/hadoop/words.txt";
//HDFS文件路径
String destination = "hdfs://master:9000/user/hadoop/words.txt";
//获取输入流
InputStream in = new BufferedInputStream(new FileInputStream(source));
//Hadoop配置文件加载
Configuration conf = new Configuration();
//工厂方法获取FIleSystem实例
FileSystem fs = FileSystem.get(URI.create(destination), conf);
OutputStream out = null;
try {
//获取输出流,OutputStream子类FSDataOutputStream
//FSDataOutputStream不允许在文件中定位,因为HDFS只允许顺序写入或者末尾追加
out = fs.create(new Path(destination));
//输出到输出路径
IOUtils.copyBytes(in, out, 4096, true);
} finally {
IOUtils.closeStream(out);
IOUtils.closeStream(in);
}
}
}
1.将FileCopyFromLocal类右键导出为 JAR file,命名为:"FileCopyFromLocal.jar";
2.利用Windows的cmd或者PowerShell(推荐)将JAR文件上传到Linux服务器
命令如下:(在JAR文件目录下执行)
scp FileCopyFromLocal.jar root@remoteIP:~/myJars/hdfs/
(其中remoteIP为远程服务器IP)
3.启动hadoop,执行JAR
命令如下:(在JAR文件目录下执行)
hadoop jar FileCopyFromLocal.jar com.hdfs.client.FileCopyFromLocal
运行结果:控制台没有输出
4.可用hadoop fs 命令查看 /user/hadoop/目录下是否有words.txt文件:
hadoop fs -ls /user/hadoop/
4.创建HDFS目录
该功能实现的HDFS命令:
hadoop fs -mkdir /user/hadoop/test
package com.hdfs.client;
import java.io.IOException;
import java.net.URI;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
/*
* 创建HDFS目录
*/
public class CreateDir {
public static void main(String[] args) {
//HDFS目录路径
String uri = "hdfs://master:9000/user/hadoop/test";
//加载HDFS配置信息
Configuration conf = new Configuration();
try {
//工厂方法获取FIleSystem实例
FileSystem fs = FileSystem.get(URI.create(uri), conf);
//创建目录
fs.mkdirs(new Path(uri));
} catch (IOException e) {
e.printStackTrace();
}
}
}
1.将CreateDir类右键导出为 JAR file,命名为:"CreateDir.jar";
2.利用Windows的cmd或者PowerShell(推荐)将JAR文件上传到Linux服务器
命令如下:(在JAR文件目录下执行)
scp CreateDir.jar root@remoteIP:~/myJars/hdfs/
(其中remoteIP为远程服务器IP)
3.启动hadoop,执行JAR
命令如下:(在JAR文件目录下执行)
hadoop jar CreateDir.jar com.hdfs.client.CreateDir
运行结果:控制台没有输出
4.可用hadoop fs 命令查看 /user/hadoop/目录下是否有test目录:
hadoop fs -ls /user/hadoop/
5.删除HDFS上的文件或目录
该功能实现的HDFS命令:
hadoop fs -rm /user/hadoop
package com.hdfs.client;
import java.io.IOException;
import java.net.URI;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
/*
* 删除文件目录
*/
public class DeleteFile {
public static void main(String[] args) {
//HDFS文件路径
String uri = "hdfs://master:9000/user/hadoop/test";
//加载HDFS配置信息
Configuration conf = new Configuration();
try {
FileSystem fs = FileSystem.get(URI.create(uri), conf);
//删除目录路径,test的上级目录
Path delef = new Path("hdfs://master:9000/user/hadoop");
//非递归删除,只能删除空文件夹,否则报错
boolean isDeleted = fs.delete(delef, false);
//递归删除文件夹及文件夹下的文件
//boolean isDeleted = fs.delete(delef, true);
System.out.println(isDeleted);
} catch (IOException e) {
e.printStackTrace();
}
}
}
1.将DeleteFile类右键导出为 JAR file,命名为:"DeleteFile.jar";
2.利用Windows的cmd或者PowerShell(推荐)将JAR文件上传到Linux服务器
命令如下:(在JAR文件目录下执行)
scp DeleteFile.jar root@remoteIP:~/myJars/hdfs/
(其中remoteIP为远程服务器IP)
3.启动hadoop,执行JAR
命令如下:(在JAR文件目录下执行)
hadoop jar DeleteFile.jar com.hdfs.client.DeleteFile
运行结果:控制台没有输出
4.可用hadoop fs 命令查看 /user/目录下是否还有hadoop目录:
hadoop fs -ls /user/
6.查看HDFS文件存在
该功能实现的HDFS命令:
hadoop fs -test -e /user/hadoop/test
package com.hdfs.client;
import java.io.IOException;
import java.net.URI;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
/*
* 检查文件是否存在
*/
public class CheckFileIsExist {
public static void main(String[] args) {
//HDFS文件路径
String uri = "hdfs://master:9000/user/hadoop/test";
//加载HDFS配置信息
Configuration conf = new Configuration();
try {
FileSystem fs = FileSystem.get(URI.create(uri), conf);
boolean isExists = fs.exists(new Path(uri));
System.out.println(isExists);
} catch (IOException e) {
e.printStackTrace();
}
}
}
1.将CheckFileIsExist类右键导出为 JAR file,命名为:"CheckFileIsExist.jar";
2.利用Windows的cmd或者PowerShell(推荐)将JAR文件上传到Linux服务器
命令如下:(在JAR文件目录下执行)
scp CheckFileIsExist.jar root@remoteIP:~/myJars/hdfs/
(其中remoteIP为远程服务器IP)
3.启动hadoop,执行JAR
命令如下:(在JAR文件目录下执行)
hadoop jar CheckFileIsExist.jar com.hdfs.client.CheckFileIsExist
运行结果:控制台输出 true 或者 false
7.列出HDFS目录下的文件或文件名
该功能实现的HDFS命令:
hadoop fs -ls /user/
package com.hdfs.client;
import java.io.IOException;
import java.net.URI;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
/*
* 列出文件夹下的文件及文件夹列表
*/
public class ListFiles {
public static void main(String[] args) {
//HDFS文件路径
String uri = "hdfs://master:9000/user";
//加载HDFS配置信息
Configuration conf = new Configuration();
try {
FileSystem fs = FileSystem.get(URI.create(uri), conf);
//获取文件夹下的文件及文件夹状态
FileStatus[] stats = fs.listStatus(new Path(uri));
//遍历
for (int i = 0; i < stats.length; i++) {
System.out.println(stats[i].getPath().toString());
}
fs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
1.将ListFiles类右键导出为 JAR file,命名为:"ListFiles.jar";
2.利用Windows的cmd或者PowerShell(推荐)将JAR文件上传到Linux服务器
命令如下:(在JAR文件目录下执行)
scp ListFiles.jar root@remoteIP:~/myJars/hdfs/
(其中remoteIP为远程服务器IP)
3.启动hadoop,执行JAR
命令如下:(在JAR文件目录下执行)
hadoop jar ListFiles.jar com.hdfs.client.ListFiles
运行结果:控制台输出HDFS文件目录"/user/"下的文件及文件夹名
4.可用hadoop fs 命令验证,是否与 /user/目录下所有文件及文件夹名一致:
hadoop fs -ls /user/
8.查询HDFS文件存储的位置
package com.hdfs.client;
import java.io.IOException;
import java.net.URI;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.BlockLocation;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
/*
* 显示文件位置信息(在哪个节点)
*/
public class LocationFile {
public static void main(String[] args) {
//HDFS文件路径:--args[0] : '/user/hadoop/test'
String uri = "hdfs://master:9000" + args[0];
//加载HDFS配置信息
Configuration conf = new Configuration();
try {
FileSystem fs = FileSystem.get(URI.create(uri), conf);
//获取HDFS文件状态
FileStatus stats = fs.getFileStatus(new Path(uri));
//获取文件块信息
BlockLocation[] blkLocations = fs.getFileBlockLocations(stats, 0, stats.getLen());
//遍历块
for (int i = 0; i < blkLocations.length; i++) {
//获取文件块所在节点主机号
String[] hosts = blkLocations[i].getHosts();
System.out.println("block_" + i + "_location: " + hosts[0]);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
1.将LocationFile类右键导出为 JAR file,命名为:"LocationFile.jar";
2.利用Windows的cmd或者PowerShell(推荐)将JAR文件上传到Linux服务器
命令如下:(在JAR文件目录下执行)
scp LocationFile.jar root@remoteIP:~/myJars/hdfs/
(其中remoteIP为远程服务器IP)
3.启动hadoop,执行JAR
命令如下:(在JAR文件目录下执行)
hadoop jar LocationFile.jar com.hdfs.client.LocationFile /user/hadoop/test
运行结果:控制台输出HDFS文件'test'的所有文件块所在的节点位置
block_0_location:localhost
block_1_location:localhost
9.写入SequenceFile
package com.hdfs.client;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.SequenceFile;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.SequenceFile.Writer;
/*
* 写入序列化文件
*/
public class SequenceFileWriter {
//待序列化文本
private static final String[] text = {
"one two tree",
"four five six",
"seven eight nine",
"ten eleven twelve"
};
public static void main(String[] args) {
//HDFS文件路径
String uri = "hdfs://master:9000/user/hadoop/testseq";
//加载HDFS配置文件
Configuration conf = new Configuration();
SequenceFile.Writer writer = null;
try {
//弃用,可由 path.getFileSystem(conf) 获得,参看createWriter底层实现
//FileSystem fs = FileSystem.get(URI.create(uri), conf);
Path path = new Path(uri);
IntWritable key = new IntWritable();
Text value = new Text();
//被弃用
//writer = SequenceFile.createWriter(fs, conf, path, key.getClass(), value.getClass());
//改成Options
writer = SequenceFile.createWriter(conf, Writer.file(path),
Writer.keyClass(key.getClass()),
Writer.valueClass(value.getClass()));
for (int i = 0; i < 100; i++) {
key.set(100-i);
value.set(text[i%text.length]);
writer.append(key, value);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.closeStream(writer);
}
}
}
1.将SequenceFileWriter类右键导出为 JAR file,命名为:"SequenceFileWriter.jar";
2.利用Windows的cmd或者PowerShell(推荐)将JAR文件上传到Linux服务器
命令如下:(在JAR文件目录下执行)
scp SequenceFileWriter.jar root@remoteIP:~/myJars/hdfs/
(其中remoteIP为远程服务器IP)
3.启动hadoop,执行JAR
命令如下:(在JAR文件目录下执行)
hadoop jar SequenceFileWriter.jar com.hdfs.client.SequenceFileWriter
运行结果:控制台没有输出
4.可用hadoop fs 命令查看序列化文件:
hadoop fs -text /user/hadoop/testseq
100 one two tree
99 four five six
98 seven eight nine
97 ten eleven twelve
.
.
.
4 one two tree
3 four five six
2 seven eight nine
1 ten eleven twelve
10.读取SequenceFile
该功能实现的HDFS命令:
hadoop fs -text /user/hadoop/testseq
package com.hdfs.client;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.SequenceFile;
import org.apache.hadoop.io.SequenceFile.Reader;
import org.apache.hadoop.io.Writable;
import org.apache.hadoop.util.ReflectionUtils;
/*
* 读出序列化文件
*/
public class SequenceFileReader {
public static void main(String[] args) {
//待解析HDFS文件路径
String uri = "hdfs://master:9000/user/hadoop/testseq";
//加载HDFS配置信息
Configuration conf = new Configuration();
SequenceFile.Reader reader = null;
try {
Path path = new Path(uri);
//被弃用,与createWriter()一样,需要对其它参数进行Option化
//底层fs 可由 path.getFileSystem(conf)获得
//reader = new SequenceFile.Reader(fs, file, conf);
reader = new SequenceFile.Reader(conf, Reader.file(path));
//获得实现Writable接口的基本类型,Key和Value
Writable key = (Writable) ReflectionUtils.newInstance(reader.getKeyClass(), conf);
Writable value = (Writable) ReflectionUtils.newInstance(reader.getValueClass(), conf);
//long position = reader.getPosition();
//reader.next()函数具有将读取位置后移功能
while (reader.next(key, value)) {
System.out.printf("[%s]\t%s\t\n", key, value);
//position = reader.getPosition();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.closeStream(reader);
}
}
}
1.将SequenceFileReader类右键导出为 JAR file,命名为:"SequenceFileReader.jar";
2.利用Windows的cmd或者PowerShell(推荐)将JAR文件上传到Linux服务器
命令如下:(在JAR文件目录下执行)
scp SequenceFileReader.jar root@remoteIP:~/myJars/hdfs/
(其中remoteIP为远程服务器IP)
3.启动hadoop,执行JAR
命令如下:(在JAR文件目录下执行)
hadoop jar SequenceFileReader.jar com.hdfs.client.SequenceFileReader
运行结果:控制台输出四行英文的信息
[100] one two tree
[99] four five six
[98] seven eight nine
[97] ten eleven twelve
.
.
.
[4] one two tree
[3] four five six
[2] seven eight nine
[1] ten eleven twelve
4.可用hadoop fs 命令,验证读取序列化文件是否正确:
hadoop fs -text /user/hadoop/testseq