接着上一篇:Hadoop HDFS 实践(1)—— 安装 IDEA 并创建项目
本笔记主要内容如下:
查看 HDFS 中的文件列表
在项目目录 ~/src/main/java
下创建一个类,命名为 Ls.java
,写入代码
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| import java.net.URI;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.BlockLocation; import org.apache.hadoop.fs.FileStatus; import org.apache.hadoop.fs.LocatedFileStatus; import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.RemoteIterator;
public class Ls { public static void main(String[] args) throws Exception { String uri = "hdfs://192.168.29.127:8020/"; Configuration config = new Configuration(); FileSystem fs = FileSystem.get(URI.create(uri), config, "root");
FileStatus[] listStatus = fs.listStatus(new Path("/")); for (FileStatus file : listStatus) { System.out.println("[" + (file.isFile() ? "file" : "dir") + "]" + file.getPath().getName()); }
RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true); while (listFiles.hasNext()) { System.out.println("========================"); LocatedFileStatus fileStatus = listFiles.next(); System.out.println("块大小:" + fileStatus.getBlockSize()); System.out.println("所属:" + fileStatus.getOwner()); System.out.println("备份数:" + fileStatus.getReplication()); System.out.println("权限:" + fileStatus.getPermission()); System.out.println("名称:" + fileStatus.getPath().getName()); System.out.println("---------块信息---------"); BlockLocation[] blockLocations = fileStatus.getBlockLocations(); for (BlockLocation b : blockLocations) { System.out.println("块起始偏移量" + b.getOffset()); System.out.println("块长度" + b.getLength()); String[] datanodes = b.getHosts(); for (String dn : datanodes) { System.out.println("DataNode:" + dn); } } } } }
|
首先启动 Hadoop,运行
1
| $ /opt/app/hadoop-2.9.2/sbin/start-all.sh
|
待 Hadoop 成功运行后,右键点击代码,选择 Run 'Ls.main()'
运行结果 (由于篇幅限制,此处省略部分输出结果):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| [dir]hbase ======================== 块大小:134217728 所属:root 备份数:1 权限:rw-r--r-- 名称:state-00000000000000000006.log ---------块信息---------
......
......
======================== 块大小:134217728 所属:root 备份数:1 权限:rw-r--r-- 名称:hadoop%2C33452%2C1553933199568.1553944017981 ---------块信息--------- 块起始偏移量0 块长度83 DataNode:hadoop ======================== 块大小:134217728 所属:root 备份数:1 权限:rw-r--r-- 名称:hbase.version ---------块信息--------- 块起始偏移量0 块长度7 DataNode:hadoop
Process finished with exit code 0
|
可以看出这些文件是由 HBase 创建的,推测是之前初始化 HBase 的时候自动生成。
错误处理
在初次运行时会出现如图所示报错,且不会有任何输出。
这是由于 log4j 没有配置日志记录的位置,需要配置 log4j.properties。
解决方法
在 src
文件夹下新建 resources
文件夹,并在里面新建文件 log4j.properties
,在文件中输入以下内容
1 2 3 4 5 6
| hadoop.root.logger = DEBUG, console log4j.rootLogger = DEBUG, console log4j.appender.console = org.apache.log4j.ConsoleAppender log4j.appender.console.target = System.out log4j.appender.console.layout = org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern = %d{yy/MM/dd HH:mm:ss} %p %c{2}: %m%n
|
重新运行代码,会有正常结果输出。
在 HDFS 中创建新目录
在 HDFS 中创建目录 /mkdir/a/b
在项目目录 ~/src/main/java
下创建一个类,命名为 Mkdir.java
,写入代码
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import java.net.URI;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path;
public class Mkdir { public static void main(String[] args) throws Exception { String uri = "hdfs://192.168.29.127:8020/"; Configuration config = new Configuration(); FileSystem fs = FileSystem.get(URI.create(uri), config, "root"); boolean mkdirs = fs.mkdirs(new Path("/mkdir/a/b")); System.out.println("创建目录结果:" + mkdirs); } }
|
运行,输出结果:
使用 hdfs 命令验证
1
| $ hdfs dfs -ls /mkdir/a/b
|
没有报不存在的错误,创建成功!
上传文件到 HDFS
在当前项目目录下新建测试文件,上传到 HDFS 中的 /mkdir
先在项目目录下创建文件 Hello_World.txt
,写入内容:This is a test file.
注意要在项目目录下创建,而不能在 src 目录下创建
然后在 ~/src/main/java
里创建一个类,命名为 Put.java
,写入代码
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import java.net.URI;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path;
public class Put { public static void main(String[] args) throws Exception { String uri = "hdfs://192.168.29.127:8020/"; Configuration config = new Configuration(); FileSystem fs = FileSystem.get(URI.create(uri), config, "root"); String localpath = "Hello_World.txt"; fs.copyFromLocalFile(new Path(localpath), new Path("/mkdir")); fs.close(); } }
|
运行。
使用 hdfs 命令验证
可以看到文件已经成功上传!
从 HDFS 下载文件到本地
把 HDFS 中的 /mkdir/Hello_World.txt 下载到指定目录下
在项目目录 ~/src/main/java
下创建一个类,命名为 Get.java
,写入代码
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import java.net.URI;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path;
public class Get { public static void main(String[] args) throws Exception { String uri = "hdfs://192.168.29.127:8020/"; Configuration config = new Configuration(); FileSystem fs = FileSystem.get(URI.create(uri), config, "root"); String localpath = "Hello_World_2.txt"; fs.copyToLocalFile(new Path("/mkdir/Hello_World.txt"), new Path(localpath)); } }
|
运行。
完毕后可以看到在项目目录下多出文件 Hello_World_2.txt
,打开后内容和之前填入的一致。
下载成功!
从 HDFS 中删除文件
删除 HDFS 中的 /mkdir/Hello_World.txt 文件
在项目目录 ~/src/main/java
下创建一个类,命名为 Del.java
,写入代码
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import java.net.URI;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path;
public class Del { public static void main(String[] args) throws Exception { String uri = "hdfs://192.168.29.127:8020/"; Configuration config = new Configuration(); FileSystem fs = FileSystem.get(URI.create(uri), config, "root"); boolean ret = fs.delete(new Path("/mkdir/Hello_World.txt"), true); System.out.println("删除结果:" + ret); } }
|
运行,输出结果:
使用 hdfs 命令验证
可以看到文件成功被删除!
重命名 HDFS 中的文件或文件夹
把 HDFS 中的 /mkdir/a 重命名为 /mkdir/a_2
在项目目录 ~/src/main/java
下创建一个类,命名为 Rename.java
,写入代码
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import java.net.URI;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path;
public class Rename { public static void main(String[] args) throws Exception { String uri = "hdfs://192.168.29.127:8020/"; Configuration config = new Configuration(); FileSystem fs = FileSystem.get(URI.create(uri), config, "root"); fs.rename(new Path("/mkdir/a"), new Path("/mkdir/a_2")); } }
|
运行
使用 hdfs 命令验证
重命名成功!
流方式读取文件部分内容
上传一个文本文件,然后使用流方式读取部分内容保存到当前项目目录
首先创建一个文件 New.txt
,内容为:
上传到 HDFS 根目录
1
| $ hdfs dfs -put New.txt /
|
在项目目录 ~/src/main/java
下创建一个类,命名为 StreamGet.java
,写入代码
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import java.io.FileOutputStream; import java.net.URI;
import org.apache.commons.io.IOUtils; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path;
public class StreamGet { public static void main(String[] args) throws Exception { String uri = "hdfs://192.168.29.127:8020/"; Configuration config = new Configuration(); FileSystem fs = FileSystem.get(URI.create(uri), config, "root"); FSDataInputStream inputStream = fs.open(new Path("/New.txt")); inputStream.seek(5); FileOutputStream outputStream = new FileOutputStream("New.txt.part2"); IOUtils.copy(inputStream, outputStream); } }
|
运行
可以看到项目目录下多出 New.txt.part2
文件,打开可以看到文件内容。
全文完