代码:
现象:
这样写,上传到oss的文件大小是0b或者16b
修改后:
根据debug和猜测在94行把inpustream改了,因此注掉这行则解决问题.
原因:
inpustream流被读取后不支持继续再读取
修改代码如下:
以上代码能解决单线程情况,而线程池多线程情况下使用MultipartFile进行异步操作报错,系统找不到指定的文件
C:\Users\ginseng\AppData\Local\Temp\tomcat.6121315196242383180826.8056\work\Tomcat\localhost\ROOT(系统找不到指定的文件)
因为异步情况下,主线程结束后,临时文件会被清空,因此需要通过流的方式来解决
思路回到,想通过重复读取流来解决问题,查了下找到这个:
但实际上,这个仍然不管用,虽然异步情况下,不会报找不到文件了,但又回到了第一个坑,上传的文件为0b
最后根据另一种方式,缓存流的方式,已达到重复使用效果:
声名一个缓存对象
@Slf4j
public class FileNodeCacheDto implements AutoCloseable, Serializable {
/**
* 存储对应的文件名
*/
@Setter
@Getter
private String fileName;
/**
* 将InputStream中的字节保存到ByteArrayOutputStream中。
*/
private ByteArrayOutputStream byteArrayOutputStream = null;
public FileNodeCacheDto() {
}
/**
* 缓存输入流
*
* @param inputStream
*/
public FileNodeCacheDto(InputStream inputStream) {
if (Objects.isNull(inputStream)) {
return;
}
this.byteArrayOutputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
try {
while ((len = inputStream.read(buffer)) > -1) {
this.byteArrayOutputStream.write(buffer, 0, len);
}
this.byteArrayOutputStream.flush();
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
public InputStream getCacheInputStream() {
if (Objects.isNull(byteArrayOutputStream)) {
return null;
}
return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
}
@Override
public void close() throws Exception {
try {
this.byteArrayOutputStream.close();
} catch (Exception e) {
log.error("销毁byteArrayOutputStream缓存失败", e);
}
}
}
在异步之前把流存储好
最终代码改成如下,两个问题均解决,但该方法如果上传的文件较多,会造成内存浪费,虽然也做了close,需要做限制:
参考:
https://stackoverflow.com/questions/9501237/read-input-stream-twice
https://blog.csdn.net/dreamtdp/article/details/26733563
https://blog.csdn.net/loophome/article/details/102700997
https://blog.csdn.net/javadream007/article/details/102566585
https://blog.csdn.net/u014656173/article/details/77280705