日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

java 预览zip_java压缩包上传,解压,预览(利用editor.md和Jstree实现)和下载

發(fā)布時(shí)間:2025/3/12 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 预览zip_java压缩包上传,解压,预览(利用editor.md和Jstree实现)和下载 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

java壓縮包上傳,解壓,預(yù)覽(利用editor.md和Jstree實(shí)現(xiàn))和下載

實(shí)現(xiàn)功能:zip文件上傳,后臺(tái)自動(dòng)解壓,Jstree樹(shù)目錄(遍歷文件),editor.md預(yù)覽

采用Spring+SpringMVC+Maven+Jstree+editor.md實(shí)現(xiàn),主要功能:

zip壓縮文件的上傳

后臺(tái)自動(dòng)解壓

Jstree自動(dòng)獲取最上層目錄,每次僅僅會(huì)獲取當(dāng)前層的文件或者文件夾,然后點(diǎn)擊文件夾或者文件,通過(guò)ajax與服務(wù)器交換數(shù)據(jù),減輕檢索和數(shù)據(jù)傳輸壓力

后臺(tái)通過(guò)文件路徑遍歷文件夾

通過(guò)editor.md將文本代碼高亮顯示

圖片的解析預(yù)覽

總體項(xiàng)目目錄結(jié)構(gòu):

預(yù)覽:

點(diǎn)擊提交后:

并提供下載功能

1. 分析代碼

上傳壓縮包的html代碼,使用velocity模板渲染引擎:

上傳壓縮項(xiàng)目包

提示:壓縮包內(nèi)請(qǐng)勿包含中文!

$(window).load(function() {

//當(dāng)鼠標(biāo)移出輸入框

$('#file-name').on('blur', function(){

var fileName = document.getElementById("file-name").value;

if(fileName==''){

$('.file-name-check').html('');

$('.file-name-check').append("請(qǐng)輸入項(xiàng)目名!")

}

});

$("#file-zip").bind("change",function(){

var imgArr = ["zip"];

if($(this).val() == "")

{

alert("請(qǐng)選擇文件!");

}

else{

var file = $(this).val();

var len = file.length;

var ext = file.substring(len-3,len).toLowerCase();

if($.inArray(ext,imgArr) == -1)

alert("不是zip格式");

}

});

$('#upload-zip').on('click', function(){

var form = document.getElementById("zipForm");

if(document.getElementById("file-name").value==''){//當(dāng)項(xiàng)目名為空時(shí)

alert("請(qǐng)輸入項(xiàng)目名!");

return false;

}

if(document.getElementById("file-zip").value==''){//當(dāng)項(xiàng)目為空時(shí)

alert("請(qǐng)上傳項(xiàng)目!");

return false;

}

var formdata = new FormData(form);

$.ajax({

url:"/admin/file/zip/upload",

data: formdata,

type:"post",

//預(yù)期服務(wù)器返回的數(shù)據(jù)類(lèi)型,自動(dòng)解析json返回值,不設(shè)置的話(huà)可能要執(zhí)行oResult = JSON.parse(oResult);進(jìn)行解析

dataType:"json",

//默認(rèn)值: true。默認(rèn)情況下,通過(guò)data選項(xiàng)傳遞進(jìn)來(lái)的數(shù)據(jù),如果是一個(gè)對(duì)象(技術(shù)上講只要不是字符串),

// 都會(huì)處理轉(zhuǎn)化成一個(gè)查詢(xún)字符串,以配合默認(rèn)內(nèi)容類(lèi)型 "application/x-www-form-urlencoded"。如果要發(fā)送 DOM 樹(shù)信息或其它不希望轉(zhuǎn)換的信息,請(qǐng)?jiān)O(shè)置為 false。

processData: false,

//contentType: false,避免 JQuery 對(duì)data操作,可能失去分界符,而使服務(wù)器不能正常解析文件。

contentType: false,

success: function(oResult) {

// console.log(oResult);

if(oResult.success==1){

window.location.href="/admin/file/zip/show?file-path="+oResult.url;

}else{

alert(oResult.message);

}

}

})

// .done(function(oResult) { //注意done表示成功,fail表示失敗,always表示不論成功還是失敗,會(huì)執(zhí)行的函數(shù),

// //但是在低版本jquery不兼容,是高版本jquery推薦

// if(oResult.success==1){

// window.location.href="/";

// alert(oResult.message);

// }else{

// alert(oResult.message);

// }

// }).fail(function () {

// alert('出現(xiàn)錯(cuò)誤,請(qǐng)重試');

// });

})

});

預(yù)覽自動(dòng)解壓后文件夾的html代碼,使用velocity模板渲染引擎:

項(xiàng)目展示

Search

下載

##支持markdown快速解析

