1、准备工作
环境:centsOS7.0、jdk1.8、maven3.3.9
工具:idea(eclipse)、HADOOP SHELL
发行版 :Hadoop2.5.0
环境上一节已经搭建好了、不明白的可以看 Hadoop之旅(1) 或者 Apache Hadoop 官网
2、添加maven依赖
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<hadoop.version>2.5.0</hadoop.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
<!-- Hadoop Client -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>${hadoop.version}</version>
</dependency>
</dependencies>
3、配置文件
这几个文件都是我们安装Hadoop的配置文件、日志文件也是(不加老是报警)
4、代码实现
4.1、获取系统配置文件信息
public static FileSystem getFileSystem() throws Exception {
// 获取配置文件:core-site.xml,core-defautl.xml,hdfs-site.xml,hdfs-default.xml
Configuration conf = new Configuration();
//解决:解决方法很简单,配置环境变量,不想重启电脑可以在程序里加上
System.setProperty("hadoop.home.dir", "F:\\ApplicationToolkit\\hadoopWinutils\\hadoop-common-2.2.0-bin-master");
// get filesystem
FileSystem fileSystem = FileSystem.get(conf);
System.out.println(fileSystem);
return fileSystem;
}
主要注意的问题:在win上开发会报这个错误:Could not locate executable null\bin\winutils.exe in the Hadoop binaries、其实这个错误是Hadoop的源码是需要读取 HADOOP_HOME 这个path,我们win上没有配置,所以报错。
解决:下载这个 hadoopWinutils 、可以在GitHub上下载、是别人开源的bin。然后配置环境变量名为 HADOOP_HOME 。
4.2、读取 HDFS 上的文件
public static void read(String fileName) throws Exception {
// get filesystem
FileSystem fileSystem = getFileSystem();
// read file
Path path = new Path(fileName);
// open file
FSDataInputStream fsDataInputStream = fileSystem.open(path);
try {
// read
IOUtils.copyBytes(fsDataInputStream, System.out, 4096, false);
} catch (Exception e) {
e.printStackTrace();
} finally {
// close Stream
IOUtils.closeStream(fsDataInputStream);
}
}
// filename
String filename = "/chenzhengyou/mapreduce/wordcount/input/putwc.input";
read(filename);
运行结果:
HADOOP SHELL 语句是这样的:bin/hdfs dfs -text /chenzhengyou/mapreduce/wordcount/input/word.input
-text(是hdfs的参数、读取的意思)、后面跟着文件路径(是在hdfs文件上的路径、不是本地的)
4.3、上传文件
public static void write(String putFileName, String filename) throws Exception {
// get filesystem
FileSystem fileSystem = getFileSystem();
// write path
Path writePath = new Path(putFileName);
// Output Stream
FSDataOutputStream outStream = fileSystem.create(writePath);
// file input Stream
FileInputStream inStream = new FileInputStream(new File(filename));
// stream read/write
try {
// read
IOUtils.copyBytes(inStream, outStream, 4096, false);
} catch (Exception e) {
e.printStackTrace();
} finally {
// close Stream
IOUtils.closeStream(inStream);
IOUtils.closeStream(outStream);
}
}
main 方法:
// write path "E:"+File.separatorChar+"nword.input";
String putFileName = "/chenzhengyou/mapreduce/wordcount/input/idea.input";
// 本地E盘
String file= "E:"+File.separatorChar+"nword.input";;
write(putFileName,file);
运行结果:
HADOOP SHELL 语句是这样的:bin/hdfs dfs -put -p wcinput/wc.input /chenzhengyou/mapreduce/wordcount/input
-put(是hdfs的参数、上传)、后面跟着文件目录(将要上传的文件目录)、最后是hdfs上的文件目录(将存放的目录)
特别注意:
问题A:Permission denied: user=administrator, access=WRITE, inode="/":root:supergroup:drwxr-xr-x、可能遇见这样的错误!这是权限问题、HADOOP默认是启开的、可以在hdfs-site.xml文件修改。
<!--权限-->
<property>
<name>dfs.permissions</name>
<value>false</value>
</property>
问题B:org.apache.Hadoop.dfs.SafeModeException: Cannot ... Name node is in safe mode 、说明namenode处于安全模式下、其实下图可以看出(官网也有解释:可以谷歌翻译快速!)、 启动hdfs需要一些恢复时间、二是hdfs需要4的数据块才解开安全模式。大概就是这个意思(如果不对、多多评论一起进步)。
解决:bin/hadoop dfsadmin -safemode leave (手动解决)、这样就可以操作 hdfs 了。