日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

inputstream java_Java实现inputstream流的复制

發布時間:2023/12/10 java 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 inputstream java_Java实现inputstream流的复制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

獲取到一個inputstream后,可能要多次利用它進行read的操作。由于流讀過一次就不能再讀了,而InputStream對象本身不能復制,而且它也沒有實現Cloneable接口,所以得想點辦法。

實現思路:

1、先把InputStream轉化成ByteArrayOutputStream

2、后面要使用InputStream對象時,再從ByteArrayOutputStream轉化回來

代碼實現如下:

package com.test;

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.InputStream;

public class StreamOperateUtil {

public static void main(String[] args) throws FileNotFoundException {

InputStream input = new FileInputStream("c:\\test.txt");

//InputStream input = httpconn.getInputStream(); //這里可以寫你獲取到的流

ByteArrayOutputStream baos = cloneInputStream(input);

// 打開兩個新的輸入流

InputStream stream1 = new ByteArrayInputStream(baos.toByteArray());

InputStream stream2 = new ByteArrayInputStream(baos.toByteArray());

}

private static ByteArrayOutputStream cloneInputStream(InputStream input) {

try {

ByteArrayOutputStream baos = new ByteArrayOutputStream();

byte[] buffer = new byte[1024];

int len;

while ((len = input.read(buffer)) > -1) {

baos.write(buffer, 0, len);

}

baos.flush();

return baos;

} catch (IOException e) {

e.printStackTrace();

return null;

}

}

}

這種適用于一些不是很大的流,因為緩存流是會消耗內存的。

關于InputStream為什么不能被重復讀取?

首先,熟悉Java的人可能都知道,Java中的Inputstream是不能重復讀取的。

但是有沒有想過,InputStream為什么不能重復讀呢?

其實要回答“為什么”這個問題很簡單,就是人家接口就是這么設計的,不能重復讀。

所以今天要討論的問題更像是:Java的InputStream為什么要設計為不能重復讀?

關于InputStream為什么不能重復讀取,網上也各有說法:

有的同學說:

“InputStream就類比成一個杯子,杯子里的水就像InputStream里的數據,你把杯子里的水拿出來了,杯子的水就沒有了,InputStream也是同樣的道理。”

比喻的非常好,讓我們從直觀上認識了InputStream為什么不能重復被讀。

也有的同學從更深的代碼角度去分析:

“在InputStream讀取的時候,會有一個pos指針,他指示每次讀取之后下一次要讀取的起始位置,當讀到最后一個字符的時候,pos指針不會重置。”

說的也有道理,就是說InputStream的讀取是單向的。但是并不是所有的InputStream實現類都是這樣的實現方式。

//BufferedInputStream代碼片段:

public synchronized int read() throws IOException {

if (pos >= count) {

fill();

if (pos >= count)

return -1;

}

return getBufIfOpen()[pos++] & 0xff;

}

//FileInputStream代碼片段:

public native int read() throws IOException;

我們知道:

Java 的List內部是使用數組實現的,遍歷的時候也有一個pos指針。但是沒有說List遍歷一個第二次遍歷就沒有了。第二次遍歷是創建新的Iterator,所以pos也回到了數組起始位置。對于某些InputStream當然可以也這么做。例如:ByteArrayInputStream

ByteArrayInputStream就是將一個Java的byte數組保存到對象里,然后讀取的時候遍歷該byte數組。

public ByteArrayInputStream(byte buf[]) {

this.buf = buf;

this.pos = 0;

this.count = buf.length;

}

public synchronized int read() {

return (pos < count) ? (buf[pos++] & 0xff) : -1;

}

就ByteArrayInputStream而言,要實現重復讀取是很簡單的,但是為什么沒有。我想是為了遵循InputStream的統一標準。

在InputStream的read方法的注釋上明確說明:

/**

* Reads the next byte of data from the input stream. The value byte is

* returned as an int in the range 0 to

* 255. If no byte is available because the end of the stream

* has been reached, the value -1 is returned. This method

* blocks until input data is available, the end of the stream is detected,

* or an exception is thrown.

*

*

A subclass must provide an implementation of this method.

*

* @return the next byte of data, or -1 if the end of the

* stream is reached.

* @exception IOException if an I/O error occurs.

*/

public abstract int read() throws IOException;

當流到達末尾后,返回-1.

其實像FileInputStream這樣的文件流,要實現重復使用可能也并不是很難,利用緩存什么的應該能做到(大文件讀取就悲劇了,呵呵呵)。

但是InputStream顧名思義就是一個單向的字節流,跟水流一樣,要想再次使用就自己再去源頭取一下。

InputStream其實不像杯子,更像是一根水管,要想喝水了,就在把水管架在水源與杯子之間,讓水流到杯子里(注意:這個動作完成了之后水管里面就沒有水了)。

這樣看來,InputStream其實是一個數據通道,只負責數據的流通,并不負責數據的處理和存儲等其他工作范疇。

前面講過,其實有的InputStream實現類是可以實現數據的處理工作的。但是沒有這么做,這就是規范和標準的重要性。

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的inputstream java_Java实现inputstream流的复制的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。