SpringMVC文件上传MultipartFile接口、FileItem接口、DiskFileItem实现类介绍

一.具体类和方法

上传文件主要方法是transferTo(),可以将某个文件复制保存到新的路径中。

Multipart接口的实现类CommonsMultipartFile类,有个保存文件到新路径的方法transferTo(),调用了FileItem接口的方法write(),
FileItem接口的实现类DiskFileItem类

二.MultipartFile接口源码如下:

复制代码
public interface MultipartFile {
    String getName();

    //获取文件原名(不包含路径)
    String getOriginalFilename();

    //获取上传文件的类型
    String getContentType();

    boolean isEmpty();

    long getSize();

    byte[] getBytes() throws IOException;

    InputStream getInputStream() throws IOException;

    //保存到一个目标文件中
    void transferTo(File var1) throws IOException, IllegalStateException;
}
复制代码

2.MultipartFile接口的实现类CommonsMultipartFile源码如下:

复制代码
public class CommonsMultipartFile implements MultipartFile, Serializable {
    protected static final Log logger = LogFactory.getLog(CommonsMultipartFile.class);
    private final FileItem fileItem;
    private final long size;

    public CommonsMultipartFile(FileItem fileItem) {
        this.fileItem = fileItem;
        this.size = this.fileItem.getSize();
    }

    public final FileItem getFileItem() {
        return this.fileItem;
    }

    public String getName() {
        return this.fileItem.getFieldName();
    }

    public String getOriginalFilename() {
        String filename = this.fileItem.getName();
        if(filename == null) {
            return "";
        } else {
            int pos = filename.lastIndexOf("/");
            if(pos == -1) {
                pos = filename.lastIndexOf("\\");
            }

            return pos != -1?filename.substring(pos + 1):filename;
        }
    }

    public String getContentType() {
        return this.fileItem.getContentType();
    }

    public boolean isEmpty() {
        return this.size == 0L;
    }

    public long getSize() {
        return this.size;
    }

    public byte[] getBytes() {
        if(!this.isAvailable()) {
            throw new IllegalStateException("File has been moved - cannot be read again");
        } else {
            byte[] bytes = this.fileItem.get();
            return bytes != null?bytes:new byte[0];
        }
    }

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

    public void transferTo(File dest) throws IOException, IllegalStateException {
        if(!this.isAvailable()) {
            throw new IllegalStateException("File has already been moved - cannot be transferred again");
        } else if(dest.exists() && !dest.delete()) {
            throw new IOException("Destination file [" + dest.getAbsolutePath() + "] already exists and could not be deleted");
        } else {
            try {
                this.fileItem.write(dest);
                if(logger.isDebugEnabled()) {
                    String ex = "transferred";
                    if(!this.fileItem.isInMemory()) {
                        ex = this.isAvailable()?"copied":"moved";
                    }

                    logger.debug("Multipart file \'" + this.getName() + "\' with original filename [" + this.getOriginalFilename() + "], stored " + this.getStorageDescription() + ": " + ex + " to [" + dest.getAbsolutePath() + "]");
                }

            } catch (FileUploadException var3) {
                throw new IllegalStateException(var3.getMessage());
            } catch (IOException var4) {
                throw var4;
            } catch (Exception var5) {
                logger.error("Could not transfer to file", var5);
                throw new IOException("Could not transfer to file: " + var5.getMessage());
            }
        }
    }

    protected boolean isAvailable() {
        return this.fileItem.isInMemory()?true:(this.fileItem instanceof DiskFileItem?((DiskFileItem)this.fileItem).getStoreLocation().exists():this.fileItem.getSize() == this.size);
    }

    public String getStorageDescription() {
        return this.fileItem.isInMemory()?"in memory":(this.fileItem instanceof DiskFileItem?"at [" + ((DiskFileItem)this.fileItem).getStoreLocation().getAbsolutePath() + "]":"on disk");
    }
}
复制代码

 三.FileItem接口,具体的api介绍如以下链接:

http://www.jb51.net/article/90331.htm

