你好,游客 登录
背景:
阅读新闻

HDFS基本编程实例

[日期:2014-10-13] 来源: 机械工业出版社  作者:黄宜华 [字体: ]

    本节介绍使用HDFS 的API 编程的简单示例。

    下面的程序可以实现如下功能:在输入文件目录下的所有文件中,检索某一特定字符串所出现的行,将这些行的内容输出到本地文件系统的输出文件夹中。这一功能在分析MapReduce 作业的Reduce 输出时很有用。

    这个程序假定只有第一层目录下的文件才有效,而且,假定文件都是文本文件。当然,如果输入文件夹是Reduce 结果的输出,那么一般情况下,上述条件都能满足。为了防止单个的输出文件过大,这里还加了一个文件最大行数限制,当文件行数达到最大值时,便关闭此文件, 创建另外的文件继续保存。保存的结果文件名为1,2,3,4,…,以此类推。

    如上所述,这个程序可以用来分析MapReduce 的结果,所以称为ResultFilter。

    程序:Result Filter

    输入参数:此程序接收4 个命令行输入参数,参数含义如下:

    <dfs path>:HDFS 上的路径

    <local path>:本地路径

    <match str>:待查找的字符串

    <single file lines>:结果每个文件的行数

    程序:ResultFilter

  1. import java.util.Scanner;  
  2. import java.io.IOException;  
  3. import java.io.File;  
  4. import org.apache.hadoop.conf.Conf iguration;  
  5. import org.apache.hadoop.fs.FSDataInputStream;  
  6. import org.apache.hadoop.fs.FSDataOutputStream;  
  7. import org.apache.hadoop.fs.FileStatus;  
  8. import org.apache.hadoop.fs.FileSystem;  
  9. import org.apache.hadoop.fs.Path;  
  10. public class resultFilter  
  11. {  
  12. public static void main(String[] args) throws IOException {  
  13. Conf iguration conf = new Conf iguration();  
  14. // 以下两句中,hdfs 和local 分别对应HDFS 实例和本地文件系统实例  
  15. FileSystem hdfs = FileSystem.get(conf);  
  16. FileSystem local = FileSystem.getLocal(conf);  
  17. Path inputDir, localFile;  
  18. FileStatus[] inputFiles;  
  19. FSDataOutputStream out = null;  
  20. FSDataInputStream in = null;  
  21. Scanner scan;  
  22. String str;  
  23. byte[] buf;  
  24. int singleFileLines;  
  25. int numLines, numFiles, i;  
  26. if(args.length!=4)  
  27. {  
  28. // 输入参数数量不够, 提示参数格式后终止程序执行  
  29. System.err.println("usage resultFilter <dfs path><local path>" +  
  30. <match str><single f ile lines>");  
  31. return;  
  32. }  
  33. inputDir = new Path(args[0]);  
  34. singleFileLines = Integer.parseInt(args[3]);  
  35. try {  
  36. inputFiles = hdfs.listStatus(inputDir); // 获得目录信息  
  37. numLines = 0;  
  38. numFiles = 1; // 输出文件从1 开始编号  
  39. localFile = new Path(args[1]);  
  40. if(local.exists(localFile)) // 若目标路径存在, 则删除之  
  41. local.delete(localFile, true);  
  42. for (i = 0; i<inputFiles.length; i++) {  
  43. if(inputFiles[i].isDir() == true) // 忽略子目录  
  44. continue;  
  45. System.out.println(inputFiles[i].getPath().getName());  
  46. in = hdfs.open(inputFiles[i].getPath());  
  47. scan = new Scanner(in);  
  48. while (scan.hasNext()) {  
  49. str = scan.nextLine();  
  50. if(str.indexOf(args[2])==-1)  
  51. continue; // 如果该行没有match 字符串, 则忽略之  
  52. numLines++;  
  53. if(numLines == 1) // 如果是1, 说明需要新建文件了  
  54. {  
  55. localFile = new Path(args[1] + File.separator + numFiles);  
  56. out = local.create(localFile); // 创建文件  
  57. numFiles++;  
  58. }  
  59. buf = (str+"\n").getBytes();  
  60. out.write(buf, 0, buf.length); // 将字符串写入输出流  
  61. if(numLines == singleFileLines) // 如果已满足相应行数, 关闭文件  
  62. {  
  63. out.close();  
  64. numLines = 0; // 行数变为0, 重新统计  
  65. }  
  66. }// end of while  
  67. scan.close();  
  68. in.close();  
  69. }// end of for  
  70. if(out != null)  
  71. out.close();  
  72. } // end of try  
  73. catch (IOException e) {  
  74. e.printStackTrace();  
  75. }  
  76. }// end of main  
  77. }// end of resultFilter 

    程序的编译命令:

  1. javac *.java 

运行命令

  1. hadoop jar resultFilter.jar resultFilter <dfs path>\  
  2. <local path><match str><single f ile lines> 

参数和含义如下:

<dfs path>:HDFS 上的路径

<local path>: 本地路径

<match str>: 待查找的字符串

<single file lines>: 结果的每个文件的行数

    上述程序的逻辑很简单,获取该目录下所有文件的信息,对每一个文件,打开文件、循环读取数据、写入目标位置,然后关闭文件,最后关闭输出文件。这里粗体打印的几个函数上面都有介绍,不再赘述。

    我们在自己机器上预装的hadoop-1.0.4 上简单试验了这个程序,在hadoop 源码中拷贝了几个文件,然后上传到HDFS 中,文件如下(见图3-17):

 

    然后,编译运行一下该示例程序,显示一下目标文件内容,结果如图3-18 所示,其中,将出现“java”字符串的每一行都输出到文件中。





收藏 推荐 打印 | 录入: | 阅读:
相关新闻       HDFS  编程 
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数
点评:
       
评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款