java實現(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)存溢出風險 |
BufferedInputStream.read()與BufferedOutputStream.write() | 默認有一個8K的緩存數(shù)組 |
二、循環(huán)每個字節(jié)加解密(此方法效率最低):
1.通過inputStream.read()
單字節(jié)加密,inputStream.read()
返回的是一個字節(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計劃.xlsx"); boolean exists = f2.exists(); FileInputStream inputStream = new FileInputStream(f2); //byte[] b = new byte[1024]; String filePath = "108B計劃.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(); }
三、加載整個文件加解密(效率快,有內(nèi)存溢出風險):
1.通過inputStream.read(bytes)
加載整個文件,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)
加載整個文件解密:
@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)存溢出風險)【推薦】:
1.通過inputStream.read(b)
加載整個文件,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)
加載整個文件解密:
@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ù)組中補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實現(xiàn)文件加密解密的文章就介紹到這了,更多相關(guān)java文件加密解密內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解用Kotlin寫一個基于Spring Boot的RESTful服務
這篇文章主要介紹了詳解用Kotlin寫一個基于Spring Boot的RESTful服務 ,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-05-05SpringBoot+JavaMailSender實現(xiàn)騰訊企業(yè)郵箱配置
這篇文章主要介紹了SpringBoot+JavaMailSender實現(xiàn)騰訊企業(yè)郵箱配置,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-04-04Springboot中使用攔截器、過濾器、監(jiān)聽器的流程分析
Javaweb三大組件:servlet、Filter(過濾器)、?Listener(監(jiān)聽器),這篇文章主要介紹了Springboot中使用攔截器、過濾器、監(jiān)聽器的流程分析,感興趣的朋友跟隨小編一起看看吧2023-12-12