java.lang.IllegalStateException:文件已被移动 - 无法再次传输

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16035103/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 21:42:11  来源:igfitidea点击:

java.lang.IllegalStateException: File has already been moved - cannot be transferred again

javaspring-mvcfile-uploadspring-3apache-commons-fileupload

提问by Xavier DSouza

I am trying to upload a file and save it on server. But I get:

我正在尝试上传文件并将其保存在服务器上。但我得到:

java.lang.IllegalStateException: File has already been moved - cannot be transferred again

I am using Commons FileUpload jar(CommonsMultipartFile). I get IllegalStateException for statement : user.getFileData().transferTo(new File("/home/xavier/uploads/" + user.getFileData().getOriginalFilename()));

我正在使用 Commons FileUpload jar(CommonsMultipartFile)。我得到 IllegalStateException for statement : user.getFileData().transferTo(new File("/home/xavier/uploads/" + user.getFileData().getOriginalFilename()));

Here useris the bean. It worked for me initially but when I tested again by deleting the files from uploads folder it threw exception as above.

user是豆子。它最初对我有用,但是当我通过从上传文件夹中删除文件再次进行测试时,它抛出了上述异常。

Stacktrace:

堆栈跟踪:

java.lang.IllegalStateException: File has already been moved - cannot be transferred again
    at org.springframework.web.multipart.commons.CommonsMultipartFile.transferTo(CommonsMultipartFile.java:126)
    at com.raistudies.controllers.RegistrationController.processForm(RegistrationController.java:113)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:754)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
    at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:325)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:226)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:165)
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
    at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)
    at java.lang.Thread.run(Thread.java:722)

回答by Arosha

The exception you reference in your question states: "File has been moved - cannot be read again". This is because we are trying to read inputstream more than one time from multipart file.

您在问题中引用的异常指出:“文件已被移动 - 无法再次读取”。这是因为我们试图从多部分文件中多次读取输入流。

I also faced this issue at one time, and in my case, first I validated the content of the file, and after that I tried to save it using "transferTo" method in Spring MultiPart. This exception comes when I try to use "transferTo" method. Here I am calling for inputstream twice.

我曾经也遇到过这个问题,在我的情况下,首先我验证了文件的内容,然后我尝试使用 Spring MultiPart 中的“transferTo”方法保存它。当我尝试使用“transferTo”方法时会出现此异常。在这里,我两次调用 inputstream。

I do not face this issue when file size is too small. In "transferTo" method there is an internal call for "isAvailable" method. Please follow the code segment below:

当文件太小时,我不会遇到这个问题。在“transferTo”方法中有对“isAvailable”方法的内部调用。请遵循以下代码段:

protected boolean More ...isAvailable() {
        // If in memory, it's available.
    if (this.fileItem.isInMemory()) {
        return true;
    }
    // Check actual existence of temporary file.
    if (this.fileItem instanceof DiskFileItem) {
        return ((DiskFileItem) this.fileItem).getStoreLocation().exists();
    }
    // Check whether current file size is different than original one.
    return (this.fileItem.getSize() == this.size);
}

link: http://grepcode.com/file/repo1.maven.org/maven2/org.springframework/spring-web/3.2.1.RELEASE/org/springframework/web/multipart/commons/CommonsMultipartFile.java#CommonsMultipartFile.isAvailable%28%29

链接:http: //grepcode.com/file/repo1.maven.org/maven2/org.springframework/spring-web/3.2.1.RELEASE/org/springframework/web/multipart/commons/CommonsMultipartFile.java#CommonsMultipartFile。可用%28%29

Observations:

观察:

If it is too small, spring save it in memory and when we ask for the file it retrive from memory. We can ask for it multiple times because file is in memory.

如果它太小,spring 将它保存在内存中,当我们请求文件时,它会从内存中检索。我们可以多次请求它,因为文件在内存中。

If it is large enough, Spring will save it as a temporary file which we do not know the location, but after we read inputstream once that file may be deleted internally by Spring. Then when we ask for the second time that error says "cannot be read again".

如果它足够大,Spring会将它保存为一个我们不知道位置的临时文件,但在我们读取输入流后,该文件可能会被Spring内部删除。然后当我们第二次询问时,该错误提示“无法再次读取”。

So my solution is first I have to save it in server loaction using "transferTo" method and retrive that local file to validate or any other second time need.

所以我的解决方案是首先我必须使用“transferTo”方法将它保存在服务器位置并检索该本地文件以进行验证或任何其他第二次需要。

I think it is not good to increase "maxUploadSize" in "multipartResolver" bean as it consumes more memory if the file is too large.

我认为在“multipartResolver”bean 中增加“maxUploadSize”不好,因为如果文件太大,它会消耗更多内存。

回答by sk2212

It seems that the file is not available as a temporary file (e.g).

该文件似乎不能用作临时文件(例如)。

Just having a look at the code of transferTo()method and calling isAvailablemethod which throws your exception:

只需看看抛出异常的transferTo()方法和调用isAvailable方法的代码:

http://grepcode.com/file/repo1.maven.org/maven2/org.springframework/spring-web/3.2.1.RELEASE/org/springframework/web/multipart/commons/CommonsMultipartFile.java#CommonsMultipartFile.isAvailable%28%29

http://grepcode.com/file/repo1.maven.org/maven2/org.springframework/spring-web/3.2.1.RELEASE/org/springframework/web/multipart/commons/CommonsMultipartFile.java#CommonsMultipartFile.isAvailable% 28%29

In other cases this exception will not be thrown.

在其他情况下,不会抛出此异常。