解压缩Hadoop hdfs目录中的所有Gzip文件

解压缩Hadoop hdfs目录中的所有Gzip文件,hadoop,gzip,compression,Hadoop,Gzip,Compression,在我的HDFS上,我有一堆gzip文件,我想将它们解压缩为正常格式。是否有用于执行此操作的API?或者我如何编写一个函数来实现这一点 我不想使用任何命令行工具;相反,我想通过编写Java代码来完成这项任务。您需要一个文件解压程序。gzip的实现是。你可以通过编解码器得到一个简单的输入输出结果。类似这样:假设您有一个文件file.gz //path of file String uri = "/uri/to/file.gz"; Configuration conf = new Configurat

在我的HDFS上,我有一堆gzip文件,我想将它们解压缩为正常格式。是否有用于执行此操作的API?或者我如何编写一个函数来实现这一点

我不想使用任何命令行工具;相反,我想通过编写Java代码来完成这项任务。

您需要一个文件解压程序。gzip的实现是。你可以通过编解码器得到一个简单的输入输出结果。类似这样:假设您有一个文件
file.gz

//path of file
String uri = "/uri/to/file.gz";
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(URI.create(uri), conf);
Path inputPath = new Path(uri);

CompressionCodecFactory factory = new CompressionCodecFactory(conf);
// the correct codec will be discovered by the extension of the file
CompressionCodec codec = factory.getCodec(inputPath);

if (codec == null) {
    System.err.println("No codec found for " + uri);
    System.exit(1);
}

// remove the .gz extension
String outputUri =
    CompressionCodecFactory.removeSuffix(uri, codec.getDefaultExtension());

InputStream is = codec.createInputStream(fs.open(inputPath));
OutputStream out = fs.create(new Path(outputUri));
IOUtils.copyBytes(is, out, conf);

// close streams

更新

如果需要获取一个目录中的所有文件,则应获取
FileStatus
es,如

FileSystem fs = FileSystem.get(new Configuration());
FileStatus[] statuses = fs.listStatus(new Path("hdfs/path/to/dir"));
然后循环一下

for (FileStatus status: statuses) {
    CompressionCodec codec = factory.getCodec(status.getPath());
    ...
    InputStream is = codec.createInputStream(fs.open(status.getPath());
    ...
}

我使用我在滚烫中写的身份映射Hadoop作业来更改压缩/更改分割大小/等等

class IdentityMap(args: Args) extends ConfiguredJob(args) {
  CombineFileMultipleTextLine(args.list("in"): _*).read.mapTo[String, String]('line -> 'line)(identity)
  .write(if (args.boolean("compress")) TsvCompressed(args("out")) else TextLine(args("out")))
}
一般配置抽象类:

abstract class ConfiguredJob(args: Args) extends Job(args) {
  override def config(implicit mode: Mode): Map[AnyRef, AnyRef] = {
    val Megabyte = 1024 * 1024
    val conf = super.config(mode)
    val splitSizeMax = args.getOrElse("splitSizeMax", "1024").toInt * Megabyte
    val splitSizeMin = args.getOrElse("splitSizeMin", "512").toInt * Megabyte
    val jobPriority = args.getOrElse("jobPriority","NORMAL")
    val maxHeap = args.getOrElse("maxHeap","512m")
    conf ++ Map("mapred.child.java.opts" -> ("-Xmx" + maxHeap),
      "mapred.output.compress" -> (if (args.boolean("compress")) "true" else "false"),
      "mapred.min.split.size" -> splitSizeMin.toString,
      "mapred.max.split.size" -> splitSizeMax.toString,
//      "mapred.output.compression.codec" -> args.getOrElse("codec", "org.apache.hadoop.io.compress.BZip2Codec"), //Does not work, has to be -D flag
      "mapred.job.priority" -> jobPriority)
  }
}

所以实际上我所有的gzip文件都存储在hdfs的一个目录中,一个目录中有一堆文件。我希望遍历目录中的每个文件,对其进行解压缩,然后将结果文件存储在新目录中。要获取目录中的文件列表,我使用的是代码列表,因此我的OutputStream仍然与:OutputStream out=fs.create(new Path(“hdfs/output”))相同;对的那么这将继续将我的InputStream文件复制到OutStream路径?还是我错了?对于我的代码示例,我基本上是将文件存储在同一个目录中,只是解压缩,没有.gz扩展名。这就是
removeSuffix
的目的。但是如果您想将它存储在其他地方,只需更改路径并自己删除扩展。问题的第二部分,是的,在循环中,您只需获取输入流并将其复制到输出流,只需尝试一下,看看您得到了什么结果。让我知道如果什么不起作用,如果不起作用,好的,最后一个问题。那么,您是否也要删除.gz扩展名文件?或者它们仍然存在于输入路径中?