我有很多输入文件,我想根据最后附加的日期处理选定的文件。我现在不知道在哪里使用globstatus方法来过滤文件。
我有一个定制的recordreader类,我试图在它的下一个方法中使用globstatus,但没有成功。
public boolean next(Text key, Text value) throws IOException {
Path filePath = fileSplit.getPath();
if (!processed) {
key.set(filePath.getName());
byte[] contents = new byte[(int) fileSplit.getLength()];
value.clear();
FileSystem fs = filePath.getFileSystem(conf);
fs.globStatus(new Path("/*" + date));
FSDataInputStream in = null;
try {
in = fs.open(filePath);
IOUtils.readFully(in, contents, 0, contents.length);
value.set(contents, 0, contents.length);
} finally {
IOUtils.closeStream(in);
}
processed = true;
return true;
}
return false;
}
我知道它返回一个filestatus数组,但是如何使用它来过滤文件。有人能帮我弄点光吗?
2条答案
按热度按时间d7v8vwbk1#
这个
globStatus
方法接受两个免费参数,允许您筛选文件。第一种是glob模式,但有时glob模式的功能不足以过滤特定的文件,在这种情况下,您可以定义PathFilter
.关于glob模式,支持以下内容:
public interface PathFilter {
boolean accept(Path path);
}
public class RegexExcludePathFilter implements PathFilter {
private final String regex;
}
conf.set("date", "2013-01-15");
public class RegexIncludePathFilter extends Configured implements PathFilter {
private String date;
private FileSystem fs;
}
yiytaume2#
对于任何阅读本文的人,我可以说“请不要在过滤器中做比验证路径更复杂的事情”。具体来说:不要检查文件是否是目录,获取它们的大小,等等。等到list/glob操作返回,然后在那里进行过滤,使用当前填充的文件中的信息
FileStatus
条目。为什么?所有这些电话
getFileStatus()
,直接或通过isDirectory()
正在对文件系统进行不必要的调用,这些调用会在hdfs集群上添加不必要的namenode负载。更关键的是,针对s3和其他对象存储,每个操作都有可能发出多个https请求,而这些请求确实需要可测量的时间。更好的是,如果s3认为您在整个计算机集群中发出的请求太多,它会限制您。你不想那样。直到调用之后,您返回的文件状态条目是那些来自对象存储的list命令,通常每个https请求返回数千个文件条目,因此效率更高。
有关更多详细信息,请查看
org.apache.hadoop.fs.s3a.S3AFileSystem
.