##支持代碼高亮

對(duì)應(yīng)的JS文件,file-node.js:

$(function() {

var filePath = document.getElementById("filePathRem").value;

//注意這里面只能處理尋找文件夾的子文件或者子文件夾事件,可以把文件的讀取寫(xiě)到 $('#container').on("changed.jstree", function (e, data)函數(shù)中

$('#container').jstree({

'core': {

'data':

//node為點(diǎn)擊的節(jié)點(diǎn),cd為輸出結(jié)果的函數(shù)

function (node, cb) {

var formdata = new FormData();

formdata.append("file-path",filePath);

formdata.append("id",node.id);

//通過(guò)表單對(duì)象上傳文件或者數(shù)據(jù),設(shè)置

// processData: false,表示不要對(duì)data參數(shù)進(jìn)行序列化處理

//contentType: false,避免 JQuery 對(duì)data操作,可能失去分界符,而使服務(wù)器不能正常解析文件。

$.ajax({

//不要用get方法,因?yàn)?在瀏覽器中有特殊含義,

// #代表網(wǎng)頁(yè)中的一個(gè)位置。其右面的字符,就是該位置的標(biāo)識(shí)符。比如,http://www.example.com/index.html#print就代表網(wǎng)頁(yè)index.html的print位置。

// 瀏覽器讀取這個(gè)URL后,會(huì)自動(dòng)將print位置滾動(dòng)至可視區(qū)域。

//并且在發(fā)送的請(qǐng)求中,自動(dòng)忽略#,而首次打開(kāi)頁(yè)面的第一次請(qǐng)求id=#

//url: "/admin/file/zip/show.action?lazy&file-path=" + filePath + "&id=" + node.id,

url:"/admin/file/zip/show.action",

data:formdata,

type:"post",

dataType:"json",

processData: false,

contentType: false,

success: function (oResult) {

if (oResult.result.success == 1) {

cb(oResult.array);

} else {

alert(oResult.result.message);

}

}

})

}

},

//0為文件夾,即默認(rèn),1為文件

"types" : {

0 : {

"icon" : "glyphicon glyphicon-folder",

"valid_children" : []

},

1 : {

"icon" : "glyphicon glyphicon-file"

}

},

//搜索功能插件和類(lèi)別插件,以對(duì)文件夾和文有不同的圖標(biāo)

"plugins" : ["search","types"]

});

//上面的表單s和本函數(shù)都用于搜索,模糊搜索,不區(qū)分大小寫(xiě)

$("#s").submit(function(e) {

e.preventDefault();

$("#container").jstree(true).search($("#q").val());

});

//注意changed與click的區(qū)別,前者只要狀態(tài)不變,點(diǎn)擊多少次都加載一次,后者每次點(diǎn)擊都重新加載

$('#container').on("changed.jstree", function (e, data) {

// console.log("The selected nodes are:");

// //顯示被選擇節(jié)點(diǎn)id編號(hào)

// console.log(data.selected);

// //顯示被選擇節(jié)點(diǎn)的命名

// console.log(data.node.text);

var name=String(data.selected);

//如果包含.則為請(qǐng)求文件

if(name.search("\\.")>1){

//判斷是否是圖片,其他文件都是讀取Json字符串的形式

if(!isImage(name)){

var formdata = new FormData();

formdata.append("file-path",filePath);

formdata.append("id",name);

$.ajax({

url:"/admin/file/zip/show.action",

data:formdata,

type:"post",

dataType:"json",

processData: false,

contentType: false,

success: function (oResult) {

if (oResult.result.success == 1) {

//首先把頁(yè)面中的可能存在的圖片清空

document.getElementById("image-panel").innerHTML ='';

//由于editor.md每次更新內(nèi)容之后都會(huì)將刪除,那么每次更新前都需要添加

document.getElementById("markdown-editor").innerHTML='';

document.getElementById("append-test").value="```\n"+oResult.fileContent+"\n```";

//用于將markdown文本轉(zhuǎn)化為html格式

editormd.markdownToHTML("markdown-editor", {

});

} else {

alert(oResult.result.message);

}

}

})

}else { //對(duì)于圖片,我們要顯示為圖片,而不是文本的字符流

document.getElementById("markdown-editor").innerHTML='';

document.getElementById("image-panel").innerHTML = '';

document.getElementById("img-circle").src = "/admin/file/zip/image.action?file-path="+filePath+"&id="+name;

}

}

});

//判斷請(qǐng)求文件是否是圖片,僅支持常用類(lèi)型

function isImage(objFile) {

var objtype = objFile.substring(objFile.lastIndexOf(".")).toLowerCase();

var fileType = new Array(".png", ".jpg", ".jpeg", ".gif", ".bmp", ".ico");

for (var i = 0; i < fileType.length; i++) {

if (objtype == fileType[i]) {

return true;

break;

}

}

return false;

}

});

