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不必关闭输入流。