前言:通過瀏覽器請求文件流進行文件下載這里就不說了,網上有很多例子,這里主要是記錄一下工作中的另一個場景,一個服務器通過HTTPClient向另一個服務請求文件流,在內存中進行業務邏輯處理,並不需要下載到本地,當然,如果你想要下載本地也是可以的,把文件流寫到本地磁盤就可以了,也可以寫到文件系統中。廢話不多說。
備注(下面所說的壓縮文件都是.gz格式的)
一,服務器傳輸的是普通的文件流,沒有經過壓縮
服務器:
@RequestMapping(value = "/getCommonFile", method = RequestMethod.POST) public void getFile(HttpServletResponse response) { BufferedInputStream buffInputStream = null; OutputStream outputStream = null; try { buffInputStream = new BufferedInputStream(new FileInputStream(new File("D:\\testFile\\test.txt"))); outputStream = response.getOutputStream(); byte[] buff = new byte[1024*1024]; //如果是稍微大的文件,這里配置的大一些 int len = 0; while((len = buffInputStream.read(buff)) > 0) { //把文件流寫入到response的輸出流中,供請求端請求 outputStream.write(buff, 0, len); outputStream.flush(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if(buffInputStream != null) { buffInputStream.close(); } } catch (IOException e) { e.printStackTrace(); } try { if(outputStream != null) { outputStream.close(); } } catch (IOException e) { e.printStackTrace(); } } }
客戶端:
public void getCommonFile() throws IOException { //從服務器請求文件流,具體代碼就不貼了 CloseableHttpResponse response = HttpSender.toPost(FILE_URL, null); InputStream inputStream = response.getEntity().getContent(); ByteArrayOutputStream byteArray = new ByteArrayOutputStream(); byte[] buff = new byte[1024*1024]; //如果是稍微大的文件,這里配置的大一些 int len = 0; while((len = inputStream.read(buff)) > 0) { //把從服務端讀取的文件流保存到ByteArrayOutputSteam中 byteArray.write(buff, 0, len); byteArray.flush(); } inputStream.close(); response.close(); BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(new ByteArrayInputStream(byteArray.toByteArray()), "utf-8")); String line = null; while((line = bufferedReader.readLine()) != null) { System.out.println(line); }
二,服務器傳輸的是壓縮的文件流(直接讀取的壓縮文件)
@RequestMapping(value = "/getZipFile", method = RequestMethod.POST) public void getZipFile(HttpServletResponse response) { BufferedInputStream buffInputStream = null; OutputStream outputStream = null; try { buffInputStream = new BufferedInputStream(new FileInputStream(new File("D:\\testFile\\test.gz"))); outputStream = response.getOutputStream(); byte[] buff = new byte[1024*1024]; //如果是稍微大的文件,這里配置的大一些 int len = 0; while((len = buffInputStream.read(buff)) > 0) { //把文件流寫入到response的輸出流中,供請求端請求 outputStream.write(buff, 0, len); outputStream.flush(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if(buffInputStream != null) { buffInputStream.close(); } } catch (IOException e) { e.printStackTrace(); } try { if(outputStream != null) { outputStream.close(); } } catch (IOException e) { e.printStackTrace(); } } }
客戶端:
public void getZipFile() throws IOException { //從服務器請求文件流,具體代碼就不貼了 CloseableHttpResponse response = HttpSender.toPost(FILE_URL, null); InputStream inputStream = response.getEntity().getContent(); ByteArrayOutputStream byteArray = new ByteArrayOutputStream(); byte[] buff = new byte[1024*1024]; //如果是稍微大的文件,這里配置的大一些 int len = 0; while((len = inputStream.read(buff)) > 0) { //把從服務端讀取的文件流保存到ByteArrayOutputSteam中 byteArray.write(buff, 0, len); byteArray.flush(); } inputStream.close(); response.close(); //GZIPInputstream解壓文件,然后讀取文件 BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(new GZIPInputStream( new ByteArrayInputStream(byteArray.toByteArray())), "utf-8")); String line = null; while((line = bufferedReader.readLine()) != null) { System.out.println(line); } }
三,服務器傳輸的是壓縮的文件流(直接讀取的普通文件,然后在內存中將文件流進行壓縮)
@RequestMapping(value = "/getCommontToZipFile", method = RequestMethod.POST) public void getCommontToZipFile(HttpServletRequest request, HttpServletResponse response) { BufferedInputStream buffInputStream = null; OutputStream outputStream = null; GZIPOutputStream zipOut = null; try { outputStream = response.getOutputStream(); buffInputStream = new BufferedInputStream(new FileInputStream(new File("D:\\testFile\\test.txt"))); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); //壓縮文件 zipOut = new GZIPOutputStream(byteArrayOutputStream); byte[] buff = new byte[1024*1024]; //如果是稍微大的文件,這里配置的大一些 int len = 0; while((len = buffInputStream.read(buff)) > 0) { //把文件流寫入到byteArrayOutputStream里面 zipOut.write(buff, 0, len); zipOut.flush(); } outputStream.write(byteArrayOutputStream.toByteArray()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if(buffInputStream != null) { buffInputStream.close(); } } catch (IOException e) { e.printStackTrace(); } try { if(outputStream != null) { outputStream.close(); } } catch (IOException e) { e.printStackTrace(); } try { if(zipOut != null) { zipOut.close(); } } catch (IOException e) { e.printStackTrace(); } } }
客戶端:
和第二種情況的客戶端代碼一樣,就 不貼代碼了
四,直接讀取多個壓縮文件,把多個壓縮文件流 寫在一個byteArray中
服務端:
@RequestMapping(value = "/getMultiZipFile", method = RequestMethod.POST) public void getMultiZipFile(HttpServletRequest request, HttpServletResponse response) { ByteArrayOutputStream byteArray = new ByteArrayOutputStream(); List<File> files = new ArrayList<File>(); File file = new File("D:\\testFile\\test1.gz"); files.add(file); file = new File("D:\\testFile\\test2.gz"); files.add(file); for(File file1 : files) { readDetailDataToByteArray(byteArray, file1); } writeToResponse(byteArray, response); } public static void readDetailDataToByteArray(ByteArrayOutputStream byteArray, File file) { BufferedInputStream bufferedInputStream = null; try { bufferedInputStream = new BufferedInputStream(new FileInputStream(file)); byte[] b = new byte[1024*1024]; int j; while ((j = bufferedInputStream.read(b)) > 0) { byteArray.write(b, 0, j); byteArray.flush(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if(bufferedInputStream != null) { bufferedInputStream.close(); } } catch (Exception e) { } } } private void writeToResponse(ByteArrayOutputStream byteArray, HttpServletResponse response) { OutputStream outputStream = null; ByteArrayInputStream inputStream = null; response.addHeader(HttpHeaders.CONTENT_TYPE, "utf-8"); response.addHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=test.gz" ); GZIPOutputStream zipOut = null; ByteArrayOutputStream zipOutByteArray = new ByteArrayOutputStream(); try { outputStream = response.getOutputStream(); zipOut = new GZIPOutputStream(zipOutByteArray); inputStream = new ByteArrayInputStream(byteArray.toByteArray()); byte[] b = new byte[Integer.parseInt(buffSize)]; int j; while ((j = inputStream.read(b)) > 0) { zipOut.write(b, 0, j); zipOut.flush(); }
//這里的zipOut一定要關閉,要不然客戶端接收到的壓縮流寫到本地后,打開會報錯 zipOut.close(); outputStream.write(zipOutByteArray.toByteArray()); } catch (IOException e1) { }finally { try { if(zipOutByteArray != null) { zipOutByteArray.close(); } } catch (Exception e) { } try { if(byteArray != null) { byteArray.close(); } } catch (Exception e) { } try { if(inputStream != null) { inputStream.close(); } } catch (Exception e) { } try { if(outputStream != null) { outputStream.close(); } } catch (Exception e) { } } }
客戶端:
和第二種情況的客戶端代碼一樣,就 不貼代碼了