我在后端项目里使用RestTemplate请求接口上传文件,有个RestTemplate的切面会打印请求参数,调用JSON.toJSONString()方法对参数序列化后,本地文件被清空,文件大小为0,上传到文件服务器的文件大小也是0;
fastjson版本:1.2.69
代码逻辑:
Map
map.put("file", new FileSystemResource(new File("filePath")));
System.out.println(JSON.toJSONString(map));
麻烦大佬帮忙解答一下
FileSystemResource 是spring封装的类,其实现了WritableResource接口
public class FileSystemResource extends AbstractResource implements WritableResource {...}
在递归解析字段时,由于是采用getter方式,getOutputStream被当做getter方法被调用,
public interface WritableResource extends Resource {
// omit
/**
* Return an {@link OutputStream} for the underlying resource,
* allowing to (over-)write its content.
* @throws IOException if the stream could not be opened
* @see #getInputStream()
*/
OutputStream getOutputStream() throws IOException;
}
getXX本意是获取XX字段的值,但getOutputStream()被调用,拿到output后未写入任何值,相当于向output写入了空,后被flush到磁盘导致的文件被重写了
FileSystemResource类,使用其他对象代替这个不是拿到outputStream 后写入了空,导致了文件被重写,而是在构造FileOutputStream 对象的时候就已经清空了文件,
具体应该是在这里
public FileOutputStream(File file, boolean append)
throws FileNotFoundException
{
String name = (file != null ? file.getPath() : null);
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(name);
}
if (name == null) {
throw new NullPointerException();
}
if (file.isInvalid()) {
throw new FileNotFoundException("Invalid file path");
}
this.fd = new FileDescriptor();
fd.attach(this);
this.append = append;
this.path = name;
open(name, append);
}
// 这里文件已经被清空了
/**
* Opens a file, with the specified name, for overwriting or appending.
* @param name name of file to be opened
* @param append whether the file is to be opened in append mode
*/
private native void open0(String name, boolean append)
throws FileNotFoundException;
// wrap native call to allow instrumentation
/**
* Opens a file, with the specified name, for overwriting or appending.
* @param name name of file to be opened
* @param append whether the file is to be opened in append mode
*/
private void open(String name, boolean append)
throws FileNotFoundException {
open0(name, append);
}
也就是说,如果构造FileOutputStrem 时,append=false(缺省值) 会先清空文件
查了一下c 语言的文档,文件打开模式为w+ 时,会截断
模式 | 描述
-- | --
r | 打开一个已有的文本文件,允许读取文件。
w | 打开一个文本文件,允许写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会从文件的开头写入内容。如果文件存在,则该会被截断为零长度,重新写入。
a | 打开一个文本文件,以追加模式写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会在已有的文件内容中追加内容。
r+ | 打开一个文本文件,允许读写文件。
w+ | 打开一个文本文件,允许读写文件。如果文件已存在,则文件会被截断为零长度,如果文件不存在,则会创建一个新文件。
a+ | 打开一个文本文件,允许读写文件。如果文件不存在,则会创建一个新文件。读取会从文件的开头开始,写入则只能是追加模式。
i can't agree with you more
@hulog @ChenYuPan 多谢两位大佬解疑答惑~