文件、图片上传,下载预览的实现

需求:将文件、图片进行上传,图片进行预览

实现:

1.相关工具类

package common.util;

import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.security.AccessController;
import java.security.PrivilegedAction;

public class FileOperateUtil {
	
	
	/**
	 * 创建文件
	 * @param filePath
	 * @return
	 */
	public static File createFile(String filePath){
		
		File localFile = new File(filePath);		
		if (!localFile.exists()) {
			   if( !localFile.getParentFile().exists())
				   localFile.getParentFile().mkdirs();
			   try {
				   localFile.createNewFile();
			   } catch (IOException e) {
				   // TODO Auto-generated catch block
				   e.printStackTrace();
			   }
		}
			 
		return localFile;
	}
	
	
	/**
	 * 创建文件
	 * @param file
	 * @return
	 */
	public static File createFile(File file){
		
		File localFile = file;		
		if (!localFile.exists()) {
			   if( !localFile.getParentFile().exists())
				   localFile.getParentFile().mkdirs();
			   try {
				   localFile.createNewFile();
			   } catch (IOException e) {
				   // TODO Auto-generated catch block
				   e.printStackTrace();
			   }
		}
			 
		return localFile;
	}
	
	
	
	/**
	 * 读取文件内容转化为字节流
	 * @param file
	 * @return
	 */
	public static byte[] byteFromFile(File file){
					
		try (ByteArrayOutputStream out=new ByteArrayOutputStream((int)file.length());						
				FileInputStream fins=new FileInputStream(file);			
			){			
				byte[] bytes=new byte[1024*4];
				int result=0;			
				while((result=fins.read(bytes))!=-1){
					out.write(bytes, 0, result);	
				}
			
				return out.toByteArray();
				
		}catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
					
		return new byte[0];
	}
	
	
	/**
	 * 复制源文件内容到目标文件
	 * @param fileSrcPath
	 * @param fileDestPath
	 * @return
	 */
	public static long fileCopy(String fileSrcPath,String fileDestPath){
		
		 try {
			Path src= Paths.get(new URI(fileSrcPath));
            OutputStream out=Files.newOutputStream(Paths.get(URI.create(fileDestPath)), StandardOpenOption.WRITE);
		   return  Files.copy(src, out);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		  
		  return 0;
		  	
	}
	
	
	/**
	 * 快速复制源文件内容到目标文件
	 * @param fileSrcPath
	 * @param fileDestPath
	 * @return
	 */
	public static long fileCopy(File fileSrcPath,File fileDestPath){
		
		 long size=0;
		
		 try (  FileInputStream  ins = new FileInputStream(fileSrcPath);
				FileOutputStream outs = new FileOutputStream(fileDestPath)){
			    byte[] bytes =new byte[1024*16];
			    int result=0;
			    while((result=ins.read(bytes))!=-1){
			    	outs.write(bytes, 0, result);
			    }
			    size=fileSrcPath.length();
			// fileSrcPath.delete();//文件复制完成后,删除源文件
		 }catch(Exception e){
			 e.printStackTrace();
		 }
		 
		 return size;
	}
	
	
	/**
	 * 快速复制源文件内容到目标文件
	 * @param inps
	 * @param fileDestPath
	 * @return
	 */
	public static long inputCopy(InputStream inps,File fileDestPath){
		
		 long size=0;
		 try (  InputStream  ins = inps;
				FileOutputStream outs = new FileOutputStream(fileDestPath)){
			    byte[] bytes =new byte[1024*16];
			    int result=0;
			    while((result=ins.read(bytes))!=-1){
			    	outs.write(bytes, 0, result);
			    }
			    
			    size=fileDestPath.length();			
		 }catch(Exception e){
			 e.printStackTrace();
		 }
		 
		 return size;
	}
	
	
	/**
	 * 快速复制源文件内容到目标文件
	 * @param fileSrcPath
	 * @param fileDestPath
	 * @return
	 */
	public static long fileFastCopy(File fileSrcPath,File fileDestPath){
		
		 long size=0;
		
		 try (  FileChannel  in = new FileInputStream(fileSrcPath).getChannel();
				FileChannel out = new FileOutputStream(fileDestPath).getChannel()){
			 size = in.size();
			 MappedByteBuffer buf = in.map(FileChannel.MapMode.READ_ONLY, 0, size);
			 out.write(buf);
			 in.close();
			 out.close();
			 //关闭缓冲区
			 clean(buf);
			// fileSrcPath.delete();//文件复制完成后,删除源文件
		 }catch(Exception e){
			 e.printStackTrace();
		 }
		 
		 return size;
	}
	
	

	/**
	 * 关闭缓冲区
	 * @param buffer
	 * @throws Exception
	 */
	private  static void clean(final Object buffer) throws Exception {
		 
		 AccessController.doPrivileged(new PrivilegedAction(){
			 	public Object run(){
				 try{
					 	Method getCleanerMethod = buffer.getClass().getMethod("cleaner",new Class[0]);
					 	getCleanerMethod.setAccessible(true);
					 	sun.misc.Cleaner cleaner =(sun.misc.Cleaner)getCleanerMethod.invoke(buffer,new Object[0]);
					 	cleaner.clean();
				 }catch(Exception e){
					 e.printStackTrace();
				 }
				 
				 return null;
				 
				 }
		 	});
		 
	}
	
	
	/**
	 * 从文件获取读入流
	 * @param file
	 * @return
	 */
	public static  InputStream inputStreamFromFile(File file){
		
		 InputStream  ins=null;
		  
		 try {
			 ins=new FileInputStream(file);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		  
		  return ins;
		    
	}
	
	/**
	 * 输入的流的内容写入到输出流(自动关闭流)
	 * @param inps
	 * @param ous
	 * @param call 的,两个参数 第一个是读入的字节数,第二个是已读入内容的字节数组
	 * @return
	 */
	public static <T> Object readToOutStream(InputStream  inps,OutputStream ous, ParamRun<T>  call){
		
		 Long size=0l;
		 T obj=null;
		 try (  InputStream  ins = inps;
				OutputStream outs = ous){
			    byte[] bytes =new byte[1024*16];
			    int result=0;
			    while((result=ins.read(bytes))!=-1){
			    	size+=result;
			    	outs.write(bytes, 0, result);
			    	if(call!=null)
			    		obj=call.run(result,bytes);
			    }			  
			    	
		 }catch(Exception e){
			 e.printStackTrace();
		 }
		   
		 return obj==null ? size : obj;
	}
	
	
	/**
	 * 输入的流的内容写入到输出流(自动关闭流)
	 * @param inps
	 * @param ous
	 * @return
	 */
	public static <T> Object readToOutStream(InputStream  inps,OutputStream ous){
		
		return readToOutStream(inps, ous, null);		
	}
	
	
	/**
	 * 输入流的内容写入到输出流(不关闭流)
	 * @param inps
	 * @param ous
	 * @return
	 */
	public static <T> Object readToOutStreamNotClose(InputStream  inps,OutputStream ous){
		
		return readToOutStreamNotClose(inps, ous, null);
	}
	
	
	/**
	 * 输入流的内容写入到输出流(不关闭流)
	 * @param inps
	 * @param ous
	 * @param call 的,两个参数 第一个是读入的字节数,第二个是已读入内容的字节数组
	 * @return
	 */
	public static <T> Object readToOutStreamNotClose(InputStream  inps,OutputStream ous, ParamRun<T>  call){
		
		 Long size=0l;
		 T obj=null;
		 try {  InputStream  ins = inps;
				OutputStream outs = ous;
			    byte[] bytes =new byte[1024*16];
			    int result=0;
			    while((result=ins.read(bytes))!=-1){
			    	size+=result;
			    	outs.write(bytes, 0, result);
			    	if(call!=null)
			    		obj=call.run(result,bytes);
			    }			  
			    	
		 }catch(Exception e){
			 e.printStackTrace();
		 }
		   
		 return obj==null ? size : obj;
	}
	
	
	
	
	
	/**
	 * 带参数的运行接口
	 * @author Administrator
	 *
	 * @param <T>
	 */
	@FunctionalInterface
	public static interface  ParamRun<T>{
		
		public  T run(Object ... param);
		
		
	}
	
	
	/**
	 * 复制文件到目标路径
	 * @param srcFile
	 * @param fileName
	 * @param destPath 目标路径
	 * @return
	 */
	public static String copydFile(InputStream srcFile ,String fileName,String destPath){
		
		File fileDest=new File(destPath);
		if(!fileDest.exists()){
			try {
				fileDest.mkdirs();
			} catch (Exception e) {	
			
				//e.printStackTrace();
				throw new RuntimeException(e);
			}
		}	
		
		fileDest=new File(destPath+"/"+fileName);
			InputStream ins=null;
			FileOutputStream fous=null;	
			try {
				if(!fileDest.exists())
					fileDest.createNewFile();
				ins=srcFile;
				fous=new FileOutputStream(fileDest);
				byte[] bytes=new byte[2048*2];
				int result=0;
				while((result=ins.read(bytes))!=-1){
					fous.write(bytes, 0, result);
				}		
							
			} catch (Exception e) {
				//e.printStackTrace();
				//如果出异常则将文件名置为空字串
				fileName="";
				
				throw new RuntimeException(e);
			
			}finally{
				try {
					if(ins!=null)
						ins.close();
					if(fous!=null)
						fous.close();
				} catch (IOException e) {				
					e.printStackTrace();
				}								
			}
		
		return fileName;				
	}
	
	
	/**
	 * 文上传
	 * @param file
	 * @param req
	 * @return
	 */
	public static String upLoadFile(MultipartFile file,String destPath){
		
		String fileName=file.getOriginalFilename();
		fileName=produceFileName(fileName);		
		//String destPath=Constants.getAppVal("defaultFilegPath");			
		try {
			fileName=copydFile(file.getInputStream(),fileName,destPath);
			
			return fileName;
		} catch (IOException e) {
			//e.printStackTrace();
			System.err.println("[=====复制传输文件异常=====文件名:["+fileName+"]=====目标路径:["+destPath+"]");
		}
		
		return null;
	}
	
	/**
	 * 用当前系统的时间戳,重新生成新的文件名
	 * 格式:新文件名=[文件名]+"__"+[系统时间戳]+"."+[原文件扩展名]
	 * @param srcName
	 * @return
	 */
	public static String produceFileName(String srcName){
		
		long time=System.currentTimeMillis();
		int index=srcName.lastIndexOf(".");
		String finalName="";
		 
		if(index>0){			
			String preFixName=srcName.substring(0,index);
			String sufixName=srcName.substring(index);			
			finalName=preFixName+"__"+time+sufixName;			
		}else{
			return srcName+"__"+time;			
		}
		
		return finalName;
	}
		
	public static void writeFile(String strUrl,String fileName,String savePath){
		URL url = null;
		try {
			url = new URL(strUrl);
		} catch (MalformedURLException e2) {
			e2.printStackTrace();
		}
		InputStream is = null;

		try {

			is = url.openStream();
		} catch (IOException e1) {

			e1.printStackTrace();
		}
		OutputStream os = null;
//			File f = new File("F:\\home\\static_res\\com");
		File f = new File(savePath);
		f.mkdirs();
		try{
			os = new FileOutputStream(savePath+fileName);
			int bytesRead = 0;
			byte[] buffer = new byte[8192];

			try {

				while((bytesRead = is.read(buffer,0,8192))!=-1){
					os.write(buffer,0,bytesRead);
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}catch(FileNotFoundException e){

			e.printStackTrace();
		}
	}
	/**
	 * 删除目录及目录下的文件
	 *
	 * @param dir
	 *            要删除的目录的文件路径
	 * @return 目录删除成功返回true,否则返回false
	 */
	public static boolean deleteDirectory(String dir) {
		// 如果dir不以文件分隔符结尾,自动添加文件分隔符
		if (!dir.endsWith(File.separator))
			dir = dir + File.separator;
		File dirFile = new File(dir);
		// 如果dir对应的文件不存在,或者不是一个目录,则退出
		if ((!dirFile.exists()) || (!dirFile.isDirectory())) {
			System.out.println("删除目录失败:" + dir + "不存在!");

			//创建一个文件夹
			dirFile.mkdirs();
			return false;
		}
		boolean flag = true;
		// 删除文件夹中的所有文件包括子目录
		File[] files = dirFile.listFiles();
		for (int i = 0; i < files.length; i++) {
			// 删除子文件
			if (files[i].isFile()) {
				flag = FileOperateUtil.deleteFile(files[i].getAbsolutePath());
				if (!flag)
					break;
			}
			// 删除子目录
			else if (files[i].isDirectory()) {
				flag = FileOperateUtil.deleteDirectory(files[i]
						.getAbsolutePath());
				if (!flag)
					break;
			}
		}
		if (!flag) {
			System.out.println("删除目录失败!");
			return false;
		}
		// 删除当前目录
		if (dirFile.delete()) {
			System.out.println("删除目录" + dir + "成功!");
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 删除单个文件
	 *
	 * @param fileName
	 *            要删除的文件的文件名
	 * @return 单个文件删除成功返回true,否则返回false
	 */
	public static boolean deleteFile(String fileName) {
		File file = new File(fileName);
		// 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
		if (file.exists() && file.isFile()) {
			if (file.delete()) {
				System.out.println("删除单个文件" + fileName + "成功!");
				return true;
			} else {
				System.out.println("删除单个文件" + fileName + "失败!");
				return false;
			}
		} else {
			System.out.println("删除单个文件失败:" + fileName + "不存在!");
			return false;
		}
	}

	/**
	 *
	 * @Title
	 * @Description 
	 * @author
	 * @param 
	 * @return 
	 * @date  2021-04-27 10:57
	 */   
	public static String getFileExtName(File file){
		String fileName = file.getName();
		String suffix = fileName.substring(fileName.lastIndexOf("."));
		return suffix;
	}

}

2.文件、图片实现代码

   @Value("${staticRes}")
    private String staticRes;
    /**
     * description文件上传
     * param [request, response, file, from, userId, orgCode]
     * return common.enums.ResultVO
     * author 
     * createTime 2021/11/26 11:37
     **/
    @PostMapping("/files")
    public ResultVO uploadFile(HttpServletRequest request, HttpServletResponse response, MultipartFile file, String from, String userId, String orgCode) {

        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
        if (multipartResolver.isMultipart(request)) {
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            Iterator<String> it = multipartRequest.getFileNames();
            while (it.hasNext()) {
                //System.out.println("=============="+(String)it.next());
                List<MultipartFile> multipartFiles = multipartRequest.getFiles((String) it.next());
                for (MultipartFile multipartFile : multipartFiles) {
                    file = multipartFile;
                    break;
                }
            }
        }
        if (file == null) {
            return new ResultVO(ResultCode.FAILED, "文件的内容为空,请确认文件是否选择正确!");
        }

        String fileDir = request.getRequestURI();

        long size = file.getSize();
        String fileName = file.getOriginalFilename();

        try {
            fileName = URLDecoder.decode(fileName, "UTF-8");
        } catch (UnsupportedEncodingException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        if (fileName.contains(" ")) {
            return new ResultVO(ResultCode.FAILED, "文件名包含非法空格");
        } else if (fileName.contains("&")) {
            return new ResultVO(ResultCode.FAILED, "文件名包含非法&");
        } else if (fileName.contains("?")) {
            return new ResultVO(ResultCode.FAILED, "文件名包含非法?");
        }
        fileName = FileOperateUtil.produceFileName(fileName);

        String imgPath = staticRes + "/files/" + orgCode + "/" + from + "/" + userId + "/" + DateUtil.formatDate(new Date(), "yyyy-MM-dd") + "/" + fileName;
        String realPath = imgPath;
        System.out.println("===========file real path:" + realPath);
        File tmFile = new File(realPath);
        tmFile = FileOperateUtil.createFile(tmFile);

        long before = size;

        JSONObject result = new JSONObject();

        try {

            size = FileOperateUtil.inputCopy(file.getInputStream(), tmFile);
            result.put("fileName", fileName);
            result.put("size", file.getSize());
            result.put("contentType", HttpClientUtil.getMimeType(tmFile.getName()));
            String localUrl = request.getContextPath() + "/down/files/" + orgCode + "/" + from + "/" + userId + "/" + DateUtil.formatDate(new Date(), "yyyy-MM-dd") + "/" + fileName;
            result.put("localUrl", localUrl);
        } catch (IOException e) {
            return new ResultVO(ResultCode.FAILED, "服务器文件写入失败!");
        }

        if (size < before) {
            return new ResultVO(ResultCode.FAILED, "服务器文件写入失败!");
        }

        System.out.println("========result back  result Json:" + result.toString());

        return new ResultVO(ResultCode.SUCCESS, result);
    }

3.文件下载,图片预览的实现


    @Value("${staticRes}")
    private String staticRes;

    /**
     * description 文件下载器
     * param [request, response]
     * return common.enums.ResultVO
     * author 
     * createTime 2021/11/26 11:40
     **/
    @GetMapping("/files/**")
    public ResultVO downFiles(HttpServletRequest request, HttpServletResponse response) {

        String fileUrl = request.getRequestURI();
        try {
            fileUrl = URLDecoder.decode(fileUrl, "UTF-8");
        } catch (UnsupportedEncodingException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        fileUrl = fileUrl.substring(fileUrl.indexOf("/files") + 6);

        String imgPath = staticRes + "/files" + fileUrl;
        String realPath = imgPath;
        File tmFile = new File(realPath);

        if ((!tmFile.exists()) || tmFile.length() < 1) {

            return new ResultVO(ResultCode.FAILED, "文件不存在!");
        }
        try {
            InputStream ins = FileOperateUtil.inputStreamFromFile(tmFile);
            String filename = tmFile.getName();
            filename = new String(filename.getBytes("utf-8"), "iso-8859-1");
            //response.setHeader("Content-Disposition", "attachment; filename=" + filename);
            OutputStream ous = response.getOutputStream();
            Long size = (Long) FileOperateUtil.readToOutStream(ins, ous, null);

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return new ResultVO(ResultCode.SUCCESS, "下载成功");
    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值