Go deep into springMVC source code ------ file upload source code parsing (next), springmvc ------

Source: Internet
Author: User

Go deep into springMVC source code ------ file upload source code parsing (next), springmvc ------

In the previous article "go deep into springMVC ------ file upload source code parsing (previous article)", I introduced springmvc file upload. In this article, we will further introduce springmvc's file upload efficiency.

I believe that most people directly obtain the input stream for operations when processing the File Upload logic. The pseudo code is similar to this:

@RequestMapping(value = "/upload", method = RequestMethod.POST)public ResultView upload(@RequestParam("file") MultipartFile file) {    Inputstream in = file.getInputStream();    ...         }

However, for efficiency, I personally recommend using the transferTo method of MultipartFile for operations, such:

@RequestMapping(value = "/upload", method = RequestMethod.POST)public ResultView upload(@RequestParam("file") MultipartFile file) {    file.transferTo(new File(destFile));    ...         }

Why? Let's start with the source code. Let's look at the source code:

1. First read the getInputStream method of MultipartFile (its implementation class CommonsMultipartFile:

CommonsMultipartFile:

public InputStream getInputStream() throws IOException {        if (!isAvailable()) {            throw new IllegalStateException("File has been moved - cannot be read again");        }        InputStream inputStream = this.fileItem.getInputStream();        return (inputStream != null ? inputStream : new ByteArrayInputStream(new byte[0]));    }

From the source code, we can see that spring obtains the input stream through the FileItem object in commons-fileupload, so let's look at the corresponding methods of FileItem (its implementation class DiskFileItem:

DiskFileItem:

public InputStream getInputStream()        throws IOException {        if (!isInMemory()) {            return new FileInputStream(dfos.getFile());        }        if (cachedContent == null) {            cachedContent = dfos.getData();        }        return new ByteArrayInputStream(cachedContent);    }

You can see from the source code: first check whether the object exists in the memory. If yes, wrap the file object in the memory as a file stream. If not, check the cache, if the cache exists, obtain the byte array from the cache and encapsulate it as an input stream.

 

Next, let's take a look at the transferTo method of CommonsMultipartFile to form a comparison:

CommonsMultipartFile:

@Override    public void transferTo(File dest) throws IOException, IllegalStateException {        if (!isAvailable()) {            throw new IllegalStateException("File has already been moved - cannot be transferred again");        }        if (dest.exists() && !dest.delete()) {            throw new IOException(                    "Destination file [" + dest.getAbsolutePath() + "] already exists and could not be deleted");        }        try {            this.fileItem.write(dest);            if (logger.isDebugEnabled()) {                String action = "transferred";                if (!this.fileItem.isInMemory()) {                    action = isAvailable() ? "copied" : "moved";                }                logger.debug("Multipart file '" + getName() + "' with original filename [" +                        getOriginalFilename() + "], stored " + getStorageDescription() + ": " +                        action + " to [" + dest.getAbsolutePath() + "]");            }        }        catch (FileUploadException ex) {            throw new IllegalStateException(ex.getMessage());        }        catch (IOException ex) {            throw ex;        }        catch (Exception ex) {            logger.error("Could not transfer to file", ex);            throw new IOException("Could not transfer to file: " + ex.getMessage());        }    }

Not to mention, we mainly look at this. fileItem. write (dest) and use the related methods in commons-fileupload:

DiskFileItem:

public void write(File file) throws Exception {        if (isInMemory()) {            FileOutputStream fout = null;            try {                fout = new FileOutputStream(file);                fout.write(get());            } finally {                if (fout != null) {                    fout.close();                }            }        } else {            File outputFile = getStoreLocation();            if (outputFile != null) {                // Save the length of the file                size = outputFile.length();........

From the source code, we can see that the transfoTo method is very neat, and directly writes files in the memory to the specified file through the output stream. Wait. Compared with the above getInputStream method, does it save some steps? Yes, let's look at another image to clearly show the differences between the two methods:

Figure:

The red line indicates that the transferTo method is used, and the black line indicates the getInputStream method. It can be seen that transferTo directly writes the files in the memory cache to the physical files on the disk, the getInputStream method will be used once (the stream is obtained from the memory through getInputStream and then output to the disk physical file through outputStream ). Compared with the two, you can see that transferTo is more efficient even from the perspective of steps.

Well, this article is over!

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.