如何使用ByteArrayOutputStream下載文件
使用ByteArrayOutputStream下載文件
//文件名稱 String filepath = ServletActionContext.getServletContext() .getRealPath(farmerQrCode.getQrCodeUrl()); File file = new File(filepath); String fileName = new Date().getTime()+".png"; //設置請求信息 HttpServletResponse response = ServletActionContext.getResponse(); response.setContentType(response.getContentType()); response.setHeader("Content-disposition", "attachment; filename="+fileName); ByteArrayOutputStream baos = new ByteArrayOutputStream(); int len = 0; FileInputStream inputStream = new FileInputStream(file); byte [] buffer = new byte[3]; while((len = inputStream.read(buffer)) != -1) { baos.write(buffer, 0, len); } byte[] bytes = baos.toByteArray(); response.setHeader("Content-Length", String.valueOf(bytes.length)); BufferedOutputStream bos = null; bos = new BufferedOutputStream(response.getOutputStream()); bos.write(bytes); bos.close(); baos.close();
使用POI導出數(shù)據(jù),然后將其下載
//此處將HSSFWorkbook wb處理好,然后最后要導出文件時加上此代碼。 ByteArrayOutputStream baos = new ByteArrayOutputStream(); response.setContentType(response.getContentType()); response.setHeader("Content-disposition", "attachment; filename=monthPayment.xls"); wb.write(baos); byte[] bytes = baos.toByteArray(); response.setHeader("Content-Length", String.valueOf(bytes.length)); BufferedOutputStream bos = null; bos = new BufferedOutputStream(response.getOutputStream()); bos.write(bytes); bos.close(); baos.close();
1、使用inputStream.read(buffer)方法分段的把txt文本中的內容寫入buffer數(shù)組。
這里為buffer數(shù)組指定了長度為3,所以“hello world!”這組長度為11的數(shù)據(jù)會被分成4次寫入到buffer數(shù)組中。
當inputStream.read(buffer)把數(shù)據(jù)都寫入到buffer數(shù)組之后,它最后還會返回一次len為-1的值,代表數(shù)據(jù)完全讀完。
2、使用outStream.write(buffer, 0, len)方法,在while循環(huán)體內把每次寫入到buffer數(shù)組的值再次疊加寫入到內存緩沖區(qū)中。
3、使用outStream.toByteArray()方法把內存緩沖區(qū)中的數(shù)據(jù)流轉換成字節(jié)數(shù)組。
4、最后把字符數(shù)組轉換成字符串進行返回return new String(data)。
使用ByteArrayOutputStream解決IO亂碼
說下經過
今天在用s3接口做ceph儲存的時候,要實現(xiàn)一個io下載的接口。
需要把InputStream轉成byte[],一開始,是的寫法是這樣的:
byte[] buf = new byte[(int) fileSize]; InputStream in = ossObject.getObjectContent(); try { for (int n = 0; n != -1; ) { n = in.read(buf, 0, buf.length); } } catch (IOException e) { log.error(e.getMessage()); } finally { try { in.close(); } catch (IOException e) { log.error(e.getMessage()); } }
可是下載的文件稍大一些,就會出現(xiàn)亂碼。
于是換了網上推薦的,使用byte緩存的方法,來實現(xiàn)InputStream轉成byte[]:
private static byte[] inputToByte(InputStream inStream, int fileSize) throws IOException { ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); byte[] buff = new byte[fileSize]; int rc; while ((rc = inStream.read(buff, 0, fileSize)) > 0) { swapStream.write(buff, 0, rc); } return swapStream.toByteArray(); }
亂碼的情況就解決了!
小結一下
IO這塊不是很熟悉,盡量不要用原生的方法去寫,而應該使用JDK封裝好的方法去實現(xiàn)。避免出現(xiàn)一些意料之外的問題。
PS:至于上面那段代碼為什么會出現(xiàn)亂碼,暫時還未研究出來。
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
SpringCloud Netfilx Ribbon負載均衡工具使用方法介紹
Ribbon是Netflix的組件之一,負責注冊中心的負載均衡,有助于控制HTTP和TCP客戶端行為。Spring Cloud Netflix Ribbon一般配合Ribbon進行使用,利用在Eureka中讀取的服務信息,在調用服務節(jié)點時合理進行負載2022-12-12servlet之session工作原理簡介_動力節(jié)點Java學院整理
這篇文章主要介紹了servlet之session工作原理簡介,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-07-07IntelliJ IDEA 2021.1 推出語音、視頻功能,邊寫代碼邊聊天(功能超級強大)
這篇文章主要介紹了IntelliJ IDEA 2021.1 推出語音、視頻功能,邊寫代碼邊聊天(功能超級強大),本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-04-04基于SpringBoot+Redis實現(xiàn)分布式鎖
本文主要介紹了基于SpringBoot+Redis實現(xiàn)分布式鎖,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-05-05MyBatis中多對一和一對多數(shù)據(jù)的處理方法
這篇文章主要介紹了MyBatis中多對一和一對多數(shù)據(jù)的處理,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-01-01SpringBoot中注解實現(xiàn)定時任務的兩種方式
這篇文章主要介紹了SpringBoot中注解實現(xiàn)定時任務的兩種方式,SpringBoot 定時任務是一種在SpringBoot應用中自動執(zhí)行任務的機制,通過使用Spring框架提供的@Scheduled注解,我們可以輕松地創(chuàng)建定時任務,需要的朋友可以參考下2023-10-10