【问题标题】:Convert ByteArrayInputStream to File without saving to Disk将 ByteArrayInputStream 转换为文件而不保存到磁盘
【发布时间】:2021-04-13 17:06:29
【问题描述】:

这个问题涉及使用 Java/Groovy/Grails 处理文件。我对这些技术还很陌生,所以请耐心等待。

在收到用户提交的来自客户端的 POST 请求的文件后,我正在将文件上传到 Stripe。如果可以避免,我不想将其保存到磁盘。

我收到文件并解析成一个字节数组。

List<MultipartFile> files = ((MultipartHttpServletRequest) request).getMultiFileMap().collect {
                it.value
            }.flatten()
            try {
                if (files.size > 0) {
                    // parse file and get byte array input stream
                    MultipartFile file = files.first()
                    String fileName = file.originalFilename
                    byte[] bytes = file.inputStream.getBytes()
                    callStripeFileService(bytes)
            }

这个字节数组被传递给一个服务,该服务调用 Stripe,如 their docs 所示。

    callStripeFileService(byte[] bytes) {
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes)
        String tempFilePath = 
             "src/main/resources/tmp/${fileName}"
        IOUtils.copy(bais, new FileOutputStream(tempFilePath))

        FileCreateParams params = FileCreateParams.builder()
            .setFile(new java.io.File(tempFilePath))
            .setPurpose(FileCreateParams.Purpose.RECEIPT)      
            .build()

        File upload = File.create(params)
    }

这工作得很好,但我不喜欢将文件写入磁盘只是最终不得不将其删除。我还怀疑写入磁盘肯定会对性能产生影响。

我希望只将流传递给 Stripe,但 .setFile() 方法只接受 File 或 FileInputStream。

有什么方法可以创建有效的 Java File 对象而不将任何内容保存到磁盘?

【问题讨论】:

标签: java grails groovy stripe-payments


【解决方案1】:

没有; java.io.File 是一个文件,因此得名。没有像File 对象那样可以捕获的类似虚拟文件的东西 - java.io.File 是一个非常薄的包装器,它有一个字段,这就是路径,仅此而已。它上面的所有方法,以及像new FileInputStream(...) 这样的东西只是从那个File 对象中读取路径并自己完成所有工作,因此不可能。设计良好的 java API 不使用 File;例如,他们使用InputStream。如果条带 API 只允许 File,那么它就是设计糟糕的 API。解决方法是向 repo 发送一个拉取请求并对其进行修复。

大概是作者搞砸了;采用FileInputStream 的变体是一个错误,它应该采用InputStream 代替。我会记录下来,为什么不呢:参数类型为FileInputStream 的方法已损坏。从“测试可以捕捉到它”的意义上说并没有破坏,但就像将两个数字加在一起的方法一样破坏,称为“减法”。

TL;DR:不可能。

【讨论】:

  • 我与您一样感到沮丧,因为该方法不接受输入流。我敢肯定他们有他们的理由......不过你已经给了我我的答案。谢谢
  • 嘿 rzwitserloot,由于您的建议,该库现在支持 InputSteam 作为 setFile() 的参数。再次感谢您的帮助!
【解决方案2】:

作为替代方案,您可以让用户将文件直接上传到 Stripe,这样您就不必担心:https://jsfiddle.net/thorstripe/bdm3j2rn/

显然我需要包含代码,因为有一个 jsfiddle 链接:

console.log("Go read the jsfiddle kthx");

【讨论】:

  • 很好的例子和很好的建议,但其他工作需要在控制器级别使用字节数组完成,所以这对我不起作用。
猜你喜欢
  • 2014-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-22
  • 2013-12-19
  • 2010-09-23
  • 2010-11-08
相关资源
最近更新 更多