Java文件上传遇FileNotFoundException问题求助(同事代码正常)
上传文件报错排查与解决方案
点击上传按钮时,屏幕和控制台返回两类错误:
java.io.FileNotFoundException: /tmp/Filename.docx (No such file or directory)- (permission denied)
java.io.FileNotFoundException: /tmp/MAXWEL-OCHIENG-CAD-Assignment1-.docx (No such file or directory)
协作同事的代码运行完全正常,但本地环境出现该问题,相关上传代码如下:
public static String uploadClientCaseFiles(HttpServletRequest request, HttpServletResponse response) throws IOException{ LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher"); DispatchContext dctx = dispatcher.getDispatchContext(); Delegator delegator = dctx.getDelegator(); String uploadedBy = ""; String folderName = ""; String caseId = ""; String clientId = ""; String comments = ""; String fieldName = ""; String fieldValue = ""; String gdriveFileId = ""; Drive service = null; int maxFileSize = 5000 * 1024; int maxMemSize = 100 * 1024; Map<String, Object> result; File file; boolean isMultipart = ServletFileUpload.isMultipartContent(request); String fileName = ""; String tempDir = System.getProperty("java.io.tmpdir"); try { service = GoogleDriveAPI.getDriveService(); } catch (IOException | GeneralSecurityException e) { e.printStackTrace(); } if(!isMultipart){ //result = ServiceUtil.returnError("Unable to upload file"); return("uploadFailed"); } DiskFileItemFactory factory = new DiskFileItemFactory(); // maximum size that will be stored in memory factory.setSizeThreshold(maxMemSize); // Location to save data that is larger than maxMemSize. factory.setRepository(new File(tempDir)); // Create a new file upload handler ServletFileUpload upload = new ServletFileUpload(factory); // maximum file size to be uploaded. upload.setSizeMax(maxFileSize); try{ // Parse the request to get file items. List fileItems = upload.parseRequest(request); // Process the uploaded file items Iterator i = fileItems.iterator(); while (i.hasNext()) { FileItem fi = (FileItem)i.next(); if (!fi.isFormField()) { // Get the uploaded file parameters fieldName = fi.getFieldName(); fileName = fi.getName(); fileName = fileName.replaceAll("\\s","-"); // Write the file if( fileName.lastIndexOf("\\\\") >= 0 ){ file = new File(tempDir + fileName.substring(fileName.lastIndexOf("\\\\"))); }else{ file = new File(tempDir + fileName.substring(fileName.lastIndexOf("\\\\")+1)); } fi.write(file); } else { fieldName = fi.getFieldName(); fieldValue = fi.getString(); if (fieldName.equals("uploadedBy")) { //logic goes here... uploadedBy = fieldValue; } else if (fieldName.equals("comments")) { //next logic goes here... comments = fieldValue; } else if(fieldName.equals("caseId")){ caseId = fieldValue; }else if (fieldName.equals("clientId")) { //next logic goes here... clientId = fieldValue; } // else if (fieldName.equals("folderName")) { // //next logic goes here... // folderName = fieldValue; // } } } } catch(Exception ex) { System.out.println(ex); } // GenericValue folderName = null; // try { // folderName = delegator.findOne("FolderDriveMapping", // UtilMisc.toMap("folderName", // folderName), false); // } catch (GenericEntityException e2) { // e2.printStackTrace(); // } // if (folderName.f) { // } // Upload to google drive com.google.api.services.drive.model.File fileMetadata = new com.google.api.services.drive.model.File(); fileMetadata.setName(fileName); fileMetadata.setParents(Collections.singletonList("1q9QFwXGmmT6xNHDl5qauIkOqi0PYwWnf")); java.io.File filePath = new java.io.File(tempDir + "/" + fileName); FileContent mediaContent = new FileContent("application/pdf", filePath); com.google.api.services.drive.model.File clientFile = service.files().create(fileMetadata, mediaContent) .setFields("id, name, webContentLink, webViewLink") .execute(); gdriveFileId = clientFile.getId(); /* Get file properties: Id, Name, Link */ log.info("########################## File Name: " + clientFile.getName()); log.info("########################## File ID: " + clientFile.getId()); log.info("########################## Download Link: " + clientFile.getWebContentLink()); log.info("########################## View Link: " + clientFile.getWebViewLink()); GenericValue setup = delegator.makeValue("ClientCaseFiles"); String clientCaseFilesId = delegator.getNextSeqId("ClientCaseFiles"); String ext = fileName.substring(fileName.length() - 3); String mimeType = ""; if((ext.equals("doc")) || (ext.equals("dot")) || (ext.equals("ocx"))){ mimeType = "application/msword"; } else if(ext.equals("pdf")){ mimeType = "application/pdf"; } else if((ext.equals("ppt")) || (ext.equals("ppz")) || (ext.equals("ptx"))){ mimeType = "application/mspowerpoint"; } else if((ext.equals("xls")) || (ext.equals("lsx")) || (ext.equals("xlt"))){ mimeType = "application/x-msexcel"; } else if(ext.equals("zip")){ mimeType = "application/zip"; } else{ mimeType = "text/plain"; } setup.put("clientCaseFilesId", clientCaseFilesId); setup.put("fileName", fileName); setup.put("caseId", caseId); setup.put("clientId", clientId); setup.put("comments", comments); setup.put("uploadedBy", uploadedBy); setup.put("mimeType", mimeType); setup.put("extension", ext); try { setup.create(); } catch (GenericEntityException e) { // TODO Auto-generated catch block e.printStackTrace(); } response.sendRedirect("casefiles?clientId="+clientId+"&caseId="+caseId); return("uplodedSuccesfully"); }
问题原因分析
- 权限不足:本地
/tmp目录(Windows对应系统临时目录)没有写入权限,导致无法创建临时文件 - 路径拼接错误:代码中手动处理路径分隔符的逻辑存在漏洞,不同操作系统(Windows/Unix)下路径格式不兼容,导致生成的文件路径无效
- 异常处理不严谨:捕获异常后仅打印日志,未终止后续流程,导致后续尝试读取未创建成功的文件时触发新异常
解决方案
1. 修复路径拼接逻辑
用File类的构造方法自动处理路径分隔符,避免系统差异:
// 替换原路径拼接代码 // 获取纯文件名(去掉客户端传来的路径部分) String simpleFileName = new File(fileName).getName(); simpleFileName = simpleFileName.replaceAll("\\s","-"); // 用File构造方法拼接路径,自动适配系统分隔符 file = new File(tempDir, simpleFileName); fi.write(file);
2. 修复临时目录权限
- Unix/Linux/macOS:执行命令赋予
/tmp写入权限
或检查运行程序的用户是否拥有chmod 777 /tmp/tmp目录的写入权限 - Windows:找到系统临时目录(一般为
C:\Users\<你的用户名>\AppData\Local\Temp),右键设置当前用户的写入权限
3. 完善异常处理
文件写入失败时直接终止流程,避免后续无效操作:
try{ // ... 其他代码 fi.write(file); } catch(IOException ioEx) { System.err.println("写入临时文件失败: " + ioEx.getMessage()); return "uploadFailed"; } catch(Exception ex) { System.err.println("上传处理异常: " + ex.getMessage()); return "uploadFailed"; }
4. 提前验证临时目录有效性
在代码开头添加目录检查,确保临时目录存在且可写:
String tempDir = System.getProperty("java.io.tmpdir"); File tempDirFile = new File(tempDir); if (!tempDirFile.exists()) { tempDirFile.mkdirs(); } if (!tempDirFile.canWrite()) { System.err.println("临时目录无写入权限: " + tempDir); return "uploadFailed"; }
内容的提问来源于stack exchange,提问作者MAXWEL OCHIENG
相关产品推荐
相关产品推荐

