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