
如果要将上传的二进制流文件转换为MultipartFile,需要使用第三方库来实现。例如,可以使用GuzzleHttp库将二进制数据流转换为StreamInterface对象,然后将其传递给UploadedFile类的构造函数。
下面是一个示例代码,演示如何将上传的二进制流文件转换为MultipartFile:
use GuzzleHttp\Psr7\Stream
use Symfony\Component\HttpFoundation\File\UploadedFile
// 获取上传的文件流
$fileContent = file_get_contents($_FILES['file']['tmp_name'])
// 将二进制流转换为 StreamInterface 对象
$stream = new Stream(fopen('php://memory','r+'))
$stream->write($fileContent)
// 创建 UploadedFile 对象
$file = new UploadedFile(
$stream,
$_FILES['file']['name'],
$_FILES['file']['type'],
$_FILES['file']['size'],
UPLOAD_ERR_OK,
true // 是否删除临时文件
)
// 现在 $file 是一个 MultipartFile 对象,可以将其传递给需要的函数进行处理
注意,上述示例中使用了GuzzleHttp和Symfony两个第三方库,需要事先安装和引入这些库才能正常运行代码。
MultipartFile提供了以下方法来获取上传文件的信息:getOriginalFilename,获取上传的文件名字;
getBytes,获取上传文件内容,转为字节数组;
getInputStream,获取一个InputStream;
isEmpty,文件上传内容为空,或者根本就没有文件上传;
getSize,文件上传的大小。
transferTo(File dest),保存文件到目标文件系统;
同时上传多个文件,则使用MultipartFile数组类来接受多个文件上传:
//多文件上传@RequestMapping(value = "/batch/upload", method = RequestMethod.POST)
@ResponseBody public String handleFileUpload(HttpServletRequest request){
List<MultipartFile>files = ((MultipartHttpServletRequest) request)
.getFiles("file")
MultipartFile file = null
BufferedOutputStream stream = null
for (int i = 0i <files.size()++i) {
file = files.get(i)
if (!file.isEmpty()) {
try {
byte[] bytes = file.getBytes()
stream = new BufferedOutputStream(new FileOutputStream(
new File(file.getOriginalFilename())))
stream.write(bytes)
stream.close()
} catch (Exception e) {
stream = null
return "You failed to upload " + i + " =>" + e.getMessage()
}
} else {
return "You failed to upload " + i
+ " because the file was empty."
}
}
return "upload successful"
}
可以通过配置application.properties对SpringBoot上传的文件进行限定默认为如下配置:
spring.servlet.multipart.enabled=true
spring.servlet.multipart.file-size-threshold=0
spring.servlet.multipart.location=
spring.servlet.multipart.max-file-size=1MB
spring.servlet.multipart.max-request-size=10MB
spring.servlet.multipart.resolve-lazily=false
enabled默认为true,既允许附件上传。
file-size-threshold限定了当上传文件超过一定长度时,就先写到临时文件里。有助于上传文件不占用过多的内存,单位是MB或KB,默认0,既不限定阈值。
location指的是临时文件的存放目录,如果不设定,则web服务器提供一个临时目录。
max-file-size属性指定了单个文件的最大长度,默认1MB,max-request-size属性说明单次HTTP请求上传的最大长度,默认10MB.
resolve-lazily表示当文件和参数被访问的时候再被解析成文件。
时间:2020.12.4
异常:java.io.FileNotFoundException: /home/jdp/apache-tomcat-8.5.54-8-group/apache-tomcat-8.5.54-80 /work/Catalina/localhost/ROOT/upload_cda0de04_fa66_4589_8170_5cb0cb7f8152_00000005.tmp
初步判断:文件上传路径问题,但是项目路径中并未配置这个路径,后面了解到 /work 是tomcat 编译文件的临时路径,联想到 /work 之后的文件可能是上传的临时文件路径,而前面的路径是tomcat的绝对路径
探索1:项目配置的文件路径为/home/temp, 可能是因为tomcat的临时文件路径和我们上传的临时文件路径不匹配导致的
尝试1:设置tomcat 临时文件路径 在 application.properites 中配置 增加配置 server.tomcat.basedir=/home/temp
结果1:未解决,报错不变
探索2:查阅资料得知 MultipartFile.transferTo(targetFile) 方法是面向绝对路径的,如果入参是一个相对路径,则会在路径之前加上 一个系统绝对路径(比较符合我们的情况)
尝试2:根据文章所述:增加配置类 指定临时文件的路径
@Configuration
public class FileUploadConfig {
@Value("${file.temp.root}")
private String FILE_TEMP_ROOT
/**
* 文件上传配置
*
* @return MultipartConfigElement
*/
@Bean
public MultipartConfigElement multipartConfigElement(
@Value("${multipart.maxFileSize}") String maxFileSize,
@Value("${multipart.maxRequestSize}") String maxRequestSize) {
MultipartConfigFactory factory = new MultipartConfigFactory()
// 单个文件最大
factory.setMaxFileSize(maxFileSize)
// 设置总上传数据总大小
factory.setMaxRequestSize(maxRequestSize)
//上传临时路径
File file = new File(FILE_TEMP_ROOT)
if (!file.exists()) {
file.mkdirs()
}
factory.setLocation(FILE_TEMP_ROOT)
return factory.createMultipartConfig()
}
}
结果2:报错发生变化,变成了我们的指定的路径加上 临时文件名,但是依旧未能解决问题
java.io.FileNotFoundException: /home/temp/upload_a8eb4246_470f_4f73_81af_891f1ad6651b_00000002.tmp
转换思路:既然是transferTo()方法的问题,换一个方法
探索3:更换transferTo()方法,使用 FileUtils.copyInputStreamToFile(sourceFile.getInputStream(), targetFile)方法
尝试3:寻找方法中包涵的transfTo()方法,替换成FileUtils.copyInputStreamToFile(sourceFile.getInputStream(), targetFile)
结果3:问题解决
总结:transferTo()在windows 系统上并没有这个问题,在Linux上出现了这个问题,网上的资料各有说法,目前未找到真正的原因。为了避免这个问题,统一使用FileUtils.copyInputStreamToFile(sourceFile.getInputStream(), targetFile)方法来复制文件。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)