如何使用ByteArrayOutputStream下載文件
使用ByteArrayOutputStream下載文件
//文件名稱 String filepath = ServletActionContext.getServletContext() .getRealPath(farmerQrCode.getQrCodeUrl()); File file = new File(filepath); String fileName = new Date().getTime()+".png"; //設(shè)置請求信息 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導(dǎo)出數(shù)據(jù),然后將其下載
//此處將HSSFWorkbook wb處理好,然后最后要導(dǎo)出文件時加上此代碼。 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文本中的內(nèi)容寫入buffer數(shù)組。
這里為buffer數(shù)組指定了長度為3,所以“hello world!”這組長度為11的數(shù)據(jù)會被分成4次寫入到buffer數(shù)組中。
當(dāng)inputStream.read(buffer)把數(shù)據(jù)都寫入到buffer數(shù)組之后,它最后還會返回一次len為-1的值,代表數(shù)據(jù)完全讀完。
2、使用outStream.write(buffer, 0, len)方法,在while循環(huán)體內(nèi)把每次寫入到buffer數(shù)組的值再次疊加寫入到內(nèi)存緩沖區(qū)中。
3、使用outStream.toByteArray()方法把內(nèi)存緩沖區(qū)中的數(shù)據(jù)流轉(zhuǎn)換成字節(jié)數(shù)組。
4、最后把字符數(shù)組轉(zhuǎn)換成字符串進(jìn)行返回return new String(data)。
使用ByteArrayOutputStream解決IO亂碼
說下經(jīng)過
今天在用s3接口做ceph儲存的時候,要實(shí)現(xiàn)一個io下載的接口。
需要把InputStream轉(zhuǎn)成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)亂碼。
于是換了網(wǎng)上推薦的,使用byte緩存的方法,來實(shí)現(xiàn)InputStream轉(zhuǎn)成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(); }
亂碼的情況就解決了!
小結(jié)一下
IO這塊不是很熟悉,盡量不要用原生的方法去寫,而應(yīng)該使用JDK封裝好的方法去實(shí)現(xiàn)。避免出現(xiàn)一些意料之外的問題。
PS:至于上面那段代碼為什么會出現(xiàn)亂碼,暫時還未研究出來。
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring的IOC容器實(shí)例化bean的方式總結(jié)
IOC容器實(shí)例化bean的三種方式:構(gòu)造方法、靜態(tài)工廠、實(shí)例工廠,本文將通過代碼示例給大家詳細(xì)講解一下這三種方式,對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-01-01Java實(shí)現(xiàn)餐廳點(diǎn)餐系統(tǒng)的實(shí)例代碼
這篇文章主要介紹了Java實(shí)現(xiàn)餐廳點(diǎn)餐系統(tǒng),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-06-06SpringCloud Netfilx Ribbon負(fù)載均衡工具使用方法介紹
Ribbon是Netflix的組件之一,負(fù)責(zé)注冊中心的負(fù)載均衡,有助于控制HTTP和TCP客戶端行為。Spring Cloud Netflix Ribbon一般配合Ribbon進(jìn)行使用,利用在Eureka中讀取的服務(wù)信息,在調(diào)用服務(wù)節(jié)點(diǎn)時合理進(jìn)行負(fù)載2022-12-12servlet之session工作原理簡介_動力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了servlet之session工作原理簡介,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-07-07java實(shí)現(xiàn)多線程交替打印兩個數(shù)
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)多線程交替打印兩個數(shù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-11-11IntelliJ IDEA 2021.1 推出語音、視頻功能,邊寫代碼邊聊天(功能超級強(qiáng)大)
這篇文章主要介紹了IntelliJ IDEA 2021.1 推出語音、視頻功能,邊寫代碼邊聊天(功能超級強(qiáng)大),本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-04-04基于SpringBoot+Redis實(shí)現(xiàn)分布式鎖
本文主要介紹了基于SpringBoot+Redis實(shí)現(xiàn)分布式鎖,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05MyBatis中多對一和一對多數(shù)據(jù)的處理方法
這篇文章主要介紹了MyBatis中多對一和一對多數(shù)據(jù)的處理,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-01-01SpringBoot中注解實(shí)現(xiàn)定時任務(wù)的兩種方式
這篇文章主要介紹了SpringBoot中注解實(shí)現(xiàn)定時任務(wù)的兩種方式,SpringBoot 定時任務(wù)是一種在SpringBoot應(yīng)用中自動執(zhí)行任務(wù)的機(jī)制,通過使用Spring框架提供的@Scheduled注解,我們可以輕松地創(chuàng)建定時任務(wù),需要的朋友可以參考下2023-10-10