Google cloud dataflow 在读取之前解压缩数据流中的文件
我们的客户正在将文件上传到地面军事系统,但它们已经压缩。有没有办法,使用Java Dataflow SDK,我们可以运行所有压缩文件,解压文件,将所有生成的.csv文件合并成一个文件,然后只进行Google cloud dataflow 在读取之前解压缩数据流中的文件,google-cloud-dataflow,Google Cloud Dataflow,我们的客户正在将文件上传到地面军事系统,但它们已经压缩。有没有办法,使用Java Dataflow SDK,我们可以运行所有压缩文件,解压文件,将所有生成的.csv文件合并成一个文件,然后只进行TextIO转换 编辑 为了回答jkffs的问题 我真的不需要将它们全部合并到一个文件中,从阅读的角度来看,这会容易得多 它们是ZIP文件,而不是GZ或BZ或其他任何文件。每个ZIP包含多个文件。文件名并不是很重要,是的,我更喜欢它TextIO透明地解压和连接所有文件,以每个存档为基础 希望有帮助 Dat
TextIO
转换
编辑
为了回答jkffs的问题
希望有帮助 Dataflow/Apache Beam自动支持
TextIO
中的ZIP压缩文件:TextIO.read()。from(filepattern)
将根据扩展名自动解压缩与filepattern匹配的文件,而.zip
是受支持的格式之一,在这种情况下,它会将.zip
中的所有文件隐式连接到一个文件中,并解析其中的文本行
如果文件没有扩展名,您也可以使用
TextIO.read().from(filepattern).withCompressionType(…)
显式指定压缩类型。,因为我遇到了同样的问题,并且只找到了这个1年前的、非常不完整的解决方案。以下是如何在google dataflow上解压缩文件的完整示例:
public class SimpleUnzip {
private static final Logger LOG = LoggerFactory.getLogger(SimpleUnzip.class);
public static void main(String[] args){
Pipeline p = Pipeline.create(
PipelineOptionsFactory.fromArgs(args).withValidation().create());
GcsUtilFactory factory = new GcsUtilFactory();
GcsUtil util = factory.create(p.getOptions());
try{
List<GcsPath> gcsPaths = util.expand(GcsPath.fromUri("gs://tlogdataflow/test/*.zip"));
List<String> paths = new ArrayList<String>();
for(GcsPath gcsp: gcsPaths){
paths.add(gcsp.toString());
}
p.apply(Create.of(paths))
.apply(ParDo.of(new UnzipFN()));
p.run();
}
catch(Exception e){
LOG.error(e.getMessage());
}
}
public static class UnzipFN extends DoFn<String,Long>{
private static final long serialVersionUID = 2015166770614756341L;
private long filesUnzipped=0;
@Override
public void processElement(ProcessContext c){
String p = c.element();
GcsUtilFactory factory = new GcsUtilFactory();
GcsUtil u = factory.create(c.getPipelineOptions());
byte[] buffer = new byte[100000000];
try{
SeekableByteChannel sek = u.open(GcsPath.fromUri(p));
InputStream is = Channels.newInputStream(sek);
BufferedInputStream bis = new BufferedInputStream(is);
ZipInputStream zis = new ZipInputStream(bis);
ZipEntry ze = zis.getNextEntry();
while(ze!=null){
LOG.info("Unzipping File {}",ze.getName());
WritableByteChannel wri = u.create(GcsPath.fromUri("gs://tlogdataflow/test/" + ze.getName()), getType(ze.getName()));
OutputStream os = Channels.newOutputStream(wri);
int len;
while((len=zis.read(buffer))>0){
os.write(buffer,0,len);
}
os.close();
filesUnzipped++;
ze=zis.getNextEntry();
}
zis.closeEntry();
zis.close();
}
catch(Exception e){
e.printStackTrace();
}
c.output(filesUnzipped);
}
private String getType(String fName){
if(fName.endsWith(".zip")){
return "application/x-zip-compressed";
}
else {
return "text/plain";
}
}
}
公共类SimpleUnzip{
私有静态最终记录器LOG=LoggerFactory.getLogger(SimpleUnzip.class);
公共静态void main(字符串[]args){
Pipeline p=Pipeline.create(
PipelineOptionFactory.fromArgs(args).withValidation().create());
GcsUtilFactory=新的GcsUtilFactory();
GcsUtil util=factory.create(p.getOptions());
试一试{
List gcsPaths=util.expand(GcsPath.fromUri(“gs://tlogdataflow/test/*.zip”);
列表路径=新的ArrayList();
用于(GcsPath gcsp:gcsPaths){
add(gcsp.toString());
}
p、 应用(创建路径)
.应用(新的UnzipFN()的第1部分);
p、 run();
}
捕获(例外e){
LOG.error(例如getMessage());
}
}
公共静态类UnzipFN扩展了DoFn{
私有静态最终长serialVersionUID=2015166770614756341L;
私有长文件解压缩=0;
@凌驾
公共void processElement(ProcessContext c){
字符串p=c.element();
GcsUtilFactory=新的GcsUtilFactory();
GcsUtil u=factory.create(c.getPipelineOptions());
字节[]缓冲区=新字节[100000000];
试一试{
seekablebytechnel sek=u.open(GcsPath.fromUri(p));
InputStream is=通道。newInputStream(sek);
BufferedInputStream bis=新的BufferedInputStream(is);
ZipInputStream zis=新的ZipInputStream(bis);
ZipEntry ze=zis.getNextEntry();
while(ze!=null){
info(“解压缩文件{}”,ze.getName());
WritableByteChannel wri=u.create(GcsPath.fromUri(“gs://tlogdataflow/test/”+ze.getName()),getType(ze.getName());
OutputStream os=Channels.newOutputStream(wri);
内伦;
而((len=zis.read(buffer))>0){
写操作(缓冲区,0,len);
}
os.close();
文件解压缩++;
ze=zis.getnextery();
}
zis.closeEntry();
zis.close();
}
捕获(例外e){
e、 printStackTrace();
}
c、 输出(文件解压缩);
}
私有字符串getType(字符串fName){
if(fName.endsWith(“.zip”)){
返回“application/x-zip-compressed”;
}
否则{
返回“文本/纯文本”;
}
}
}
}您能解释一下为什么要在进一步处理之前将所有.csv文件合并为一个文件吗?您需要按顺序而不是并行处理文件吗?在那之后有没有并行处理?另外,你能告诉我更多关于你的zip文件吗?它们真的是.zip还是.gz/.bz2?(TextIO目前支持gzip和bzip2压缩,但不支持.zip文件)如果是.zip文件,每个.zip文件中是有很多文件,还是只有一个?归档文件中的文件名是否重要?例如,如果TextIO透明地解压并连接zip存档中的所有文件,这对你有用吗?@jkff我用一些答案更新了这个问题!值得注意的是,这仅适用于Java库。到目前为止,Python库仍然只支持BZIP和GZIP2(),我在github上找不到任何与添加支持相关的pull请求。