Java InputStream的多種使用詳解
以前寫東西,尤其是網(wǎng)絡(luò)傳輸方面總會(huì)碰到將某種格式的文本或者圖片等轉(zhuǎn)幻成數(shù)據(jù)流的方式來傳輸,那時(shí)候用的就直接網(wǎng)上找點(diǎn)就粘貼,也沒什么搞懂到底是怎么個(gè)機(jī)理。后來抽點(diǎn)空就死啃了點(diǎn)這方面的文章,稍微懂了點(diǎn),特意分享一下。
InputStream FileInputStream BufferInputStream InputStreamreader ByteArrayInputStream這些東西到底什么關(guān)系呢?
一、首先我先理解InputStream是老大,剩下的這些都是為其服務(wù)的,先建立一個(gè)標(biāo)準(zhǔn),而FileInputStream是其子類。他可以對文件進(jìn)行數(shù)據(jù)流的轉(zhuǎn)換。
String fileName = "E:\\電影\\[高清電影]";
InputStream inputstream = new FileInputStream("fileName");//然后對InputStream 進(jìn)行讀操作,為啥是讀呢?可以把內(nèi)存當(dāng)作主體,這是某個(gè)網(wǎng)友說的,你從硬盤往內(nèi)存里Input 東西就是讀取數(shù)據(jù)咯。 另外這里因?yàn)镕ileInputStream繼承InputStream 類//所以可以這樣用
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 的語句。
File f = new File("F:\\……");
if (!f.exists()) {
System.out.println("creat " + f.toString());
f.createNewFile();
}
FileOutputStream fos = new FileOutputStream(f);//InputStream和OutputStream 一般辯證的來看,一個(gè)讀,一個(gè)寫,兩者差不多的用法。
fos.write(b, 0, len);
fos.flush();
fos.close();
二、在接下來說BufferInputStream,他是數(shù)據(jù)流緩存的東西,不帶緩沖的操作,每讀一個(gè)字節(jié)就要寫入一個(gè)字節(jié),由于涉及磁盤的IO操作相比內(nèi)存的操作要慢很多,所以不帶緩沖的流效率很低。帶緩沖的流,可以一次讀很多字節(jié),但不向磁盤中寫入,只是先放到內(nèi)存里。等湊夠了緩沖區(qū)大小的時(shí)候一次性寫入磁盤,這種方式可以減少磁盤操作次數(shù),速度就會(huì)提高很多!這就是兩者的區(qū)別。
public class InputStreamTest {
private static final String FILENAME="E:\\電影\\[高清電影]阿甘正傳.1994.美國.中文字幕.1280x720.rmvb";
public static void main(String[] args) throws IOException {
long l1 = readByBufferedInputStream();
long l2 = readByInputStream();
System.out.println("通過BufferedInputStream讀取用時(shí):"+l1+";通過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 {
/**
* 沒有緩沖區(qū),只能使用read()方法。
*/
//讀取字節(jié)流
//InputStream in = System.in;//讀取鍵盤的輸入。
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ū)對象的 read() 和 readLine()方法。
*/
//讀取字節(jié)流
//InputStream in = System.in;//讀取鍵盤上的數(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)值足夠大。類似于BufferInputStream
//只是兩者緩沖的對象不一樣。
//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來上代碼。他的作用就是把字節(jié)流轉(zhuǎn)成字符。其實(shí)我感覺沒啥用,可能是我知道的不多
從文件中讀取二進(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();
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
在springboot項(xiàng)目中同時(shí)接收文件和多個(gè)參數(shù)的方法總結(jié)
在開發(fā)接口中,遇到了需要同時(shí)接收文件和多個(gè)參數(shù)的情況,可以有多種方式實(shí)現(xiàn)文件和參數(shù)的同時(shí)接收,文中給大家介紹了兩種實(shí)現(xiàn)方法,感興趣的同學(xué)跟著小編一起來看看吧2023-08-08
java中Memcached的使用實(shí)例(包括與Spring整合)
這篇文章主要介紹了java中Memcached的使用實(shí)例(包括與Spring整合),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
spring boot udp或者tcp接收數(shù)據(jù)的實(shí)例詳解
這篇文章主要介紹了spring boot udp或者tcp接收數(shù)據(jù),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-12-12
Spring Security動(dòng)態(tài)權(quán)限的實(shí)現(xiàn)方法詳解
這篇文章主要和小伙伴們簡單介紹下 Spring Security 中的動(dòng)態(tài)權(quán)限方案,以便于小伙伴們更好的理解 TienChin 項(xiàng)目中的權(quán)限方案,感興趣的可以了解一下2022-06-06
Java在高并發(fā)場景下實(shí)現(xiàn)點(diǎn)贊計(jì)數(shù)器
點(diǎn)贊計(jì)數(shù)器的本質(zhì)就是對某個(gè)變量在高并發(fā)情況下的修改,這篇文章主要為大家介紹了Java實(shí)現(xiàn)點(diǎn)贊計(jì)數(shù)器的示例代碼,感興趣的小伙伴可以了解一下2023-06-06
關(guān)于SpringBoot大文件RestTemplate下載解決方案
這篇文章主要介紹了SpringBoot大文件RestTemplate下載解決方案,最近結(jié)合網(wǎng)上案例及自己總結(jié),寫了一個(gè)分片下載tuling/fileServer項(xiàng)目,需要的朋友可以參考下2021-10-10
Java 數(shù)據(jù)結(jié)構(gòu)與算法系列精講之字符串暴力匹配
字符串暴力匹配算法是指在一個(gè)長字符串中暴力尋找是否包含某一子串所謂暴力匹配,就是不使用任何其他算法,將兩個(gè)字符串中的字符一一進(jìn)行比對2022-02-02
Redisson分布式信號量RSemaphore的使用超詳細(xì)講解
這篇文章主要介紹了Redisson分布式信號量RSemaphore的使用,基于Redis的Redisson的分布式信號量RSemaphore采用了與java.util.concurrent.Semaphore相似的接口和用法2023-02-02