1.  boolean isFormField()
isFormField方法用于判断FileItem类对象封装的数据是一个普通文本表单字段,还是一个文件表单字段,如果是普通表单字段则返回true,否则返回false。因此,可以使用该方法判断是否为普通表单域,还是文件上传表单域。
2.  String getName()
getName方法用于获得文件上传字段中的文件名。
注意IE或FireFox中获取的文件名是不一样的,IE中是绝对路径,FireFox中只是文件名。
3.  String getFieldName()
getFieldName方法用于返回表单标签name属性的值。如上例中<input type="text" name="column" />的value。
4.  void write(File file)
write方法用于将FileItem对象中保存的主体内容保存到某个指定的文件中。如果FileItem对象中的主体内容是保存在某个临时文件中,该方法顺利完成后,临时文件有可能会被清除。该方法也可将普通表单字段内容写入到一个文件中,但它主要用途是将上传的文件内容保存在本地文件系统中。
5.  String getString()
getString方法用于将FileItem对象中保存的数据流内容以一个字符串返回,它有两个重载的定义形式:
public java.lang.String getString()
public java.lang.String getString(java.lang.String encoding)
throws java.io.UnsupportedEncodingException
前者使用缺省的字符集编码将主体内容转换成字符串,后者使用参数指定的字符集编码将主体内容转换成字符串。如果在读取普通表单字段元素的内容时出现了中文乱码现象,请调用第二个getString方法,并为之传递正确的字符集编码名称。
6.  String getContentType()
getContentType 方法用于获得上传文件的类型,即表单字段元素描述头属性“Content-Type”的值,如“image/jpeg”。如果FileItem类对象对应的是普通表单字段,该方法将返回null。
7.  boolean isInMemory()
isInMemory方法用来判断FileItem对象封装的数据内容是存储在内存中,还是存储在临时文件中,如果存储在内存中则返回true,否则返回false。
8.  void delete()
delete方法用来清空FileItem类对象中存放的主体内容,如果主体内容被保存在临时文件中,delete方法将删除该临时文件。
尽管当FileItem对象被垃圾收集器收集时会自动清除临时文件,但及时调用delete方法可以更早的清除临时文件,释放系统存储资源。另外,当系统出现异常时,仍有可能造成有的临时文件被永久保存在了硬盘中。
9.  InputStream getInputStream()
以流的形式返回上传文件的数据内容。
10. long getSize()
返回该上传文件的大小(以字节为单位)。

 

四.FileItem的实现类DiskFileItem源码如下:

重点看write()方法。

复制代码
public class DiskFileItem implements FileItem {
    private static final long serialVersionUID = 2237570099615271025L;
    public static final String DEFAULT_CHARSET = "ISO-8859-1";
    private static final String UID = UUID.randomUUID().toString().replace('-', '_');
    private static final AtomicInteger COUNTER = new AtomicInteger(0);
    private String fieldName;
    private final String contentType;
    private boolean isFormField;
    private final String fileName;
    private long size = -1L;
    private final int sizeThreshold;
    private final File repository;
    private byte[] cachedContent;
    private transient DeferredFileOutputStream dfos;
    private transient File tempFile;
    private File dfosFile;
    private FileItemHeaders headers;

    public DiskFileItem(String fieldName, String contentType, boolean isFormField, String fileName, int sizeThreshold, File repository) {
        this.fieldName = fieldName;
        this.contentType = contentType;
        this.isFormField = isFormField;
        this.fileName = fileName;
        this.sizeThreshold = sizeThreshold;
        this.repository = repository;
    }

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

