java實(shí)現(xiàn)文件加密解密多種方法
一、對于文件流讀寫取的方式對比:
inputStream.read()與OutputStream.write() | 單字節(jié)讀取,效率低下 |
inputStream.read(new byte[80*1024])與OutputStream.write(new byte[80*1024]) | 固定數(shù)組讀取,經(jīng)測試數(shù)組增加到80k左右性能最佳 |
nputStream.read(inputStream.available()) 與OutputStream.write(inputStream.available()) | 按文件大小一次性讀取,如文件過大有內(nèi)存溢出風(fēng)險(xiǎn) |
BufferedInputStream.read()與BufferedOutputStream.write() | 默認(rèn)有一個(gè)8K的緩存數(shù)組 |
二、循環(huán)每個(gè)字節(jié)加解密(此方法效率最低):
1.通過inputStream.read()
單字節(jié)加密,inputStream.read()
返回的是一個(gè)字節(jié)的內(nèi)容(0-255之間的數(shù)字),可直接異或加密:
@PostMapping("/swlUpload") public void swlUpload(MultipartFile file) throws IOException { String originalFilename = file.getOriginalFilename(); InputStream inputStream = file.getInputStream(); //FileInputStream inputStream = new FileInputStream((File) file); byte[] b = new byte[1024]; FileOutputStream fileOutputStream = new FileOutputStream(new File("D:\\"+originalFilename)); BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream); int swl = 0; while((swl=inputStream.read())!=-1){ //System.out.println(b); bufferedOutputStream.write(swl^9527); } //6.2用來刷新緩沖區(qū),刷新后可以再次寫出 bufferedOutputStream.flush(); inputStream.close(); bufferedOutputStream.close(); }
2.通過inputStream.read()
單字節(jié)解密:
@PostMapping("/swlDownload") public void swlDownload(HttpServletResponse response) throws IOException { File f2= new File("D:\\108B計(jì)劃.xlsx"); boolean exists = f2.exists(); FileInputStream inputStream = new FileInputStream(f2); //byte[] b = new byte[1024]; String filePath = "108B計(jì)劃.xlsx"; //6.1清除buffer緩存 response.reset(); response.setContentType("application/octet-stream;charset=UTF-8"); //response.setHeader("Content-Disposition", "inline; filename="+ new String(filePath.getBytes("UTF-8"), "ISO-8859-1"));// 定義文件名 //response.setHeader("Content-Disposition", "attachment; filename="+ new String(filePath.getBytes("UTF-8"), "ISO-8859-1"));// 定義文件名 response.setHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode(filePath, "UTF-8")); response.setHeader("Pragma", "no-cache"); response.setHeader("Cache-Control", "no-cache"); response.setHeader("Expires", " 0"); ServletOutputStream outputStream = response.getOutputStream(); BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream); int swl = 0; while((swl = inputStream.read())!=-1){ bufferedOutputStream.write(swl^9527); } //6.2用來刷新緩沖區(qū),刷新后可以再次寫出 bufferedOutputStream.flush(); inputStream.close(); bufferedOutputStream.close(); }
三、加載整個(gè)文件加解密(效率快,有內(nèi)存溢出風(fēng)險(xiǎn)):
1.通過inputStream.read(bytes)
加載整個(gè)文件,inputStream.read(bytes)返回bytes大小的字節(jié),放入bytes數(shù)組中,循環(huán)異或加密:
@PostMapping("/swlUpload") public void swlUpload(MultipartFile file) throws IOException { String originalFilename = file.getOriginalFilename(); InputStream inputStream = file.getInputStream(); //FileInputStream inputStream = new FileInputStream((File) file); byte[] b = new byte[8*1024]; FileOutputStream fileOutputStream = new FileOutputStream(new File("D:\\"+originalFilename)); BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream); //一、整體io讀取、循環(huán)加密 long l = System.currentTimeMillis(); log.info(String.valueOf(System.currentTimeMillis())); int swl = 0; byte[] bytes = new byte[inputStream.available()]; while((inputStream.read(bytes))!=-1){ //System.out.println(b); for(int i=0;i<bytes.length;i++){ bufferedOutputStream.write(bytes[i]^9527); } } //6.2用來刷新緩沖區(qū),刷新后可以再次寫出 bufferedOutputStream.flush(); inputStream.close(); bufferedOutputStream.close(); log.info(String.valueOf(System.currentTimeMillis())); log.info(String.valueOf(System.currentTimeMillis()-l)); }
2.通過inputStream.read(bytes)
加載整個(gè)文件解密:
@PostMapping("/swlDownloadAll") public void swlDownloadAll(HttpServletResponse response) throws IOException { File f2= new File("D:\\84333c1377d99d970a0984049db926ae.mp4"); boolean exists = f2.exists(); FileInputStream inputStream = new FileInputStream(f2); //byte[] b = new byte[1024]; String filePath = "84333c1377d99d970a0984049db926ae.mp4"; //6.1清除buffer緩存 response.reset(); response.setContentType("application/octet-stream;charset=UTF-8"); //response.setHeader("Content-Disposition", "inline; filename="+ new String(filePath.getBytes("UTF-8"), "ISO-8859-1"));// 定義文件名 //response.setHeader("Content-Disposition", "attachment; filename="+ new String(filePath.getBytes("UTF-8"), "ISO-8859-1"));// 定義文件名 response.setHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode(filePath, "UTF-8")); response.setHeader("Pragma", "no-cache"); response.setHeader("Cache-Control", "no-cache"); response.setHeader("Expires", " 0"); ServletOutputStream outputStream = response.getOutputStream(); BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream); long l = System.currentTimeMillis(); log.info(String.valueOf(System.currentTimeMillis())); int swl = 0; byte[] bytes = new byte[inputStream.available()]; while((inputStream.read(bytes))!=-1){ for(int i=0;i<bytes.length;i++){ bufferedOutputStream.write(bytes[i]^9527); } } //6.2用來刷新緩沖區(qū),刷新后可以再次寫出 bufferedOutputStream.flush(); inputStream.close(); bufferedOutputStream.close(); log.info(String.valueOf(System.currentTimeMillis())); log.info(String.valueOf(System.currentTimeMillis()-l)); }
四、小數(shù)組加載文件加解密(效率快,無內(nèi)存溢出風(fēng)險(xiǎn))【推薦】:
1.通過inputStream.read(b)
加載整個(gè)文件,inputStream.read(b)返回b大小的字節(jié),放入b數(shù)組中,循環(huán)異或加密:
@PostMapping("/swlUploadArray") public void swlUploadArray(MultipartFile file) throws IOException { String originalFilename = file.getOriginalFilename(); InputStream inputStream = file.getInputStream(); //FileInputStream inputStream = new FileInputStream((File) file); byte[] b = new byte[8*1024]; FileOutputStream fileOutputStream = new FileOutputStream(new File("D:\\"+originalFilename)); BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream); //三、小數(shù)組循環(huán)io讀取、循環(huán)加密 long l = System.currentTimeMillis(); log.info(String.valueOf(System.currentTimeMillis())); while((inputStream.read(b))!=-1){ //System.out.println(b); for(int i=0;i<b.length;i++){ bufferedOutputStream.write(b[i]^9527); } } //6.2用來刷新緩沖區(qū),刷新后可以再次寫出 bufferedOutputStream.flush(); inputStream.close(); bufferedOutputStream.close(); log.info(String.valueOf(System.currentTimeMillis())); log.info(String.valueOf(System.currentTimeMillis()-l)); }
2.通過inputStream.read(b)
加載整個(gè)文件解密:
@PostMapping("/swlDownloadArray") public void swlDownloadArray(HttpServletResponse response) throws IOException { File f2= new File("D:\\84333c1377d99d970a0984049db926ae.mp4"); boolean exists = f2.exists(); FileInputStream inputStream = new FileInputStream(f2); byte[] b = new byte[8*1024]; String filePath = "84333c1377d99d970a0984049db926ae.mp4"; //6.1清除buffer緩存 response.reset(); response.setContentType("application/octet-stream;charset=UTF-8"); //response.setHeader("Content-Disposition", "inline; filename="+ new String(filePath.getBytes("UTF-8"), "ISO-8859-1"));// 定義文件名 //response.setHeader("Content-Disposition", "attachment; filename="+ new String(filePath.getBytes("UTF-8"), "ISO-8859-1"));// 定義文件名 response.setHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode(filePath, "UTF-8")); response.setHeader("Pragma", "no-cache"); response.setHeader("Cache-Control", "no-cache"); response.setHeader("Expires", " 0"); ServletOutputStream outputStream = response.getOutputStream(); BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream); long l = System.currentTimeMillis(); log.info(String.valueOf(System.currentTimeMillis())); int swl = 0; while((inputStream.read(b))!=-1){ for(int i=0;i<b.length;i++){ bufferedOutputStream.write(b[i]^9527); } } //6.2用來刷新緩沖區(qū),刷新后可以再次寫出 bufferedOutputStream.flush(); inputStream.close(); bufferedOutputStream.close(); log.info(String.valueOf(System.currentTimeMillis())); log.info(String.valueOf(System.currentTimeMillis()-l)); }
五、解決小數(shù)組讀取文件流后,office文檔打開異常的問題:
注意看下面的代碼:
原因:這是文檔最后一次讀取文件,剩余的文件流不足b.length
造成的,不足時(shí)會在數(shù)組中補(bǔ)0,造成上傳后的文件與原文件有出入。解決方案1:采用byte[] bytes = new byte[inputStream.available()];
解決方案2(推薦):
int j; while((j=(inputStream.read(b)))!=-1){ for(int i=0;i<j;i++){ bufferedOutputStream.write(b[i]^9527); } }
總結(jié)
到此這篇關(guān)于java實(shí)現(xiàn)文件加密解密的文章就介紹到這了,更多相關(guān)java文件加密解密內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
RSA加密算法java簡單實(shí)現(xiàn)方法(必看)
下面小編就為大家?guī)硪黄猂SA加密算法java簡單實(shí)現(xiàn)方法(必看)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-09-09java中hashmap容量的初始化實(shí)現(xiàn)
這篇文章主要介紹了java中hashmap容量的初始化實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11詳解用Kotlin寫一個(gè)基于Spring Boot的RESTful服務(wù)
這篇文章主要介紹了詳解用Kotlin寫一個(gè)基于Spring Boot的RESTful服務(wù) ,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05JAVA時(shí)間存儲類Period和Duration使用詳解
這篇文章主要為大家介紹了JAVA時(shí)間存儲類Period和Duration使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09SpringBoot整合Milvus的實(shí)現(xiàn)
本文主要介紹了SpringBoot整合Milvus的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07RxJava2 Scheduler使用實(shí)例深入解析
這篇文章主要為大家介紹了RxJava2 Scheduler使用實(shí)例深入解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10SpringBoot+JavaMailSender實(shí)現(xiàn)騰訊企業(yè)郵箱配置
這篇文章主要介紹了SpringBoot+JavaMailSender實(shí)現(xiàn)騰訊企業(yè)郵箱配置,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04Springboot中使用攔截器、過濾器、監(jiān)聽器的流程分析
Javaweb三大組件:servlet、Filter(過濾器)、?Listener(監(jiān)聽器),這篇文章主要介紹了Springboot中使用攔截器、過濾器、監(jiān)聽器的流程分析,感興趣的朋友跟隨小編一起看看吧2023-12-12