對(duì)應(yīng)Controller層代碼,FileController.java:

import com.alibaba.fastjson.JSON;

import com.alibaba.fastjson.JSONArray;

import com.alibaba.fastjson.JSONObject;

import com.demo.fileTree.model.FileHandleResponse;

import com.demo.fileTree.model.JstreeNode;

import com.demo.fileTree.service.FileService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.web.bind.annotation.*;

import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;

import java.io.*;

import java.util.List;

/**

* 實(shí)現(xiàn)項(xiàng)目zip壓縮包的上傳,自動(dòng)解壓,解壓后的預(yù)覽,包括文本和字符串,項(xiàng)目的壓縮下載,

* 由于java.util.zip包不支持漢字的問(wèn)題,在項(xiàng)目壓縮包內(nèi)請(qǐng)勿包含中文文件名,但是在頁(yè)面中的項(xiàng)目名可以起名為中文,

* 可以用org.apache.tools.zip壓縮/解壓縮zip文件,解決中文亂碼問(wèn)題。

*

* @author xie

* @version 1.0

* @Date 2017/5/26

*/

@Controller

public class FileController {

@Autowired

FileService fileService;

/**

* 主頁(yè)

* @return

*/

@RequestMapping(path = {"/"}, method = {RequestMethod.GET, RequestMethod.POST})

public String index() {

return "upload_zip";

}

/**

* 上傳壓縮zip項(xiàng)目文件

* @param file zip壓縮文件

* @param fileName 項(xiàng)目的命名,我們將解壓縮的文件放到以項(xiàng)目名命名的文件夾內(nèi),為了保證項(xiàng)目名重復(fù)的也可以上傳,項(xiàng)目名文件夾外部還有一個(gè)32位UUID命名的文件夾,

* 只不過(guò)取出項(xiàng)目時(shí)沒(méi)有顯示

* @return 結(jié)果的json字符串

*/

@RequestMapping(path = {"/admin/file/zip/upload"}, method = {RequestMethod.GET, RequestMethod.POST})

@ResponseBody

public String uploadZipFile(@RequestParam("file-zip") MultipartFile file,@RequestParam("file-name")String fileName) {

FileHandleResponse fileHandleResponse = new FileHandleResponse();

try {

if(file.isEmpty()){

fileHandleResponse.setSuccess(0);

fileHandleResponse.setMessage("上傳壓縮文件為空");

return JSON.toJSONString(fileHandleResponse);

}

fileHandleResponse = fileService.uploadFileZip(file,fileName);

return JSON.toJSONString(fileHandleResponse);

}catch (Exception e) {

fileHandleResponse.setSuccess(0);

fileHandleResponse.setMessage("服務(wù)器異常!");

fileHandleResponse.setUrl(null);

return JSON.toJSONString(fileHandleResponse);

}

}

/**

* 展示上傳的zip項(xiàng)目解壓縮后的文件結(jié)構(gòu)

* @param filePath 項(xiàng)目的路徑,比如,C:\home\myblog\project\2d76c7aa844b4585a53d982d205099e2\123\其中123為項(xiàng)目名,

* @param model

* @return

*/

@RequestMapping(path = {"/admin/file/zip/show"}, method = {RequestMethod.GET, RequestMethod.POST})

public String showZipFile(@RequestParam("file-path")String filePath, Model model) {

model.addAttribute("filePath",filePath);

//filePath地址大概樣子,C:\home\myblog\project\2d76c7aa844b4585a53d982d205099e2\123\,windows和linux不同,

// 包含文件名,我們提取出來(lái),作為fileName,分隔符可能為/或\或\\,其中\(zhòng)要轉(zhuǎn)意為\\

String fileName = filePath.split("\\|\\\\|/")[filePath.split("\\|\\\\|/").length-1];

model.addAttribute("fileName",fileName);

return "show_zip";

}

/**

* 項(xiàng)目展示頁(yè)面

* @param filePath 項(xiàng)目路徑

* @param relativePath 節(jié)點(diǎn)相比項(xiàng)目路徑的相對(duì)路徑,比如項(xiàng)目路徑:

* C:/home/myblog/project/dccb182a7ded477483362ce46be1eb5c/123/

* 那么節(jié)點(diǎn)路徑src/main/java/表示

* C:/home/myblog/project/dccb182a7ded477483362ce46be1eb5c/123/src/main/java/

* @return 對(duì)于文件,返回字符內(nèi)容的json字符串,對(duì)于文件夾,返回文件夾的下一級(jí)所有子文件和子文件夾,其實(shí)若文件是圖片,我們?cè)谙旅娴膅etImage()方法中處理

*/

@RequestMapping(path = {"/admin/file/zip/show.action"}, method = {RequestMethod.GET, RequestMethod.POST})

@ResponseBody

public String showZipFileDetail(@RequestParam("file-path") String filePath, @RequestParam("id") String relativePath, Model model) {

FileHandleResponse fileHandleResponse = new FileHandleResponse();

try {

if (relativePath.equals("#")) { //表示第一次打開(kāi)頁(yè)面的請(qǐng)求,relativePath為#,沒(méi)什么意義,設(shè)為空字符串

relativePath = "";

}

File file = new File(filePath+relativePath);

//如果請(qǐng)求路徑存在,即文件或者目錄存在

if (file.exists()) {

//分為文件或者文件夾兩種情況

if (file.isFile()) {

BufferedReader bufferedReader;

try {

StringBuilder stringBuilder = new StringBuilder();

//將字節(jié)流向字符流的轉(zhuǎn)換,并創(chuàng)建字符流緩沖區(qū)

bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));

// 每次讀入一行

String read;

//每讀入一行,要加一個(gè)換行符

String lineText="\n";

while ((read = bufferedReader.readLine()) != null) {

stringBuilder.append(read+lineText);

}

bufferedReader.close();

fileHandleResponse.setSuccess(1);

fileHandleResponse.setMessage("請(qǐng)求成功!");

model.addAttribute("result", fileHandleResponse);

model.addAttribute("fileContent", stringBuilder.toString());

return JSON.toJSONString(model);

} catch (Exception e1) {

e1.printStackTrace();

}

} else {

List list = fileService.getAllChildrenNode(filePath,relativePath);

JSONArray jsonArray = new JSONArray();

for(JstreeNode jstreeNode : list){

JSONObject jsonObject = new JSONObject();

jsonObject.put("id", jstreeNode.getId());

jsonObject.put("text", jstreeNode.getText());

jsonObject.put("children", jstreeNode.isHasChildren());

jsonObject.put("type",jstreeNode.getType());

jsonArray.add(jsonObject);

}

fileHandleResponse.setSuccess(1);

fileHandleResponse.setMessage("請(qǐng)求成功!");

model.addAttribute("result", fileHandleResponse);

//最好不要直接傳遞list,前端不可以很好的解析

model.addAttribute("array", jsonArray);

return JSON.toJSONString(model);

}

} else { //如果請(qǐng)求路徑不存在

fileHandleResponse.setSuccess(0);

fileHandleResponse.setMessage("請(qǐng)求路徑不存在!");

model.addAttribute("result",fileHandleResponse);

return JSON.toJSONString(model);

}

} catch (IOException e) {

e.printStackTrace();

}

