Spring REST上传Jar文件损坏,无法从服务器访问求助
问题分析与修复方案
嘿,我一眼就瞅出你上传Jar文件后损坏的问题所在了——是你的文件写入逻辑有个关键疏漏!
核心错误原因
你用reader.read(buffer)读取数据时,这个方法返回的是本次实际读取到的字节数(最后一次读取大概率会读不满你设置的1000字节缓冲区),但你调用writer.write(buffer)时,直接把整个1000字节的缓冲区都写入了文件。这就会把缓冲区里没被新数据覆盖的旧残留字节也写到文件末尾,而Jar是严格的二进制格式,多余的无效字节直接就把文件搞坏了。
修正后的代码
把写入逻辑改成只写入实际读取到的字节数,同时我推荐用Java 7+的try-with-resources语法,它能自动帮你关闭流,不用再写繁琐的finally块,还能避免资源泄漏:
fileloc = fileloc.replace("$", "/"); String filename = uploadedFileRef.getOriginalFilename(); String path = fileloc + filename; // 缓冲区大小换成4096或者8192会更高效,这是磁盘IO的常见块大小 byte[] buffer = new byte[4096]; File outputFile = new File(path); // try-with-resources会自动关闭括号里的流 try (InputStream reader = uploadedFileRef.getInputStream(); FileOutputStream writer = new FileOutputStream(outputFile)) { outputFile.createNewFile(); int bytesRead = 0; while ((bytesRead = reader.read(buffer)) != -1) { // 只写入实际读取到的那部分字节 writer.write(buffer, 0, bytesRead); } } catch (IOException e) { e.printStackTrace(); // 这里建议换成更友好的错误处理,比如抛出业务异常或者返回错误提示 }
更简洁的Spring方案
其实在Spring环境里,你完全可以不用自己写流读写逻辑,MultipartFile已经封装好了transferTo方法,内部处理了所有细节,既简洁又可靠:
fileloc = fileloc.replace("$", "/"); String filename = uploadedFileRef.getOriginalFilename(); String path = fileloc + filename; File outputFile = new File(path); try { // 一行代码搞定文件上传 uploadedFileRef.transferTo(outputFile); } catch (IOException e) { e.printStackTrace(); }
额外小建议
- 别用
FileInputStream强转,uploadedFileRef.getInputStream()返回的是InputStream父类,直接用父类类型更安全通用。 - 如果担心文件重复,可以加个检查:如果
outputFile已经存在,要么提示用户,要么生成唯一文件名避免覆盖。
内容的提问来源于stack exchange,提问作者Pavan Jois
相关产品推荐
相关产品推荐

