Java InputStream的多種使用詳解
以前寫(xiě)東西,尤其是網(wǎng)絡(luò)傳輸方面總會(huì)碰到將某種格式的文本或者圖片等轉(zhuǎn)幻成數(shù)據(jù)流的方式來(lái)傳輸,那時(shí)候用的就直接網(wǎng)上找點(diǎn)就粘貼,也沒(méi)什么搞懂到底是怎么個(gè)機(jī)理。后來(lái)抽點(diǎn)空就死啃了點(diǎn)這方面的文章,稍微懂了點(diǎn),特意分享一下。
InputStream FileInputStream BufferInputStream InputStreamreader ByteArrayInputStream這些東西到底什么關(guān)系呢?
一、首先我先理解InputStream是老大,剩下的這些都是為其服務(wù)的,先建立一個(gè)標(biāo)準(zhǔn),而FileInputStream是其子類(lèi)。他可以對(duì)文件進(jìn)行數(shù)據(jù)流的轉(zhuǎn)換。
String fileName = "E:\\電影\\[高清電影]";
InputStream inputstream = new FileInputStream("fileName");//然后對(duì)InputStream 進(jìn)行讀操作,為啥是讀呢?可以把內(nèi)存當(dāng)作主體,這是某個(gè)網(wǎng)友說(shuō)的,你從硬盤(pán)往內(nèi)存里Input 東西就是讀取數(shù)據(jù)咯。 另外這里因?yàn)镕ileInputStream繼承InputStream 類(lèi)//所以可以這樣用
byte[] by = new byte[8192];//此數(shù)字不唯一哦;
int len ;
while( (len=inputStream.read(by))!=-1 ){ //len就是得出的字節(jié)流了。
}
inputStream.close();//最后別忘記關(guān)閉,當(dāng)然應(yīng)該還有個(gè)if判斷是否為空和try catch 的語(yǔ)句。
File f = new File("F:\\……");
if (!f.exists()) {
System.out.println("creat " + f.toString());
f.createNewFile();
}
FileOutputStream fos = new FileOutputStream(f);//InputStream和OutputStream 一般辯證的來(lái)看,一個(gè)讀,一個(gè)寫(xiě),兩者差不多的用法。
fos.write(b, 0, len);
fos.flush();
fos.close();
二、在接下來(lái)說(shuō)BufferInputStream,他是數(shù)據(jù)流緩存的東西,不帶緩沖的操作,每讀一個(gè)字節(jié)就要寫(xiě)入一個(gè)字節(jié),由于涉及磁盤(pán)的IO操作相比內(nèi)存的操作要慢很多,所以不帶緩沖的流效率很低。帶緩沖的流,可以一次讀很多字節(jié),但不向磁盤(pán)中寫(xiě)入,只是先放到內(nèi)存里。等湊夠了緩沖區(qū)大小的時(shí)候一次性寫(xiě)入磁盤(pán),這種方式可以減少磁盤(pán)操作次數(shù),速度就會(huì)提高很多!這就是兩者的區(qū)別。
public class InputStreamTest {
private static final String FILENAME="E:\\電影\\[高清電影]阿甘正傳.1994.美國(guó).中文字幕.1280x720.rmvb";
public static void main(String[] args) throws IOException {
long l1 = readByBufferedInputStream();
long l2 = readByInputStream();
System.out.println("通過(guò)BufferedInputStream讀取用時(shí):"+l1+";通過(guò)InputStream讀取用時(shí):"+l2);
}
public static long readByInputStream() throws IOException {
InputStream in=new FileInputStream(FILENAME);
byte[] b=new byte[8192];
int l=0;
long start=System.currentTimeMillis();
while(in.read(b,0,8192)!=-1){
}
long end=System.currentTimeMillis();
return end-start;
}
public static long readByBufferedInputStream() throws IOException {
BufferedInputStream in=new BufferedInputStream(new FileInputStream(FILENAME));
byte[] b=new byte[8192];
int l=0;
long start=System.currentTimeMillis();
while(in.read(b,0,8192)!=-1){
}
long end=System.currentTimeMillis();
return end-start;
}
}
三、InputStreamreader其實(shí)就是將字節(jié)流轉(zhuǎn)成字符流。
import java.io.*;
class InputStreamReaderDemo {
public static void transReadNoBuf() throws IOException {
/**
* 沒(méi)有緩沖區(qū),只能使用read()方法。
*/
//讀取字節(jié)流
//InputStream in = System.in;//讀取鍵盤(pán)的輸入。
InputStream in = new FileInputStream("D:\\demo.txt");//讀取文件的數(shù)據(jù)。
//將字節(jié)流向字符流的轉(zhuǎn)換。要啟用從字節(jié)到字符的有效轉(zhuǎn)換,
//可以提前從底層流讀取更多的字節(jié).
InputStreamReader isr = new InputStreamReader(in);//讀取
//綜合到一句。
//InputStreamReader isr = new InputStreamReader(
//new FileInputStream("D:\\demo.txt"));
char []cha = new char[1024];
int len = isr.read(cha);
System.out.println(new String(cha,0,len));
isr.close();
}
public static void transReadByBuf() throws IOException {
/**
* 使用緩沖區(qū) 可以使用緩沖區(qū)對(duì)象的 read() 和 readLine()方法。
*/
//讀取字節(jié)流
//InputStream in = System.in;//讀取鍵盤(pán)上的數(shù)據(jù)
InputStream in = new FileInputStream("D:\\demo.txt");//讀取文件上的數(shù)據(jù)。
//將字節(jié)流向字符流的轉(zhuǎn)換。
InputStreamReader isr = new InputStreamReader(in);//讀取
//創(chuàng)建字符流緩沖區(qū)
BufferedReader bufr = new BufferedReader(isr);//從字符輸入流中讀取文本,緩沖各個(gè)字符,從而實(shí)現(xiàn)字符、數(shù)組和行的
//高效讀取。 可以指定緩沖區(qū)的大小,或者可使用默認(rèn)的大小。大多數(shù)情況下,默認(rèn)值足夠大。類(lèi)似于BufferInputStream
//只是兩者緩沖的對(duì)象不一樣。
//BufferedReader bufr = new BufferedReader(
//new InputStreamReader(new FileInputStream("D:\\demo.txt")));可以綜合到一句。
/*int ch =0;
ch = bufr.read();
System.out.println((char)ch);
*/
String line;
while((line = bufr.readLine())!=null){
System.out.println(line);
}
isr.close();
}
}
四、最后一個(gè)ByteArrayInputStream 這個(gè)其實(shí)用的的不多,但是ByteArrayOutputStream還是用的多點(diǎn),所以拿ByteArrayOutputStream來(lái)上代碼。他的作用就是把字節(jié)流轉(zhuǎn)成字符。其實(shí)我感覺(jué)沒(méi)啥用,可能是我知道的不多
從文件中讀取二進(jìn)制數(shù)據(jù),全部存儲(chǔ)到ByteArrayOutputStream中。
FileInputStream fis=new FileInputStream("test");
BufferedInputStream bis=new BufferedInputStream(fis);
ByteArrayOutputStream baos=new ByteArrayOutputStream();
int c=bis.read();//讀取bis流中的下一個(gè)字節(jié)
while(c!=-1){
baos.write(c);
c=bis.read();
}
bis.close();
byte retArr[]=baos.toByteArray();
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
idea運(yùn)行main方法或Test避免編譯整個(gè)應(yīng)用的實(shí)現(xiàn)方法
這篇文章主要介紹了idea運(yùn)行main方法或Test避免編譯整個(gè)應(yīng)用的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04
Java中對(duì)象的創(chuàng)建和銷(xiāo)毀過(guò)程詳析
這篇文章主要介紹了Java中對(duì)象的創(chuàng)建和銷(xiāo)毀過(guò)程,對(duì)象的創(chuàng)建過(guò)程包括類(lèi)加載檢查、內(nèi)存分配、初始化零值內(nèi)存、設(shè)置對(duì)象頭和執(zhí)行init方法,對(duì)象的銷(xiāo)毀過(guò)程由垃圾回收機(jī)制負(fù)責(zé),文中介紹的非常詳細(xì),需要的朋友可以參考下2025-02-02
Java模擬實(shí)現(xiàn)HashMap算法流程詳解
在java開(kāi)發(fā)中,HashMap是最常用、最常見(jiàn)的集合容器類(lèi)之一,文中通過(guò)示例代碼介紹HashMap為啥要二次Hash,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2023-02-02
布隆過(guò)濾器詳解以及其在Java中的實(shí)際應(yīng)用
布隆過(guò)濾器是一種數(shù)據(jù)結(jié)構(gòu),比較巧妙的概率型數(shù)據(jù)結(jié)構(gòu)(probabilistic data structure),特點(diǎn)是高效地插入和查詢(xún),這篇文章主要給大家介紹了關(guān)于布隆過(guò)濾器詳解以及其在Java中的實(shí)際應(yīng)用,需要的朋友可以參考下2023-12-12
Java分析Lambda表達(dá)式Stream流合并分組內(nèi)對(duì)象數(shù)據(jù)合并
Lambda表達(dá)式,基于Lambda所帶來(lái)的函數(shù)式編程,又引入了一個(gè)全新的Stream概念,用于解決集合類(lèi)庫(kù)既有的弊端,Lambda 允許把函數(shù)作為一個(gè)方法的參數(shù)(函數(shù)作為參數(shù)傳遞進(jìn)方法中)。使用 Lambda 表達(dá)式可以使代碼變的更加簡(jiǎn)潔緊湊2022-12-12
Java如何使用spire進(jìn)行word文檔的替換詳解
創(chuàng)作一份文案經(jīng)常會(huì)高頻率地使用某些詞匯,如地名、人名、人物職位等,若表述有誤,就需要整體撤換,下面這篇文章主要給大家介紹了關(guān)于Java如何使用spire進(jìn)行word文檔的替換的相關(guān)資料,需要的朋友可以參考下2023-01-01
Java RPC框架如何實(shí)現(xiàn)客戶(hù)端限流配置
這篇文章主要介紹了Java RPC框架如何實(shí)現(xiàn)客戶(hù)端限流配置,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02