return null;

}

/**

* 將項(xiàng)目壓縮后以字節(jié)流的方式發(fā)送

* @param filePath 項(xiàng)目路徑

* @param response

*/

@RequestMapping(path = {"/admin/file/zip/download"}, method = {RequestMethod.GET})

public void downloadZipFile(@RequestParam("file-path")String filePath, HttpServletResponse response) {

FileHandleResponse fileHandleResponse;

try {

fileHandleResponse = fileService.downloadFileZip(filePath);

//地址大概樣子,C:\home\myblog\project\2d76c7aa844b4585a53d982d205099e2\123.zip,windows和linux不同,

// 包含文件名,我們提取出來(lái),作為fileName,分隔符可能為/或\或\\,其中\(zhòng)要轉(zhuǎn)意為\\

String fileName = fileHandleResponse.getUrl().split("\\|/|\\\\")[fileHandleResponse.getUrl().split("\\|/|\\\\").length-1];

response.setContentType("application/zip");

response.setCharacterEncoding("UTF-8");

response.setHeader("Content-Disposition","attachment;filename="+fileName);

OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());

byte[] data = fileService.toByteArray(fileHandleResponse.getUrl());

outputStream.write(data);

outputStream.flush();

outputStream.close();

}catch (Exception e) {

e.printStackTrace();

}

}

/**

* 按照?qǐng)D片路徑查找圖片

* @param filePath 項(xiàng)目路徑

* @param relativePath 節(jié)點(diǎn)相比項(xiàng)目路徑的相對(duì)路徑,比如項(xiàng)目路徑:

* C:/home/myblog/project/dccb182a7ded477483362ce46be1eb5c/123/

* 那么節(jié)點(diǎn)路徑src/main/java/表示

* C:/home/myblog/project/dccb182a7ded477483362ce46be1eb5c/123/src/main/java/

* @param response

*/

@RequestMapping(path = "/admin/file/zip/image.action")

