hadoop - hdfs如何在hadoop的新目录中解压. gz 文件?

我在hdfs的一个文件夹里有很多.gz文件,想把所有这些.gz文件解压到hdfs的一个新文件夹中,我该怎么做?

时间:

可以通过3种不同的方式来实现它。

使用Linux命令行

以下命令为我工作。


hadoop fs -cat /tmp/Links.txt.gz | gzip -d | hadoop fs -put - /tmp/unzipped/Links.txt



我的压缩文件是Links.txt.gz
输出结果存储在/tmp/unzipped/Links.txt中

使用Java程序

Hadoop The Definitve Guide书上有一个关于Codecs的章节,在该部分中,有一个程序使用CompressionCodecFactory解压缩输出。我正在按原样生成代码:


package com.myorg.hadooptests;



import org.apache.hadoop.conf.Configuration;


import org.apache.hadoop.fs.FileSystem;


import org.apache.hadoop.fs.Path;


import org.apache.hadoop.io.IOUtils;


import org.apache.hadoop.io.compress.CompressionCodec;


import org.apache.hadoop.io.compress.CompressionCodecFactory;



import java.io.InputStream;


import java.io.OutputStream;


import java.net.URI;



public class FileDecompressor {


 public static void main(String[] args) throws Exception {


 String uri = args[0];


 Configuration conf = new Configuration();


 FileSystem fs = FileSystem.get(URI.create(uri), conf);


 Path inputPath = new Path(uri);


 CompressionCodecFactory factory = new CompressionCodecFactory(conf);


 CompressionCodec codec = factory.getCodec(inputPath);


 if (codec == null) {


 System.err.println("No codec found for" + uri);


 System.exit(1);


 }


 String outputUri =


 CompressionCodecFactory.removeSuffix(uri, codec.getDefaultExtension());


 InputStream in = null;


 OutputStream out = null;


 try {


 in = codec.createInputStream(fs.open(inputPath));


 out = fs.create(new Path(outputUri));


 IOUtils.copyBytes(in, out, conf);


 } finally {


 IOUtils.closeStream(in);


 IOUtils.closeStream(out);


 }


 }


}



这里代码将gz文件路径作为输入,
你可以执行以下操作:


FileDecompressor <gzipped file name>



例如,当我执行压缩文件时:


FileDecompressor /tmp/Links.txt.gz



我在位置找到解压缩的文件:/tmp/Links.txt

它将解压缩的文件存储在同一文件夹中,因此,你需要修改代码以获取2个输入参数:<input file path> and <output folder>

一旦你使用了这个程序,你可以编写一个Shell/Perl/Python脚本来为你的每个输入调用这个程序。

使用Pig脚本

你可以编写一个简单的Pig脚本来。

我编写了以下脚本,它工作:


A = LOAD '/tmp/Links.txt.gz' USING PigStorage();


Store A into '/tmp/tmp_unzipped/' USING PigStorage();


mv /tmp/tmp_unzipped/part-m-00000 /tmp/unzipped/Links.txt


rm /tmp/tmp_unzipped/



运行这里脚本时,解压缩的内容将存储在临时文件夹中:/tmp/tmp_unzipped此文件夹将包含


/tmp/tmp_unzipped/_SUCCESS


/tmp/tmp_unzipped/part-m-00000



part-m-00000包含解压缩的文件。

因此,需要使用以下命令显式重命名它,最后删除/tmp/tmp_unzipped文件夹:


mv /tmp/tmp_unzipped/part-m-00000 /tmp/unzipped/Links.txt


rm /tmp/tmp_unzipped/



如果使用这个Pig脚本,你只需要处理参数化文件名(links.txt.gz和links.txt )。

同样,一旦得到了这个脚本,你可以编写一个Shell/Perl/Python脚本来调用每个输入的Pig脚本。

Bash解决方案

我创建了一个简单的bash脚本,下面有一个简短的描述。


#!/bin/bash



workdir=/tmp/unziphdfs/


cd $workdir



# get all zip files in a folder


zips=$(hadoop fs -ls /yourpath/*.zip | awk '{print $8}')


for hdfsfile in $zips


do


 echo $hdfsfile



 # copy to temp folder to unpack


 hdfs dfs -copyToLocal $hdfsfile $workdir



 hdfsdir=$(dirname"$hdfsfile")


 zipname=$(basename"$hdfsfile")



 # unpack locally and remove


 unzip $zipname


 rm -rf $zipname



 # copy files back to hdfs


 files=$(ls $workdir)


 for file in $files; do


 hdfs dfs -copyFromLocal $file $hdfsdir


 rm -rf $file


 done



 # optionally remove the zip file from hdfs?


 # hadoop fs -rm -skipTrash $hdfsfile


done



描述

  • 未定义
  • 未定义
  • 解压缩
  • 将所有提取的文件复制到zip文件的目录中
  • 清理

可以使用配置单元(假设它是文本数据)执行这个操作。


create external table source (t str) location '<directory_with_gz_files>';


create external table target (t str) location '<target_dir>';


insert into table target select * from source;



数据将被压缩到新的文件集。

如果不想更改名称,并且在运行的node上有足够的存储空间,你可以执行以下操作。


hadoop fs -get <your_source_directory> <directory_name>


It will create a directory where you run hadoop command. cd to it and gunzip all the files


cd ..


hadoop fs -moveFromLocal <directory_name> <target_hdfs_path>



如果你已经压缩了文本文件,hadoop -text支持gzip以及其他常见的压缩格式。


hadoop fs -text /tmp/a.gz | hadoop fs -put - /tmp/uncompressed_a



Hadoop的FileUtil类有unTar()unZip()方法来实现这一点,unTar()方法也适用于.tar.gz和.tgz文件。不幸的是,它们只处理本地文件系统上的文件,必须使用一个类方法的一个copy()来复制到你需要使用的分布式文件系统中。

...