【问题标题】:Uncompressing base64 gzip on S3 and saving to local file system在 S3 上解压 base64 gzip 并保存到本地文件系统
【发布时间】:2018-03-23 04:43:24
【问题描述】:

我是 Java 傻瓜/新手,所以请保持温和。我有两个我意识到有些不兼容的功能:

  1. saveS3toFilesystem - 从 AWS S3 获取 InputStream 并将其作为文件保存到本地文件系统
  2. decompress - 接受一个字符串并解码 base64 编码并解压缩 gzip 压缩。

我真的希望这两者协同工作以实现保存到文件系统的文件是未压缩文件的结果,但我意识到我的“解压缩”函数可能应该更改为接收流而不是字符串,但遗憾的是这些天来,我只是 Java 世界中的“剪纸师”。

这是我现在的两个函数:

private void saveS3toFilesystem(String filename, String bucketName, String localFilename) {
  S3Object obj = s3.getObject(bucketName, filename);
  InputStream in = obj.getObjectContent();
  try {
    Files.createDirectories(Paths.get(localFilename.replace(this.FILE_EXTENSION, "")));
    Files.copy(in, Paths.get(localFilename));
    this.logger.log("Input file has been placed in local filesystem for ITMS to pick up: " + localFilename + "\n");
  } catch (IOException err) {
    this.logger.log("There was a problem saving the file to " + localFilename);
    err.printStackTrace();
  } finally {
    try {
      in.close();
    } catch (IOException err) {
      err.printStackTrace();
    }
  }
  return;
}

然后……

private String decompress(String compressedZip) {
  byte[] decodedBytes = Base64.getDecoder().decode(compressedZip);
  String result = null;
  GZIPInputStream zip = null;
  try {
    zip = new GZIPInputStream(new ByteArrayInputStream(decodedBytes));
    result = IOUtils.toString(zip);
  } catch (IOException e) {
    e.printStackTrace();
  } finally {
    IOUtils.closeQuietly(zip);
  }
  return result;
}

谁能帮我实现梦想?很高兴使用流、字符串或任何可行的方法来做到这一点。可悲的是,我负担不起 atm 来提高我的 Java 技能以自己摸索解决方案。

非常感谢。

【问题讨论】:

  • 为了将您的解压缩函数从字符串输入重构为 InpuStream 输入:您的意思是这样的吗? stackoverflow.com/questions/247161/…
  • 顺便问一下,您是否考虑过一种更管道化的方法 - 即从 S3 获取文件以将其内容保存在内存中而不是硬盘驱动器上,然后立即解压缩,然后才保存它在文件系统上?
  • @JimGarrison 我认为 ken 只是在使用一个修辞格。具有 3K 评级的 SO 用户知道如何正确提问......
  • 我认为 "...我负担不起 atm 来提高我的 Java 技能以自己摸索解决方案" 非常明确地“为我编写代码”。
  • @Jim 或者我们的想法是从相关 API 上获得一些想法并从中找出解决方案

标签: java base64 gzip


【解决方案1】:

基于以下 API: Base64.DecoderGZIPInputStream(看前者的wrap方法和后者的构造函数),解压方法可以重载如下:

private String decompress(InputStream compressedStream) {
  InputStream decodingStream = Base64.getDecoder().wrap(compressedStream);
  String result = null;
  GZIPInputStream zip = null;
  try {
    zip = new GZIPInputStream(decodingStream);
    result = IOUtils.toString(zip);
  } catch (IOException e) {
    e.printStackTrace();
  } finally {
    IOUtils.closeQuietly(zip);
  }
  return result;
}

最后,saveS3toFilesystem 的变化如下:

private void saveS3toFilesystem(String filename, String bucketName, String localFilename) {
  S3Object obj = s3.getObject(bucketName, filename);
  InputStream in = obj.getObjectContent();
  // decoding the inputstream via decode into a string, which is then
  // used in order to create an inputstream of decoded data
  InputStream decodedStream = 
     new ByteArrayInputStream(decompress(in).getBytes(StandardCharsets.UTF_8));
  try {
    Files.createDirectories(Paths.get(localFilename.replace(this.FILE_EXTENSION, "")));
    Files.copy(decodedStream, Paths.get(localFilename));
    this.logger.log("Input file has been placed in local filesystem for ITMS to pick up: " + localFilename + "\n");
  } catch (IOException err) {
    this.logger.log("There was a problem saving the file to " + localFilename);
    err.printStackTrace();
  } finally {
    try {
      in.close();
    } catch (IOException err) {
      err.printStackTrace();
    }
  }
  return;
}

【讨论】:

  • saveToFilesystem 方法中,Base64.getDecoder().decode() 似乎抱怨获取 InputStream:[Java] The method decode(byte[]) in the type Base64.Decoder is not applicable for the arguments (InputStream)
  • @ken :您应该使用 Base64.getDecoder().wrap() 而不是 Base64.getDecoder().decode()。前者用于 InputStream 参数,后者用于字节数组参数,如您的 linter 错误消息中所示。
  • 我只是指您的 saveS3toFilesystem 中的 decode(in) 行。也许这也意味着要换行?
  • @ken 一千个道歉。我写的是 decode(.....) 而不是 decompress(.....)。这就是应该使用我们的解压缩方法的地方。
  • 我确实编译了最新的更改,现在收到java.io.EOFException 错误。这是该函数的屏幕截图,其中注释了异常发生的位置。 screencast.com/t/YP1mRqC8Y ...我正在努力调试它。不确定您是否有任何见解。谢谢你坚持我@rann
猜你喜欢
  • 2018-06-30
  • 1970-01-01
  • 1970-01-01
  • 2014-05-22
  • 2021-07-22
  • 1970-01-01
  • 1970-01-01
  • 2013-08-19
  • 2017-08-23
相关资源
最近更新 更多