public void getImage(@RequestParam("file-path") String filePath,

@RequestParam("id") String relativePath,

HttpServletResponse response) {

try {

byte[] data = fileService.toByteArray(filePath+relativePath);

response.setCharacterEncoding("UTF-8");

OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());

outputStream.write(data);

outputStream.flush();

outputStream.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

對(duì)應(yīng)Service層代碼,FileService.java:

import com.demo.fileTree.configuration.GlobalConfig;

import com.demo.fileTree.model.FileHandleResponse;

import com.demo.fileTree.model.JstreeNode;

import com.demo.fileTree.utils.ZipUtils;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.web.multipart.MultipartFile;

import java.io.File;

import java.io.FileInputStream;

import java.io.IOException;

import java.nio.ByteBuffer;

import java.nio.channels.FileChannel;

import java.util.LinkedList;

import java.util.List;

/**

* 壓縮文件上傳,并且解壓縮后放到服務(wù)器響應(yīng)目錄下,

* 為什么不直接放壓縮包,因?yàn)閯e人看一次,需要解壓縮一次,也很浪費(fèi)系統(tǒng)資源

*

* @author xie

* @version 1.0

* @Date 2017/5/27

*/

@Service

public class FileService {

@Autowired

ZipUtils zipUtils;

/**

* 默認(rèn)上傳zip壓縮格式

* @param file 上傳的文件

* @return 上傳的結(jié)果UploadResponse對(duì)象

* @throws IOException

*/

public FileHandleResponse uploadFileZip(MultipartFile file, String fileName) throws IOException {

FileHandleResponse fileHandleResponse;

try {

fileHandleResponse = zipUtils.unZipFiles(zipUtils.getZipDir(), fileName, file);

return fileHandleResponse;

} catch (Exception e) {

// 請(qǐng)求失敗時(shí)打印的異常的信息

fileHandleResponse = new FileHandleResponse();

fileHandleResponse.setSuccess(0);

fileHandleResponse.setMessage("服務(wù)器異常!");

return fileHandleResponse;

}

}

/**

* 下載壓縮后的項(xiàng)目文件

*

* @param filePath 項(xiàng)目路徑

* @return 文件處理結(jié)果實(shí)體,其中url表示項(xiàng)目壓縮后的路徑

* @throws IOException

*/

public FileHandleResponse downloadFileZip(String filePath) throws IOException {

FileHandleResponse fileHandleResponse;

try {

fileHandleResponse = zipUtils.zipFiles(filePath);

return fileHandleResponse;

} catch (Exception e) {

// 請(qǐng)求失敗時(shí)打印的異常的信息

fileHandleResponse = new FileHandleResponse();

fileHandleResponse.setSuccess(0);

fileHandleResponse.setMessage("服務(wù)器異常!");

return fileHandleResponse;

}

}

/**

* 返回某一結(jié)點(diǎn)(即文件夾)的下一級(jí)所有子節(jié)點(diǎn),注意這里輸入的不是具體文件或者不存在的路徑,是已經(jīng)判定存在的文件夾路徑,

* 如果是請(qǐng)求具體文件或者不存在的路徑,在上一層controller層就應(yīng)該將文件內(nèi)容讀取并返回或者返回錯(cuò)誤信息

*

* @param filePath 項(xiàng)目路徑

* @param relativePath 節(jié)點(diǎn)相比項(xiàng)目路徑的相對(duì)路徑,比如項(xiàng)目路徑:

* C:/home/myblog/project/dccb182a7ded477483362ce46be1eb5c/123/

* 那么節(jié)點(diǎn)路徑src/main/java/表示

* C:/home/myblog/project/dccb182a7ded477483362ce46be1eb5c/123/src/main/java/

* 但是由于files[i].getName()只會(huì)獲得abc這樣的單層目錄名或者abc.java這樣的文件名,因此我們要設(shè)置下一級(jí)的相對(duì)路徑為;

* relativePath+files[i].getName()(如果是路徑,還要包含/)

*

* @return 所有子節(jié)點(diǎn)的列表

* @throws IOException

*/

public List getAllChildrenNode(String filePath,String relativePath) throws IOException {

File file = new File(filePath+relativePath);

List list = new LinkedList<>();

try {

//對(duì)于文件夾,我們要遍歷它的下一級(jí)子節(jié)點(diǎn)

File[] files = file.listFiles();

JstreeNode jstreeNode;

for (int i = 0; i < files.length; i++) {

//目錄

if (files[i].isDirectory()) {

jstreeNode = new JstreeNode();

jstreeNode.setId(relativePath+files[i].getName() + "/");

jstreeNode.setText(files[i].getName());

jstreeNode.setHasChildren(true);

jstreeNode.setType(GlobalConfig.TYPE_FLODER);

list.add(jstreeNode);

}

//文件

else {

jstreeNode = new JstreeNode();

jstreeNode.setId(relativePath+files[i].getName());

jstreeNode.setText(files[i].getName());

jstreeNode.setHasChildren(false);

jstreeNode.setType(GlobalConfig.TYPE_FILE);

list.add(jstreeNode);

}

}

return list;

} catch (Exception e) {

// 請(qǐng)求失敗時(shí)打印的異常的信息

e.printStackTrace();

}

return null;

}

/**

* NIO方式讀取file文件為byte[]

*

* @param filename 文件名,要求包含文件絕對(duì)路徑

* @return 文件的byte[]形式

* @throws IOException

*/

public byte[] toByteArray(String filename) throws IOException {

File file = new File(filename);

/*

Java NIO中的FileChannel是一個(gè)連接到文件的通道。可以通過(guò)文件通道讀寫(xiě)文件。FileChannel無(wú)法設(shè)置為非阻塞模式,它總是運(yùn)行在阻塞模式下。

在使用FileChannel之前,必須先打開(kāi)它。但是,我們無(wú)法直接打開(kāi)一個(gè)FileChannel,需要通過(guò)使用一個(gè)InputStream、OutputStream或RandomAccessFile來(lái)獲取一個(gè)FileChannel實(shí)例。

FileChannel實(shí)例的size()方法將返回該實(shí)例所關(guān)聯(lián)文件的大小。

*/

FileChannel channel = null;

FileInputStream fileInputStream = null;

try {

fileInputStream = new FileInputStream(file);

channel = fileInputStream.getChannel();

//所分配的ByteBuffer的容量

ByteBuffer byteBuffer = ByteBuffer.allocate((int) channel.size());

/*

FileChannel.read()方法。該方法將數(shù)據(jù)從FileChannel讀取到Buffer中。read()方法返回的int值表示了有多少字節(jié)被讀到了Buffer中。

如果返回-1,表示到了文件末尾。

*/

while ((channel.read(byteBuffer)) > 0) {

// do nothing

// System.out.println("reading");

}

return byteBuffer.array();

} catch (IOException e) {

e.printStackTrace();

} finally {

try {

channel.close();

} catch (IOException e) {

e.printStackTrace();

}

try {

fileInputStream.close();

} catch (IOException e) {

e.printStackTrace();

}

}

return null;

}

}

工具類(lèi),ZipUtils.java:

import com.demo.fileTree.model.FileHandleResponse;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.stereotype.Service;

import org.springframework.web.multipart.MultipartFile;

import java.io.*;

import java.util.UUID;

import java.util.zip.ZipEntry;

import java.util.zip.ZipInputStream;

import java.util.zip.ZipOutputStream;

/**

* 文件或者文件夾的壓縮和解壓縮,詳細(xì)看java核心技術(shù)卷II,P27,

* 注意,如果是更新項(xiàng)目,要將原來(lái)文件夾及文件夾中的內(nèi)容全部刪除,重新生成UUID及文件夾,在這里由于沒(méi)有到數(shù)據(jù)庫(kù),就不執(zhí)行這一步了

*

* @author xie

* @version 1.0

* @Date 2017/5/30

*/

@Service

public class ZipUtils {

/** 頭像圖片的放置路徑*/

@Value("${zipPath.home}")

private String ZipDir;

/**

* 獲得圖片存儲(chǔ)路徑

* @return

*/

public String getZipDir(){

return ZipDir;

}

/**

* 壓縮文件-由于out要在遞歸外調(diào)用,所以封裝一個(gè)方法

* 壓縮后的壓縮文件的路徑和命名,比如 File zipFile = new File("C:/home/myblog/project/32位UUID/test.zip"),

* 但注意解壓縮后的文件夾的名字與壓縮文件的名字不一定相同,test.zip只是壓縮包的名字,

* 在這里我們將test.zip設(shè)為fileName.zip,放在32位UUID目錄下面,和解壓后的項(xiàng)目相同層次,

* 下載完成后也不刪除,防止多人下載,服務(wù)器每次都要壓縮文件

*

* @param filePath 要壓縮的項(xiàng)目的路徑

* @throws IOException

* @return FileHandleResponse 表示壓縮結(jié)果實(shí)體對(duì)象

*/

public static FileHandleResponse zipFiles(String filePath) throws IOException{

FileHandleResponse fileHandleResponse = new FileHandleResponse();

//將壓縮文件和原項(xiàng)目放到相同目錄下,并且相同命名,除了壓縮文件以.zip結(jié)尾,但注意filePath以/結(jié)尾,要處理一下

File zipFile = new File(filePath.substring(0,filePath.length()-1)+".zip");

File noZipFile = new File(filePath);

if(zipFile.exists()){

fileHandleResponse.setMessage("壓縮文件存在");

}else if(!noZipFile.exists()){

fileHandleResponse.setSuccess(0);

fileHandleResponse.setMessage("請(qǐng)求文件夾或文件不存在!");

return fileHandleResponse;

}else{

try {

//創(chuàng)建一個(gè)將壓縮數(shù)據(jù)寫(xiě)出到指定的OutputStream的ZipOutputStream

ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(zipFile));

zipFiles(zipOutputStream, "", noZipFile);

zipOutputStream.close();

System.out.println("*****************壓縮完畢*******************");

fileHandleResponse.setMessage("壓縮成功");

} catch (Exception e) {

fileHandleResponse.setSuccess(0);

fileHandleResponse.setMessage("服務(wù)器異常");

e.printStackTrace();

return fileHandleResponse;

}

}

fileHandleResponse.setSuccess(1);

fileHandleResponse.setUrl(zipFile.getAbsolutePath());

return fileHandleResponse;

}

/**

* 壓縮文件,

* 如果是目錄,則對(duì)目錄里的文件重新調(diào)用ZipFiles方法,一級(jí)目錄一級(jí)目錄的壓縮

*

* @param zipOutputStream 壓縮文件輸出流

* @param fileParentPath 壓縮文件的上級(jí)目錄

* @param srcFiles 要壓縮的文件,可以壓縮1到多個(gè)文件,通過(guò)寫(xiě)數(shù)組的方式或者一個(gè)個(gè)寫(xiě)到參數(shù)列表里面

*/

public static void zipFiles(ZipOutputStream zipOutputStream,String fileParentPath,File... srcFiles){

//將目錄中的1個(gè)或者多個(gè)\置換為/,因?yàn)樵趙indows目錄下,以\或者\(yùn)\為文件目錄分隔符,linux卻是/

if(fileParentPath!=""){

fileParentPath = fileParentPath.replaceAll("\\+", "/");

if(!fileParentPath.endsWith("/")){

fileParentPath+="/";

}

}

byte[] bytes = new byte[4096];

try {

/*

希望放入zip文件的每一項(xiàng),都應(yīng)該創(chuàng)建一個(gè)ZipEntry對(duì)象,然后將文件名傳遞給ZipEntry的構(gòu)造器,它將設(shè)置文件日期,解壓縮方法等參數(shù),

并且需要調(diào)用putNextEntry方法來(lái)開(kāi)始寫(xiě)出新文件,并將文件數(shù)據(jù)放松到zip流中,當(dāng)完成時(shí),需要調(diào)用closeEntry方法。所有文件都重復(fù)這一過(guò)程。

*/

for(int i=0;i

//對(duì)于目錄,遞歸

if(srcFiles[i].isDirectory()){

File[] files = srcFiles[i].listFiles();

String srcPath = srcFiles[i].getName();

srcPath = srcPath.replaceAll("\\+", "/");

if(!srcPath.endsWith("/")){

srcPath+="/";

}

zipOutputStream.putNextEntry(new ZipEntry(fileParentPath+srcPath));

zipFiles(zipOutputStream,fileParentPath+srcPath,files);

}

//對(duì)于文件,發(fā)送到ZIP流中,利用4KB的緩沖區(qū),可以考慮使用BufferedInputStream()流過(guò)濾器

else{

FileInputStream fileInputStream = new FileInputStream(srcFiles[i]);

zipOutputStream.putNextEntry(new ZipEntry(fileParentPath + srcFiles[i].getName()));

int len;

while((len=fileInputStream.read(bytes))>0){

zipOutputStream.write(bytes,0,len);

}

zipOutputStream.closeEntry();

fileInputStream.close();

}

}

} catch (Exception e) {

e.printStackTrace();

}

}

/**

* 解壓文件到指定目錄

* @param unZipPath 解壓路徑,比如C:\\home\\myblog\\project\\

* @param fileName 解壓后的文件名,一般命名為項(xiàng)目名,強(qiáng)制要求用戶(hù)輸入,并且保證不為空,

* fileName的上層目錄為一個(gè)隨機(jī)生成的32位UUID,以保證項(xiàng)目名重復(fù)的依然可以保存到服務(wù)器

* @param multipartFile 上傳壓縮文件

*

* @return FileHandleResponse 表示上傳結(jié)果實(shí)體對(duì)象

*/

@SuppressWarnings("rawtypes")

public static FileHandleResponse unZipFiles(String unZipPath, String fileName, MultipartFile multipartFile)throws IOException{

FileHandleResponse fileHandleResponse = new FileHandleResponse();

String unZipRealPath = unZipPath +UUID.randomUUID().toString().replaceAll("-", "")+ "/"+fileName + "/";

//如果保存解壓縮文件的目錄不存在,則進(jìn)行創(chuàng)建,并且解壓縮后的文件總是放在以fileName命名的文件夾下

File unZipFile = new File(unZipRealPath);

if (!unZipFile.exists()) {

unZipFile.mkdirs();

}

//ZipInputStream用來(lái)讀取壓縮文件的輸入流

ZipInputStream zipInputStream = new ZipInputStream(multipartFile.getInputStream());

//壓縮文檔中每一個(gè)項(xiàng)為一個(gè)zipEntry對(duì)象,可以通過(guò)getNextEntry方法獲得,zipEntry可以是文件,也可以是路徑,比如abc/test/路徑下

ZipEntry zipEntry;

try {

while ((zipEntry = zipInputStream.getNextEntry()) != null) {

String zipEntryName = zipEntry.getName();

//將目錄中的1個(gè)或者多個(gè)\置換為/,因?yàn)樵趙indows目錄下,以\或者\(yùn)\為文件目錄分隔符,linux卻是/

String outPath = (unZipRealPath + zipEntryName).replaceAll("\\+", "/");

//判斷所要添加的文件所在路徑或者

// 所要添加的路徑是否存在,不存在則創(chuàng)建文件路徑

File file = new File(outPath.substring(0, outPath.lastIndexOf('/')));

if (!file.exists()) {

file.mkdirs();

}

//判斷文件全路徑是否為文件夾,如果是,在上面三行已經(jīng)創(chuàng)建,不需要解壓

if (new File(outPath).isDirectory()) {

continue;

}

OutputStream outputStream = new FileOutputStream(outPath);

byte[] bytes = new byte[4096];

int len;

//當(dāng)read的返回值為-1,表示碰到當(dāng)前項(xiàng)的結(jié)尾,而不是碰到zip文件的末尾

while ((len = zipInputStream.read(bytes)) > 0) {

outputStream.write(bytes, 0, len);

}

outputStream.close();

//必須調(diào)用closeEntry()方法來(lái)讀入下一項(xiàng)

zipInputStream.closeEntry();

}

zipInputStream.close();

fileHandleResponse.setSuccess(1);

fileHandleResponse.setMessage("解壓完畢");

fileHandleResponse.setUrl((unZipRealPath).replaceAll("\\+", "/"));

System.out.println("******************解壓完畢********************");

} catch (Exception e) {

fileHandleResponse.setSuccess(0);

fileHandleResponse.setMessage("服務(wù)器異常");

e.printStackTrace();

return fileHandleResponse;

}

return fileHandleResponse;

}

}

對(duì)應(yīng)的model層,FileHandleResponse.java:

/**

* 文件處理后回顯提示的實(shí)體類(lèi)

*

* @author xie

* @version 1.0

* @Date 2017/5/25

*/

public class FileHandleResponse {

/** 上傳狀態(tài),0:失敗,1:上傳成功 */

private int success;

/** 圖片上傳提示信息,包括上傳成功或上傳失敗及錯(cuò)誤信息等 */

private String message;

/** 圖片上傳成功后返回的地址 */

private String url;

public int getSuccess() {

return success;

}

public void setSuccess(int success) {

this.success = success;

}

public String getMessage() {

return message;

}

public void setMessage(String message) {

this.message = message;

}

public String getUrl() {

return url;

}

public void setUrl(String url) {

this.url = url;

}

}

JstreeNode.java

/**

* Jstree節(jié)點(diǎn)實(shí)體

*

* @author xie

* @version 1.0

* @Date 2017/5/31

*/

public class JstreeNode {

/** id并沒(méi)有實(shí)際的意義,僅僅用于唯一標(biāo)識(shí)節(jié)點(diǎn),為了掌握節(jié)點(diǎn)之間的上下級(jí)關(guān)系,我們將id設(shè)為節(jié)點(diǎn)對(duì)file-path的相對(duì)路徑 */

private String id;

/** 節(jié)點(diǎn)的顯示名字,我們?cè)O(shè)為文件名 */

private String text;

/** 節(jié)點(diǎn)是否有孩子節(jié)點(diǎn) */

private boolean hasChildren;

/** 節(jié)點(diǎn)類(lèi)型,即文件還是文件夾,設(shè)置文件夾為0,文件為1 */

private int type;

public String getId() {

return id;

}

public void setId(String id) {

this.id = id;

}

public String getText() {

return text;

}

public void setText(String text) {

this.text = text;

}

public boolean isHasChildren() {

return hasChildren;

}

public void setHasChildren(boolean hasChildren) {

this.hasChildren = hasChildren;

}

public int getType() {

return type;

}

public void setType(int type) {

this.type = type;

}

}

總結(jié)

以上是生活随笔為你收集整理的java 预览zip_java压缩包上传,解压,预览(利用editor.md和Jstree实现)和下载的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。