Servlet上传Excel遇文件未找到异常及临时文件删除方案
Servlet上传Excel文件出现FileNotFoundException的解决方案
问题描述
在Eclipse中基于Tomcat开发Servlet实现Excel文件上传,HTML表单接收文件的代码无语法错误,但控制台持续抛出FileNotFoundException,无法找到上传的文件。
相关代码
try { ServletFileUpload sf=new ServletFileUpload(new DiskFileItemFactory()); List<FileItem> multifiles = sf.parseRequest(request); String file=""; for(FileItem item : multifiles) { file =item.getName(); item.write(new File("C:\Users\khuha\eclipse-workspace\firstDemo\"+ file)); } FileInputStream fis= new FileInputStream(file); XSSFWorkbook wb=new XSSFWorkbook(fis); System.out.println("Enter the sheet you want to search in: "); Scanner sc= new Scanner(System.in); int n= sc.nextInt(); XSSFSheet sheet=wb.getSheetAt(n-1); Iterator<Row> itr=sheet.iterator(); } catch (Exception e) { e.printStackTrace(); }
异常栈信息
INFO: Server startup in 17359 ms java.io.FileNotFoundException: IT_return_FY_22.xlsx (The system cannot find the file specified) at java.base/java.io.FileInputStream.open0(Native Method) at java.base/java.io.FileInputStream.open(FileInputStream.java:216) at java.base/java.io.FileInputStream.<init>(FileInputStream.java:157) at java.base/java.io.FileInputStream.<init>(FileInputStream.java:111) at attendanceApp.fileUpload.doPost(fileUpload.java:51) ...(省略后续栈信息)
问题原因及解决方法
1. 路径错误与文件读取路径不完整
问题:
- Java字符串中反斜杠
\是转义字符,直接写"C:\Users\khuha\eclipse-workspace\firstDemo\"会导致路径解析错误; FileInputStream仅传入文件名file,未带上完整的存储目录,JVM会在Tomcat的bin目录(服务器当前工作目录)查找文件,而非你指定的上传目录。
- Java字符串中反斜杠
解决:
- 将路径中的反斜杠改为双反斜杠
\\或正斜杠/; - 保存文件时记录完整文件路径,读取时使用该完整路径。
- 将路径中的反斜杠改为双反斜杠
2. 未过滤非文件表单字段
- 问题:表单中可能包含普通输入框等非文件字段,
multifiles会包含这些字段,循环处理时会覆盖file变量,导致最终读取的文件名无效。 - 解决:用
item.isFormField()判断是否为文件字段,仅处理文件类型的项。
3. 目录不存在的潜在问题
- 问题:如果指定的上传目录不存在,
item.write()会抛出异常,导致文件未保存。 - 解决:先检查并创建上传目录。
修正后的完整代码
try { ServletFileUpload sf = new ServletFileUpload(new DiskFileItemFactory()); List<FileItem> multifiles = sf.parseRequest(request); // 定义上传目录,使用双反斜杠或正斜杠 String uploadDir = "C:\\Users\\khuha\\eclipse-workspace\\firstDemo\\"; File uploadDirectory = new File(uploadDir); // 若目录不存在则创建 if (!uploadDirectory.exists()) { uploadDirectory.mkdirs(); } String savedFullPath = ""; for (FileItem item : multifiles) { // 仅处理文件字段,跳过普通表单元素 if (!item.isFormField()) { String fileName = item.getName(); // 构建完整的文件存储路径 savedFullPath = uploadDir + fileName; File targetFile = new File(savedFullPath); item.write(targetFile); System.out.println("文件已成功保存至:" + savedFullPath); } } // 检查是否有有效文件被上传 if (!savedFullPath.isEmpty()) { // 使用完整路径读取文件 FileInputStream fis = new FileInputStream(savedFullPath); XSSFWorkbook wb = new XSSFWorkbook(fis); // 注意:Servlet中使用Scanner读取控制台输入不合理,建议改为前端传递参数 System.out.println("输入要查询的工作表序号:"); Scanner sc = new Scanner(System.in); int sheetIndex = sc.nextInt(); XSSFSheet sheet = wb.getSheetAt(sheetIndex - 1); Iterator<Row> rowIterator = sheet.iterator(); // 在这里添加Excel内容处理逻辑... // 关闭资源,避免内存泄漏 fis.close(); wb.close(); sc.close(); // 操作完成后删除临时文件 deleteTempFile(savedFullPath); } else { System.out.println("未检测到有效上传文件"); } } catch (Exception e) { e.printStackTrace(); } // 封装删除临时文件的方法 private void deleteTempFile(String filePath) { File tempFile = new File(filePath); if (tempFile.exists()) { if (tempFile.delete()) { System.out.println("临时文件已删除:" + filePath); } else { System.out.println("临时文件删除失败,可能被占用"); } } }
关键注意事项
- Servlet中禁止使用Scanner读取控制台输入:Tomcat服务器的控制台与前端用户分离,用户无法在前端输入到服务器控制台,建议通过表单参数、AJAX等方式传递工作表序号。
- 资源必须关闭:文件流、Workbook、Scanner等资源使用后必须关闭,否则会导致资源泄漏。
- 文件删除时机:必须在所有流关闭后再删除文件,否则文件处于被占用状态,无法删除。
内容的提问来源于stack exchange,提问作者lord foul
相关产品推荐
相关产品推荐

