All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ailyr.tool.extra.servlet.multipart.UploadFile Maven / Gradle / Ivy

The newest version!
package com.ailyr.tool.extra.servlet.multipart;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import com.ailyr.tool.core.io.FileUtil;
import com.ailyr.tool.core.io.IoUtil;
import com.ailyr.tool.core.util.StrUtil;
import com.ailyr.tool.log.Log;
import com.ailyr.tool.log.LogFactory;

/**
 * 上传的文件对象
 * 
 * @author xiaoleilu
 * 
 */
public class UploadFile {
	private static Log log = LogFactory.get();

	private static final String TMP_FILE_PREFIX = "hutool-";
	private static final String TMP_FILE_SUFFIX = ".upload.tmp";

	private UploadFileHeader header;
	private UploadSetting setting;
	
	private int size = -1;

	// 文件流(小文件位于内存中)
	private byte[] data;
	// 临时文件(大文件位于临时文件夹中)
	private File tempFile;

	/**
	 * 构造
	 * 
	 * @param header 头部信息
	 * @param setting 上传设置
	 */
	public UploadFile(UploadFileHeader header, UploadSetting setting) {
		this.header = header;
		this.setting = setting;
	}

	// ---------------------------------------------------------------- operations

	/**
	 * 从磁盘或者内存中删除这个文件
	 */
	public void delete() {
		if (tempFile != null) {
			tempFile.delete();
		}
		if (data != null) {
			data = null;
		}
	}

	/**
	 * 将上传的文件写入指定的目标文件路径,自动创建文件
* 写入后原临时文件会被删除 * @param destPath 目标文件路径 * @return 目标文件 * @throws IOException */ public File write(String destPath) throws IOException { if(data != null || tempFile != null) { return write(FileUtil.touch(destPath)); } return null; } /** * 将上传的文件写入目标文件
* 写入后原临时文件会被删除 * * @return 目标文件 */ public File write(File destination) throws IOException { assertValid(); if (destination.isDirectory() == true) { destination = new File(destination, this.header.getFileName()); } if (data != null) { FileUtil.writeBytes(data, destination); data = null; } else { if (tempFile != null) { FileUtil.move(tempFile, destination, true); } } return destination; } /** * Returns the content of file upload item. */ /** * @return 获得文件字节流 * @throws IOException */ public byte[] getFileContent() throws IOException { assertValid(); if (data != null) { return data; } if (tempFile != null) { return FileUtil.readBytes(tempFile); } return null; } /** * @return 获得文件流 * @throws IOException */ public InputStream getFileInputStream() throws IOException { assertValid(); if (data != null) { return new BufferedInputStream(new ByteArrayInputStream(data)); } if (tempFile != null) { return new BufferedInputStream(new FileInputStream(tempFile)); } return null; } // ---------------------------------------------------------------- header /** * @return 上传文件头部信息 */ public UploadFileHeader getHeader() { return header; } /** * @return 文件名 */ public String getFileName() { return header == null ? null : header.getFileName(); } // ---------------------------------------------------------------- properties /** * @return 上传文件的大小,< 0 表示未上传 */ public int size() { return size; } /** * @return 是否上传成功 */ public boolean isUploaded() { return size > 0; } /** * @return 文件是否在内存中 */ public boolean isInMemory() { return data != null; } // ---------------------------------------------------------------- process /** * 处理上传表单流,提取出文件 * * @param input 上传表单的流 * @throws IOException */ protected boolean processStream(MultipartRequestInputStream input) throws IOException { if (!isAllowedExtension()) { // 非允许的扩展名 log.debug("Forbidden uploaded file [{}]", this.getFileName()); size = input.skipToBoundary(); return false; } size = 0; // 处理内存文件 int memoryThreshold = setting.memoryThreshold; if (memoryThreshold > 0) { ByteArrayOutputStream baos = new ByteArrayOutputStream(memoryThreshold); int written = input.copy(baos, memoryThreshold); data = baos.toByteArray(); if (written <= memoryThreshold) { // 文件存放于内存 size = data.length; return true; } } // 处理硬盘文件 tempFile = FileUtil.createTempFile(TMP_FILE_PREFIX, TMP_FILE_SUFFIX, FileUtil.touch(setting.tmpUploadPath), false); BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(tempFile)); if (data != null) { size = data.length; out.write(data); data = null; // not needed anymore } int maxFileSize = setting.maxFileSize; try { if (maxFileSize == -1) { size += input.copy(out); return true; } size += input.copy(out, maxFileSize - size + 1); // one more byte to detect larger files if (size > maxFileSize) { // 超出上传大小限制 tempFile.delete(); tempFile = null; log.debug("Upload file [{}] too big, file size > [{}]", this.getFileName(), maxFileSize); input.skipToBoundary(); return false; } } finally { IoUtil.close(out); } // if (getFileName().length() == 0 && size == 0) { // size = -1; // } return true; } // ---------------------------------------------------------------------------- Private method start /** * @return 是否为允许的扩展名 */ private boolean isAllowedExtension() { String[] exts = setting.fileExts; boolean isAllow = setting.isAllowFileExts; if (exts == null || exts.length == 0) { // 如果给定扩展名列表为空,当允许扩展名时全部允许,否则全部禁止 return isAllow; } String fileNameExt = FileUtil.extName(this.getFileName()); for (String fileExtension : setting.fileExts) { if (fileNameExt.equalsIgnoreCase(fileExtension)) { return isAllow; } } // 未匹配到扩展名,如果为允许列表,返回false, 否则true return !isAllow; } /** * 断言是否文件流可用 * @throws IOException */ private void assertValid() throws IOException { if(! isUploaded()) { throw new IOException(StrUtil.format("File [{}] upload fail", getFileName())); } } // ---------------------------------------------------------------------------- Private method end }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy