1. 程式人生 > >javaWeb向伺服器上傳和下載檔案

javaWeb向伺服器上傳和下載檔案

專案經常需要向伺服器上傳檔案或者從伺服器下載檔案,因此將所需要的許多方法整理到了一個工具類中,包括從伺服器下載流檔案,上傳檔案到伺服器(用Apache和spring不同的方法),希望能幫助到大家。

package com.phy.szms.utils;

import java.awt.image.BufferedImage;
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 java.io.OutputStream;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;



import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class UploadFileUtils {
	
	public static final String UPLOAD_SUCCESS = "upload success";
	
	public static final String UPLOAD_FAIL = "upload fail";
	
	public static final String UPLOAD_OVER_MAX_SIZE = "single file more than max size";
	
	public static BASE64Encoder encoder = new BASE64Encoder();
	public static BASE64Decoder decoder = new BASE64Decoder();
	
	public static String uploadByCommon(HttpServletRequest request) {
		//得到上傳檔案的儲存目錄,將上傳的檔案存放於WEB-INF目錄下,不允許外界直接訪問,保證上傳檔案的安全
		String savePath = request.getServletContext().getRealPath("WEB-INF/upload");
		//上傳時生成的臨時檔案儲存目錄
		String tempPath = request.getServletContext().getRealPath("temp");
		File tempFile = new File(tempPath);
		if (!tempFile.exists()) {
			//建立臨時目錄
			tempFile.mkdir();
		}
		//訊息提示
		String message = "";
		try {
			//使用Apache檔案上傳元件處理檔案上傳步驟
			//1、建立一個DiskFileItemFactory工廠
			DiskFileItemFactory factory = new DiskFileItemFactory();
			//設定工廠的緩衝區的大小,當上傳的檔案大小超過緩衝區的大小時,就會生成一個臨時檔案存放到指定的臨時目錄中
			factory.setSizeThreshold(1024*100);
			//設定上傳時生成的臨時檔案的儲存目錄
			factory.setRepository(tempFile);
			//2、建立一個檔案上傳解析器
			ServletFileUpload upload = new ServletFileUpload(factory);
			//監聽檔案上傳進度
			upload.setProgressListener(new ProgressListener() {
				@Override
				public void update(long pBytesRead, long pContentLength, int arg2) {
					System.out.println("檔案大小為:" + pContentLength + ",當前已處理:" + pBytesRead);
				}
			});
			//解決上傳檔名的中文亂碼
			upload.setHeaderEncoding("UTF-8");
			//3、判斷提交上來的資料是否是上傳表單的資料
			if (!ServletFileUpload.isMultipartContent(request)) {
				//按照傳統的方式獲取資料
				return null;
			}
			//設定上傳單個檔案的大小的最大值,目前是設定為1024*1024位元組,也就是1MB
			upload.setFileSizeMax(1024*1024);
			//設定上傳檔案總量的最大值,最大值=同時上傳的多個檔案的大小的最大值的和,目前設定為10MB
			upload.setSizeMax(1024*1024*10);
			//4、使用ServletFileUpload解析器解析上傳資料,解析結果返回的事一個List<FileItem>集合,每一個FileItem對應一個Form表單的輸入項
			List<FileItem> list = upload.parseRequest(request);
			for (FileItem item : list) {
				//如果fileItem中封裝的是普通輸入項的資料
				if (item.isFormField()) {
					String name = item.getFieldName();
					//解決普通輸入項的資料的中文亂碼問題
					String value = item.getString("UTF-8");
					//value = new String(value.getBytes("iso8859-1", "UTF-8");
					System.out.println(name + "=" + value);
				} else {
					//如果fileItem中封裝的是上傳檔案
					//得到上傳的檔名稱
					String fileName = item.getName();
					System.out.println(fileName);
					if (fileName == null || fileName.trim().equals("")) {
						continue;
					}
					//注意:不同的瀏覽器提交的檔名是不一樣的,有些瀏覽器提交上來的檔名是帶有路徑的,如:c:\a\b\1.txt,而有些只是單純的檔名,如:1.txt
					//處理獲取到的上傳檔案的檔名的路徑部分,只保留檔名部分
					String fileExtName = fileName.substring(fileName.lastIndexOf("\\.") + 1);
					//如果需要限制檔案上傳的檔案型別,那麼可以通過檔案的副檔名來判斷上傳的檔案型別是否合法
					System.out.println("上傳的檔案的副檔名是:" + fileExtName);
					//獲取item中的上傳檔案的輸入流
					InputStream in = item.getInputStream();
					//得到檔案儲存的名稱
					String saveFileName = makeFileName(fileName);
					//得到檔案的儲存目錄
					String realSavePath = makePath(saveFileName, savePath);
					//建立一個檔案輸出流
					FileOutputStream out = new FileOutputStream(realSavePath + "\\" + saveFileName);
					//建立一個緩衝區
					byte[] buffer = new byte[1024];
					//判斷輸入流中的資料是否已經讀完的標識
					int len = 0;
					//迴圈將輸入流讀入到緩衝區中,(len=in.read(buffer))>0就表示in裡面還有資料
					while ((len = in.read(buffer)) > 0) {
						//使用FileOutputStream輸出流將緩衝區的資料寫入到指定的目錄(savePath + "\\" + fileName)當中
						out.write(buffer, 0, len);
					}
					//關閉輸入流
					in.close();
					//關閉輸出流
					out.close();
					//刪除處理檔案上傳時生成的臨時檔案
					item.delete();
					message = UploadFileUtils.UPLOAD_SUCCESS;
				}
			}
		} catch (FileUploadBase.FileSizeLimitExceededException e) {
			e.printStackTrace();
			message = UploadFileUtils.UPLOAD_OVER_MAX_SIZE;
			return message;
		} catch (Exception e) {
			message = UploadFileUtils.UPLOAD_FAIL;
			e.printStackTrace(); 
			return message;
		}
		return message;
	}
	
	public static void download(HttpServletRequest request,HttpServletResponse response, String fileName) throws IOException{
		//得到下載的檔名
//		String fileName = request.getParameter("filename");
		//fileName = new String(fileName.getBytes("iso8859-1"),"UTF-8");
		//上傳的檔案都是儲存在/WEB-INF/upload目錄下的子目錄中的
		String fileSaveRootPath = request.getServletContext().getRealPath("/WEB-INF/upload");
		//通過檔名找出檔案所在目錄
		String path = makePath(fileName,fileSaveRootPath);
		//得到要下載的檔案
		File file = new File(path+"\\"+fileName);
		//如果檔案不存在
		if(!file.exists()){
			request.setAttribute("message", "您下載的資源已被刪除");
			return;
		}
		//處理檔名
		String realname = fileName.substring(fileName.indexOf("_")+1);
		
		//設定響應頭,控制瀏覽器下載該檔案
		response.setHeader("content-Disposition", "attachment;filename="+URLEncoder.encode(realname,"UTF-8"));
		//讀取要下載的檔案,儲存到檔案輸入流
		FileInputStream in = new FileInputStream(path+"\\"+fileName);
		//建立輸出流
		OutputStream out = response.getOutputStream();
		//建立緩衝區
		byte buffer[] = new byte[1024];
		int len = 0;
		//迴圈將輸入流中的內容讀取到緩衝區當中
		while((len = in.read(buffer))>0){
			//輸出緩衝區的內容到瀏覽器,實現檔案下載
			out.write(buffer,0,len);
		}
		//關閉檔案輸入流
		in.close();
		//關閉輸出流
		out.close();
	}
	
	
	public static Map<String, Object> uploadBySpring(HttpServletRequest request, String[] fileExts) throws Exception {
		Map<String, Object> map = new HashMap<>();
		//得到上傳檔案的儲存目錄,將上傳的檔案存放於upload目錄下
		String savePath = request.getServletContext().getRealPath("/WEB-INF/upload");
		//建立一個通用的多部分解析器
		CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
		//判斷request是否有檔案上傳,即多部分請求
		if (multipartResolver.isMultipart(request)) {
			//轉換成多部分request
			MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
			Iterator<String> iter = multiRequest.getFileNames();
			while (iter.hasNext()) {
				//取得上傳檔案
				MultipartFile file = multiRequest.getFile(iter.next());
				if (file != null) {
					//取得當前上傳檔案的檔名稱
					String fileName = file.getOriginalFilename();
					//獲取檔案字尾名
					String fileExtName = fileName.substring(fileName.lastIndexOf("."));
					if (null != fileExts) {
						for (int i = 0; i < fileExts.length; i++) {
							if (fileExts[i].equalsIgnoreCase(fileExtName)) {
								break;
							}
							if (i < fileExts.length -1 && !fileExts[i].equalsIgnoreCase(fileExtName)) {
								continue;
							} else if (!fileExts[i].equalsIgnoreCase(fileExtName)) {
								return null;
							}
						}
					}
					//如果名稱不為”“,說明該檔案存在,否則說明該檔案不存在
					if (fileName.trim() != "") {
						//重新命名上傳後的檔名,得到檔案儲存的名稱
						String saveFileName = makeFileName(file.getOriginalFilename());
						//得到檔案的儲存目錄
						String realSavePath = makePath(saveFileName, savePath);
						File localFile = new File(realSavePath + "\\" + saveFileName);
						try {
							file.transferTo(localFile);
							map.put("originalFileName", fileName);
							map.put("realPath", realSavePath + "\\" + saveFileName);
						} catch (IllegalStateException | IOException e) {
							throw e;
						}
					}
				}
			}
		}
		return map;
	}
	
	/**
	 * 生成上傳檔案的檔名,檔名以:uuid + "-" + 檔案的原始名稱
	 * @param fileName
	 * @return
	 */
	private static String makeFileName(String fileName) {
		//為防止檔案覆蓋的現象發生,要為上傳檔案產生一個唯一的檔名
		return UUID.randomUUID().toString() + "_" + fileName;
	}
	
	/**
	 * 為防止一個目錄下面出現太多檔案,要使用hash演算法打散儲存
	 * @param fileName
	 * @param savePath
	 * @return
	 */
	private static String makePath(String fileName, String savePath) {
		//得到檔名的hashCode值,得到的就是fileName這個字串物件在記憶體中的地址
		int hashCode = fileName.hashCode();
		int dir1 = hashCode & 0xf; //0-15
		int dir2 = (hashCode & 0xf0) >> 4; //0-15
		//構造新的儲存目錄
		String dir = savePath + "\\" + dir1 + "\\" + dir2;  //如:upload\2\3
		//File既可以代表檔案也可以代表目錄
		File file = new File(dir);
		//如果目錄不存在
		if (!file.exists()) {
			//建立目錄
			file.mkdirs();
		}
		return dir;
	}
	
	public static String uploadFile(HttpServletRequest request, String[] fileExts) throws Exception {
		//得到上傳檔案的儲存目錄,將上傳的檔案存放於images目錄下
		String savePath = request.getServletContext().getRealPath("/images");
		String backPath = null;
		//建立一個通用的多部分解析器
		CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
		//判斷request是否有檔案上傳,即多部分請求
		if (multipartResolver.isMultipart(request)) {
			//轉換成多部分request
			MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
			Iterator<String> iter = multiRequest.getFileNames();
			while (iter.hasNext()) {
				//取得上傳檔案
				MultipartFile file = multiRequest.getFile(iter.next());
				if (file != null) {
					//取得當前上傳檔案的檔名稱
					String fileName = file.getOriginalFilename();
					//獲取檔案字尾名
					String fileExtName = fileName.substring(fileName.lastIndexOf("."));
					if (null != fileExts) {
						for (int i = 0; i < fileExts.length; i++) {
							if (fileExts[i].equalsIgnoreCase(fileExtName)) {
								break;
							}
							if (i < fileExts.length -1 && !fileExts[i].equalsIgnoreCase(fileExtName)) {
								continue;
							} else if (!fileExts[i].equalsIgnoreCase(fileExtName)) {
								return null;
							}
						}
					}
					//如果名稱不為”“,說明該檔案存在,否則說明該檔案不存在
					if (fileName.trim() != "") {
						//重新命名上傳後的檔名,得到檔案儲存的名稱
						String saveFileName = makeFileName(file.getOriginalFilename());
						//得到檔案的儲存目錄
						String realSavePath = makePath(saveFileName, savePath);
						File localFile = new File(realSavePath + "\\" + saveFileName);
						try {
							file.transferTo(localFile);
							backPath = realSavePath + "\\" + saveFileName;
						} catch (IllegalStateException | IOException e) {
							throw e;
						}
					}
				}
			}
		}
		return backPath;
	}
	
	/**
	 * getImageBinary
	 * @描述: 獲得圖片二進位制流
	 * @作者: liangzhg
	 * @建立時間: 2018-4-4下午02:27:43
	 * @param imagePath
	 * @return
	 */
	public static String getImageBinary(String imagePath) {
		
		File file = new File(imagePath);
		System.out.println(imagePath);
		BufferedImage bi;
		try {
			bi = ImageIO.read(file);
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			ImageIO.write(bi, "jpg", baos);//格式可不管。
			byte[] bytes = baos.toByteArray();
			return encoder.encodeBuffer(bytes).trim();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;	
	}
	
	/**
	 * base64StringToImage
	 * @描述:將二進位制字元轉化為圖片
	 * @作者: liangzhg
	 * @建立時間: 2018-4-4下午04:13:49
	 * @param savePath
	 * @param base64String
	 */
	public static void base64StringToImage(String savePath,String base64String) {
		try {
			byte[] bytes = decoder.decodeBuffer(base64String);
			ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
			BufferedImage bi = ImageIO.read(bais);
			File file = new File(savePath);
			ImageIO.write(bi, "jpg", file);
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

相關推薦

javaWeb伺服器下載檔案

專案經常需要向伺服器上傳檔案或者從伺服器下載檔案,因此將所需要的許多方法整理到了一個工具類中,包括從伺服器下載流檔案,上傳檔案到伺服器(用Apache和spring不同的方法),希望能幫助到大家。package com.phy.szms.utils; import java

Ubuntu Linux 搭建一個簡單的ftp伺服器,用於下載檔案

第一步,安裝軟體 $ sudo apt-get update $ sudo apt-get install vsftpd 第二步,修改配置檔案 $ sudo vi /etc/vsftpd.conf

解決 伺服器vsftpd安裝完成後,用winscp不能下載檔案的問題

需要修改vsftpd配置檔案,配置檔案預設是不允許上傳下載和修改的 sudo vi /etc/vsftpd.conf 檢視配置檔案裡面的註釋,將你需要的功能的註釋去掉(上傳下載功能都被注視掉了) 然後儲存,重啟vsftpd就可以了。 ps:如果重啟之後發現連線ftp伺

Linux使用rzsz操作下載檔案

rz軟體安裝 (1)編譯安裝 root 賬號登陸後,依次執行以下命令: 1 cd /tmp 2 wget http://www.ohse.de/uwe/releases/lrzsz-0.12.20.

使用ssh協議在linux主機之間快速下載檔案

scp 要上傳的檔案 上傳主機使用者名稱@主機地址:要上傳的主機目錄 例如: scp *20181111*.gz [email protected]:/INAS/dsgbak/20181110 表示將當前目錄下的含有20181111字元的.gz檔案,上傳到10.2.13.57主機,使用者名稱為

SFTP下載檔案指令碼

運維工作中,遠端上傳或下載檔案很常用,我分享下我經常使用的sftp指令碼 #!/bin/bash SCRIPT_NAME=`basename $0` CURRENT_DIR=$(cd "$(dirna

springmvc下載檔案

pom依賴 <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.sou

遠端下載檔案XFTP5

XFTP5是一款基於windows系統用於連線windows和linux/unix之間進行檔案的上傳和下載操作的軟體. 在windows系統上安裝xftp5 軟體百度雲提取地址: https://pan.baidu.com/s/1fPHhtDWO9lg5LoFk

linux系統下載檔案(命令列)

SecureCRT與linux互相上傳和下載檔案(命令列) 在scrt中檔案的上傳或者下載除了使用命令列以後可以通過ftp,今天咋們就用命令列rz實現檔案的上傳, 上傳 1. 檔案的上傳

如何在命令列中使用 ftp 命令下載檔案

本文中,介紹在 Linux shell 中如何使用 ftp 命令。包括如何連線 FTP 伺服器,上傳或下載檔案以及建立資料夾。儘管現在有許多不錯的 FTP 桌面應用,但是在伺服器、SSH、遠端會話中命令列 ftp 命令還是有很多應用的。比如。需要伺服器從 ftp 倉庫拉取

C#進行Http下載檔案

廢話不多說,直接上程式碼 一:客戶端 1:上傳: 首先:在web.config的<appSettings></appSettings>節點中加上伺服器的地址 <add k

Xshell 下載檔案

經常使用xshell的人,他們在上傳、下載或者重新命名一個檔案的時候,往往會使用命令方式,例如sz,rz,cp 等命令。但是如果新手呢?他們卻不知道這些命令的,而且往往用起來不方便。本文為大家介紹一種用xshell直接開啟Xftp的方法。 第二種方式 FTP工具 安裝完成X

使用python下載檔案到FastDFS

2. 解壓後進入目錄執行"python setup.py install": 3. 新建測試檔案test_fdfs.py,把下載解壓後安裝包的.../FastDFS/conf/client.con

使用SecureCRT來下載檔案

  用SSH管理linux伺服器時經常需要遠端與本地之間互動檔案。而直接用SecureCRT自帶的上傳下載功能無疑是最方便的,SecureCRT下的檔案傳輸協議有ASCII.Xmodem.Zmodem。 檔案傳輸協議: 檔案傳輸是資料交換的主要形式。在進行檔案傳輸時,為使檔案能被正確識別和傳送,我們需要在兩臺

centos中使用 vsftpd 服務,並且配置匿名使用者下載檔案

首先我們需要再linux當中安裝 vsftpd服務 yum install vsftpd 然後cd當vsftpd的安裝配置資料夾 ,一般是  /etc/vsftpd 這個資料夾。 接下來配置一下vsftpd.conf檔案,配置檔案見下方,直接貼上進您的配置中即可: #允許

SecureCRT-下載檔案

1.選擇session標籤,這裡選擇的是 10.143.128.165 然後右鍵,選擇“會話選項”,設定上傳下載目錄 2.進入到指定目錄,這裡選擇的是/app/creditcc/e_servic

Linux下載檔案

sz命令傳送檔案到本地: # sz filename       rz命令本地上傳檔案到伺服器: # rz  執行該命令後,在彈出框中選擇要上傳的檔案即可。 說明:開啟SecureCRT軟體 -> Options -> session opt

okhttp2.6使用getpost 下載檔案 普通的下載

為了寫部落格所以沒有封裝 使用的時候OkHttpClien() new 一次就可以了 不用new很多次 implementation 'com.squareup.okhttp:okhttp:2.6.0'public void downPhotos(String url

Python:FTP下載檔案程式設計

冒犯轉載,還望請見諒!僅供個人筆記所用,故不設定文章標籤等資訊。 Python 程式設計中使用ftplib模組的FTP物件,可以進行方便的實現FTP客戶端功能,簡易的流程如下: # FTP操作基本流程示意 FTP.connect(伺服器地址,埠,超時時間) # 連線伺服器 FTP.login(使用者名

myBatis + SpringMVC下載檔案

環境:maven+SpringMVC + Spring + MyBatis + MySql 首先要建立資料庫,此處使用MySql資料庫。 第一步: 匯入commons-fileupload-1.3.1.jar和commons-io-2.4.jar以及Spr