我们的客户正在将文件上传到GCS,但它们是压缩的。有没有办法,使用Java Dataflow SDK,我们可以在其中运行所有压缩文件,解压缩文件,将所有生成的.csv文件合并到一个文件中,然后只进行TextIO
转换?
编辑
回答jkffs的问题,
希望有所帮助!
答案 0 :(得分:4)
因为我遇到了同样的问题,而且只是在这个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";
}
}
}
}
答案 1 :(得分:1)
Dataflow / Apache Beam自动TextIO
支持ZIP压缩文件:TextIO.read().from(filepattern)
将根据文件扩展名自动解压缩与文件模式匹配的文件,.zip
是受支持的格式之一 - 在这种情况下,它将隐式地将.zip
内的所有文件连接成一个文件,并从中解析文本行。
如果文件没有扩展名,您还可以使用TextIO.read().from(filepattern).withCompressionType(...)
明确指定压缩类型。