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)存溢出風(fēng)險 |
| BufferedInputStream.read()與BufferedOutputStream.write() | 默認(rèn)有一個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)存溢出風(fēng)險):
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)存溢出風(fēng)險)【推薦】:
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)文章
最新Spring Security的基于內(nèi)存用戶認(rèn)證方式
本文講解SpringSecurity內(nèi)存認(rèn)證配置,適用于開發(fā)、測試等場景,通過代碼創(chuàng)建用戶及權(quán)限管理,支持密碼加密,雖簡單但不持久化,生產(chǎn)環(huán)境推薦使用數(shù)據(jù)庫或JWT等認(rèn)證方式,感興趣的朋友一起看看吧2025-07-07
SpringBoot中@Value注入靜態(tài)變量方式
SpringBoot中靜態(tài)變量無法直接用@Value注入,需通過setter方法,@Value('${}')從屬性文件獲取值,@Value('#{}')用于SpEL表達(dá)式,可注入其他bean屬性,注意bean默認(rèn)名稱為類名首字母小寫2025-08-08
解決springboot讀取application.properties中文亂碼問題
初用properties,讀取java properties文件的時候如果value是中文,會出現(xiàn)亂碼的問題,所以本文小編將給大家介紹如何解決springboot讀取application.properties中文亂碼問題,需要的朋友可以參考下2023-11-11
springboot jpa實現(xiàn)優(yōu)雅處理isDelete的默認(rèn)值
如果多個實體類都有 isDelete 字段,并且你希望在插入時為它們統(tǒng)一設(shè)置默認(rèn)值時改怎么做呢,本文為大家整理了一些方法,希望對大家有所幫助2024-11-11

