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