Hadoop框架下的HDFS编程:【遍历目录下所有文件】在指定目录下查找包含某一内容的文件,并输出符合条件的文件名

HDFS编程练习,首先要查找某一目录下是否包含某一内容,那么就要做遍历该目录下所有文件的操作。
使用Path实例得到目的目录的路径下所有文件的路径,调用listStatus函数得到路径,返回的是一个FileStatus类的数组
然后遍历该数组中所有文件的路径,通过getPath方法得到
通过FileSystem类对象调用open方法打开数据流
要从Hadoop文件系统读取文件,最简单的方法是使用java.net.URL 对象打开数据流,从中读取数据。
让Java程序能够能够识别Hadoop的hdfs URL 方案还需要一些额外的工作。这里采用的方法是通过FsUrlStreamHandlerFactory实例调用java.net.URL对象的setURLStreamHandlerFactory()方法。每个Java虚拟机只能调用一次这个方法,因此通常在静态方法中调用。这个限制意味着如果程序的其他组件(如不受你控制的第三方控件)已经声明一个URLStreamHandlerFactory实例,你将无法使用这个方法从Hadoop中读取数据。
得到数据流后转换为字符缓冲流BufferedReader
接着调用字符缓冲流中的readline对象读取每个文件的内容,并通过分隔符分割每个单词,一一对比遍历单词和查找子串的内容,出现过则输出该文件名

该实例的参数有两个,一是目的目录的路径,二是搜索的字符串,字符串不带空格。
调用结果如下:
在这里插入图片描述

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.conf.*;
import java.net.*;
public class test1 {
	static {
		URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
	}
	public static void getfileStr(String filePath,String check) {
		final String INNER_DELIMITER = " ";
		// 遍历目录下的所有文件
		BufferedReader br = null;
		try {
			FileSystem fs = FileSystem.get(new Configuration());
			FileStatus[] status = fs.listStatus(new Path(filePath));//获取文件目录
			System.out.println("find result:");
			int cnt=0;
			for (FileStatus file : status)//遍历文件目录,file为指针
			{
				FSDataInputStream inputStream = fs.open(file.getPath());//输入流 获取某个文件到路径
				br = new BufferedReader(new InputStreamReader(inputStream));//建立 字符缓冲输入流 实例
				
				String line = null;
				boolean flag=false;
				while (null != (line = br.readLine())) 
				{
					String[] strs = line.split(INNER_DELIMITER);//设置读取分割符
					for(int i=0;i<strs.length;i++)
					{
//						System.out.println(strs[i]+"-------------");
						if(strs[i].equals(check))
						{
							flag=true;
							break;
						}
					}
					if(flag)
					{
						cnt++;
						System.out.println(cnt+"."+file.getPath().getName());
						break;
					}
				}// end of while
			}
			if(cnt==0)System.out.println("No such file!");
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				br.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	public static void main(String[] args) throws IOException{
		// TODO Auto-generated method stub
//		String uri="hdfs://master:9000/input";
		String uri=args[0];//接收路径参数
		String checkstr=args[1];//接收查找字符串参数
		Configuration conf=new Configuration();
		getfileStr(uri,checkstr);
	}
}

IOUtils.copyBytes()方法:
IOUtils.copyBytes(in, out, 4096, false)
–in:是FSDataInputStream类的对象,是有关读取文件的类,也就是所谓“输入流”
–out:是FSDataOutputStream类的对象,是有关文件写入的类,也就是“输出流”
–4096表示用来拷贝的buffer大小(buffer是缓冲区)–缓冲区大小
–// true - 是否关闭数据流,如果是false,就在finally里关掉

我们可以调用Hadoop中简洁的IOUtils类,并在finally 子句中关闭数据流,同时也可以在输入流和输出流之间复制数据(本例中为System.out)。copyBytes方法的最后两个参数,第一个设置用于复制的缓冲区大小,第二个设置复制结束后是否关闭数据流。这里我们选择自行关闭输入流,因而System.out不必关闭输入流。

posted @ 2018-10-13 23:25  KuroNekonano  阅读(1018)  评论(0编辑  收藏  举报