【问题标题】:FileNotFoundException (Is a Directory) [duplicate]FileNotFoundException(是一个目录)[重复]
【发布时间】:2015-06-28 03:17:46
【问题描述】:

我目前正在尝试上传多个文件,并且这些文件正在正确上传到目标目录。但在日志中它给了我这个错误:

java.io.FileNotFoundException: /home/sandeep/java_proj/jee_tut/files (Is a directory)

at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
at java.io.FileOutputStream.<init>(FileOutputStream.java:171)
at com.jee.controller.FileProcessing.uploadFiles(FileProcessing.java:35)
at com.jee.controller.View.doPost(View.java:48)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)

这是我上传文件的代码:

final String UPLOAD_DIR="files";

    String applicationPath="/home/sandeep/java_proj/jee_tut";
    String uploadDirPath= applicationPath + File.separator + UPLOAD_DIR;

    try{
        File fileDir=new File(uploadDirPath);
        if(!fileDir.exists()){
            fileDir.mkdirs();
        }
        InputStream inputStream= null;
        OutputStream outputStream = null;
        try{
            for(Part part:request.getParts()){
                String fileName=getFileName(part);

                    File outputPath=new File(uploadDirPath + File.separator + fileName);
                    inputStream = part.getInputStream();
                    outputStream = new FileOutputStream(outputPath);

                    int read = 0;
                    final byte[] bytes = new byte[1024];
                    while((read=inputStream.read(bytes)) != -1){
                        outputStream.write(bytes, 0, read);
                    }
                System.out.println(fileName);
            }
        }catch(Exception e){
            e.printStackTrace();
            return "";
        }
        finally{
            if(inputStream != null){
                inputStream.close();
            }
            if(outputStream != null){
                outputStream.close();
            }
        }
        return uploadDirPath;

    }catch(Exception e){
        e.printStackTrace();
        return "";
    }

由于我是 java 新手,我不确定它为什么会给我这个错误。 我该如何调试?

【问题讨论】:

  • FileProcessing.java 的第35 行,您正试图打开一个FileOutputStream 到一个目录。你不能那样做。
  • 你为什么在 2015 年使用 java.io.File?如果 Java 7+,请改用 java.nio.file。
  • @fge :感谢您的提醒。我将开始使用 Java 7+
  • 看我的答案以获取样本;特别是你泄漏资源是一件坏事。

标签: java jakarta-ee file-upload multipartform-data


【解决方案1】:

这个错误发生在我身上,因为我使用带有完整文件名的file.mkdirs()

假设你的文件路径是emulated/0/test/images/img.jpg

然后从路径中删除最后一部分并在结果文件上使用file.mkdirs()

File file = new File("emulated/0/test/images/")

if (!file.exists()) {
    file.mkdirs();
}

【讨论】:

  • 为我解决了。你必须在调用 mkdirs() 之前调用 makeNewFile()
【解决方案2】:

您的代码中有很多错误。一方面,您只关闭 last InputStreams 和 OutputStreams;你应该关闭它们中的每一个。你在这里做事的方式,你有资源泄漏。

第二,这是 2015 年;因此删除 File 并改用 java.nio.file ;另外,使用 try-with-resources。

第三:现在你上传到项目目录;当应用程序在服务器上“实时”运行时不要这样做,这显然是行不通的。

示例:

private static final Path BASEDIR = Paths.get("/path/to/upload/directory");

// in the upload method:

Files.createDirectories(BASEDIR);

String fileName;
Path path;

for (final Part part: request.getParts()) {
    fileName = getFileName(part);

    if (fileName.isEmpty())
        continue;

    path = BASEDIR.resolve(fileName);

    try (
        final InputStream in = part.getInputStream();
    ) {
        Files.copy(in, path, StandardOpenOption.CREATE_NEW);
    }
}

【讨论】:

  • 这很有帮助。谢谢:)
【解决方案3】:

看起来在某些情况下filename 是空白或空,所以File outputPath=new File(uploadDirPath + File.separator + fileName); 将是一个目录,而这里new FileOutputStream(outputPath); 您尝试写入目录而不是文件。所以你应该检查filename是否不为空。

【讨论】:

  • 我还想指出,看起来像文件的路径实际上可能是目录。例如,“home/test/file.png”可能是一个目录,如果您的代码通过调用文件而不是父目录的 .mkdirs() 出现错误。
猜你喜欢
  • 2021-05-30
  • 2019-01-03
  • 1970-01-01
  • 1970-01-01
  • 2012-06-02
  • 1970-01-01
  • 1970-01-01
  • 2022-07-21
  • 2014-04-18
相关资源
最近更新 更多