Spark Java文件上传异常:为何不同文件类型结果不同?
问题原因分析
这个现象的核心原因是Servlet规范中Multipart请求的分阶段存储机制,结合Spark Java 2.9.4的默认行为导致的,具体拆解如下:
- 当你配置
MultipartConfigElement时,若未显式指定fileSizeThreshold(文件大小阈值)参数,Spark Java底层依赖的Jetty容器会采用默认策略:当上传文件体积小于阈值时,直接将文件内容保存在内存中,不会在你指定的/tmp_files目录创建物理临时文件;只有当文件体积超过阈值时,才会将内容写入磁盘临时文件。 - 你的
test.png体积较小,触发了内存存储逻辑,此时如果代码中尝试访问该文件的磁盘路径(比如某些隐式依赖临时文件路径的操作),就会因为磁盘上根本不存在对应的文件而抛出java.nio.file.NoSuchFileException。而zip文件体积较大,被写入了/tmp_files的临时文件,所以整个流程能正常执行。
补充:也有可能是IDEA HTTP客户端上传png时的请求头细节问题,但既然zip能正常上传,这个可能性极低,核心还是文件大小触发的存储策略差异。
解决办法
针对这个问题,有两种可靠的解决思路:
- 强制所有文件写入磁盘:显式设置
MultipartConfigElement的fileSizeThreshold参数为0,让所有上传文件都写入指定的临时目录,示例代码如下:// 配置参数:临时目录、单文件最大大小、请求总大小、文件大小阈值(0表示全部写入磁盘) MultipartConfigElement multipartConfig = new MultipartConfigElement( "/tmp_files", 10 * 1024 * 1024, 50 * 1024 * 1024, 0 ); - 统一使用流读取内容:修改代码逻辑,不再依赖磁盘临时文件路径,而是通过
Part.getInputStream()直接读取文件内容,这种方式无论文件存在内存还是磁盘,都能正常工作。
内容的提问来源于stack exchange,提问作者Denis Fadeev
相关产品推荐
相关产品推荐