            return new ByteArrayInputStream(this.cachedContent);
        }
    }

    public String getContentType() {
        return this.contentType;
    }

    public String getCharSet() {
        ParameterParser parser = new ParameterParser();
        parser.setLowerCaseNames(true);
        Map params = parser.parse(this.getContentType(), ';');
        return (String)params.get("charset");
    }

    public String getName() {
        return Streams.checkFileName(this.fileName);
    }

    public boolean isInMemory() {
        return this.cachedContent != null?true:this.dfos.isInMemory();
    }

    public long getSize() {
        return this.size >= 0L?this.size:(this.cachedContent != null?(long)this.cachedContent.length:(this.dfos.isInMemory()?(long)this.dfos.getData().length:this.dfos.getFile().length()));
    }

    public byte[] get() {
        if(this.isInMemory()) {
            if(this.cachedContent == null) {
                this.cachedContent = this.dfos.getData();
            }

            return this.cachedContent;
        } else {
            byte[] fileData = new byte[(int)this.getSize()];
            BufferedInputStream fis = null;

            try {
                fis = new BufferedInputStream(new FileInputStream(this.dfos.getFile()));
                fis.read(fileData);
            } catch (IOException var12) {
                fileData = null;
            } finally {
                if(fis != null) {
                    try {
                        fis.close();
                    } catch (IOException var11) {
                        ;
                    }
                }

            }

            return fileData;
        }
    }

    public String getString(String charset) throws UnsupportedEncodingException {
        return new String(this.get(), charset);
    }

    public String getString() {
        byte[] rawdata = this.get();
        String charset = this.getCharSet();
        if(charset == null) {
            charset = "ISO-8859-1";
        }

        try {
            return new String(rawdata, charset);
        } catch (UnsupportedEncodingException var4) {
            return new String(rawdata);
        }
    }

    public void write(File file) throws Exception {
        if(this.isInMemory()) {
            FileOutputStream outputFile = null;

            try {
                outputFile = new FileOutputStream(file);
                outputFile.write(this.get());
            } finally {
                if(outputFile != null) {
                    outputFile.close();
                }

            }
        } else {
            File outputFile1 = this.getStoreLocation();
            if(outputFile1 == null) {
                throw new FileUploadException("Cannot write uploaded file to disk!");
            }

            this.size = outputFile1.length();
            if(!outputFile1.renameTo(file)) {
                BufferedInputStream in = null;
                BufferedOutputStream out = null;

                try {
                    in = new BufferedInputStream(new FileInputStream(outputFile1));
                    out = new BufferedOutputStream(new FileOutputStream(file));
                    IOUtils.copy(in, out);
                } finally {
                    if(in != null) {
                        try {
                            in.close();
                        } catch (IOException var19) {
                            ;
                        }
                    }

                    if(out != null) {
                        try {
                            out.close();
                        } catch (IOException var18) {
                            ;
                        }
                    }

                }
            }
        }

    }

    public void delete() {
        this.cachedContent = null;
        File outputFile = this.getStoreLocation();
        if(outputFile != null && outputFile.exists()) {
            outputFile.delete();
        }

    }

    public String getFieldName() {
        return this.fieldName;
    }

    public void setFieldName(String fieldName) {
        this.fieldName = fieldName;
    }

    public boolean isFormField() {
        return this.isFormField;
    }

    public void setFormField(boolean state) {
        this.isFormField = state;
    }

    public OutputStream getOutputStream() throws IOException {
        if(this.dfos == null) {
            File outputFile = this.getTempFile();
            this.dfos = new DeferredFileOutputStream(this.sizeThreshold, outputFile);
        }

        return this.dfos;
    }

    public File getStoreLocation() {
        return this.dfos == null?null:this.dfos.getFile();
    }

    protected void finalize() {
        File outputFile = this.dfos.getFile();
        if(outputFile != null && outputFile.exists()) {
            outputFile.delete();
        }

    }

    protected File getTempFile() {
        if(this.tempFile == null) {
            File tempDir = this.repository;
            if(tempDir == null) {
                tempDir = new File(System.getProperty("java.io.tmpdir"));
            }

            String tempFileName = String.format("upload_%s_%s.tmp", new Object[]{UID, getUniqueId()});
            this.tempFile = new File(tempDir, tempFileName);
        }

        return this.tempFile;
    }

    private static String getUniqueId() {
        int limit = 100000000;
        int current = COUNTER.getAndIncrement();
        String id = Integer.toString(current);
        if(current < 100000000) {
            id = ("00000000" + id).substring(id.length());
        }

        return id;
    }

    public String toString() {
        return String.format("name=%s, StoreLocation=%s, size=%s bytes, isFormField=%s, FieldName=%s", new Object[]{this.getName(), this.getStoreLocation(), Long.valueOf(this.getSize()), Boolean.valueOf(this.isFormField()), this.getFieldName()});
    }

    private void writeObject(ObjectOutputStream out) throws IOException {
        if(this.dfos.isInMemory()) {
            this.cachedContent = this.get();
        } else {
            this.cachedContent = null;
            this.dfosFile = this.dfos.getFile();
        }

        out.defaultWriteObject();
    }

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        if(this.repository != null) {
            if(!this.repository.isDirectory()) {
                throw new IOException(String.format("The repository [%s] is not a directory", new Object[]{this.repository.getAbsolutePath()}));
            }

            if(this.repository.getPath().contains("\u0000")) {
                throw new IOException(String.format("The repository [%s] contains a null character", new Object[]{this.repository.getPath()}));
            }
        }

        OutputStream output = this.getOutputStream();
        if(this.cachedContent != null) {
            output.write(this.cachedContent);
        } else {
            FileInputStream input = new FileInputStream(this.dfosFile);
            IOUtils.copy(input, output);
            this.dfosFile.delete();
            this.dfosFile = null;
        }

        output.close();
        this.cachedContent = null;
    }

    public FileItemHeaders getHeaders() {
        return this.headers;
    }

    public void setHeaders(FileItemHeaders pHeaders) {
        this.headers = pHeaders;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_39805338/article/details/80923038