将 ByteArrayInputStream 转换为文件而不保存到磁盘

Convert ByteArrayInputStream to File without saving to Disk

此问题涉及使用 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)
            }

此字节数组被传递给服务,该服务按照 their docs 中的指示调用 Stripe。

    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() 方法只接受文件或 FileInputStream。

有什么方法可以在不将任何内容保存到磁盘的情况下创建有效的 Java 文件对象?

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

大概是作者搞砸了;采用 FileInputStream 的变体是错误的,它应该采用 InputStream 代替。我会记录下来,为什么不呢:参数类型为 FileInputStream 的方法已损坏。在 'tests can catch it' 的意义上没有损坏,但像将 2 个数字加在一起的方法一样损坏,名为 'subtract'.

TL;DR: 不可能。

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

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

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