FileInputFormat.java
主要是createInputSplits这个函数
源码中会得到文件系统(这里会得到HDFS),和文件的总大小。然后考虑了输入文件时文件夹,输入文件不可切分等情况,然后根据HDFS的分块(block)大小,文件总大小和Source的并行度来计算每个split的大小,每个split会存储对应的HDFS的block信息,例如block在哪个host上。注意:每个split的大小是不能超过HDFS中分块(block)的大小的。得到每个split的大小后就可以根据HDFS的各个分块信息来构造inputSplits了。
- 获取最小的split,默认是1
- 如果输入的是文件夹,获取文件夹下的所有文件,如果目标是文件,直接加入。并得到总的文件大小
- 判断文件是否能切割读取
1 |
|
1 | 举例说明:文件A大小为256M,存储在HDFS上,HDFS的分块大小为64M,则A文件会被分割成4个block,每个block都是64M。 |
判断文件是否能切割
获取文件的后缀,根据后缀去判断文件是否能切割,如果文件是的后缀如下,不能切割,只能一个solt读取(几乎都是压缩包)
- xz
- deflate
- gz
- gzip
- bz2
1
2
3
4
5
6
7
8
9
10
11
12
13
14protected boolean testForUnsplittable(FileStatus pathFile) {
if(getInflaterInputStreamFactory(pathFile.getPath()) != null) {
unsplittable = true;
return true;
}
return false;
}
protected static InflaterInputStreamFactory<?> getInflaterInputStreamFactory(String fileExtension) {
synchronized (INFLATER_INPUT_STREAM_FACTORIES) {
return INFLATER_INPUT_STREAM_FACTORIES.get(fileExtension);
}
}