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

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

字节流--IO学习笔记(二)

發(fā)布時(shí)間:2023/12/20 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 字节流--IO学习笔记(二) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

IO流:
包括字節(jié)流和字符流。

在這里解釋一下我對(duì)于流的理解,其實(shí)流就相當(dāng)于一個(gè)用來(lái)運(yùn)輸字節(jié)或者字符的管道,一開(kāi)始會(huì)把所有的數(shù)據(jù)存放到流中,然后我們?cè)購(gòu)牧髦腥〕鰯?shù)據(jù)(進(jìn)行讀取或者寫(xiě)出操作),每讀或者寫(xiě)一次就會(huì)從管道中把讀或者寫(xiě)的數(shù)據(jù)取出來(lái),管道中就沒(méi)有了你剛才讀到或者寫(xiě)出的數(shù)據(jù)了。比如:
FileInputStream fis = new FileInputStream(String filename);
就會(huì)把文件名為filename的文件內(nèi)容全部存放到管道中去,然后我們進(jìn)行fis.read(),就會(huì)從管道中讀取出內(nèi)容,讀到的內(nèi)容就會(huì)從管道中消失。

字節(jié)流:

(1)InputStream:抽象了應(yīng)用程序讀取數(shù)據(jù)的方式
OutputStream : 抽象了應(yīng)用程序?qū)懗鰯?shù)據(jù)的方式
(2)輸入流的基本方法:
InputStream in = new InputStream();
int b = in.read();
讀取一個(gè)字節(jié)無(wú)符號(hào)填充到int的最后8位,返回的是讀到的字節(jié)(轉(zhuǎn)換成int類(lèi)型的值的)內(nèi)容,當(dāng)讀到-1時(shí),標(biāo)識(shí)讀取到最后結(jié)束了。
in.read(byte[] buf):讀取的數(shù)據(jù)填充到字節(jié)數(shù)組buf中,返回的是讀到的字節(jié)的個(gè)數(shù)。
in.read(byte[] buf,int start ,int size):讀取數(shù)據(jù)到字節(jié)數(shù)組buf,并且是從buf的start位置開(kāi)始,最多存放size長(zhǎng)度的數(shù)據(jù),返回的是讀到的字節(jié)的個(gè)數(shù)。
(3)輸出流的基本方法:
OutputStream out = new OutputStream();
out.write(int b):寫(xiě)出一個(gè)字節(jié)到流,寫(xiě)的是int的最后的8位
out.write(byte[] buf):將buf字節(jié)數(shù)組都寫(xiě)入到流
out.write(byte[] buf,int start,int size):字節(jié)數(shù)組buf從start位置開(kāi)始寫(xiě)size長(zhǎng)度的字節(jié)到流

下面介紹字節(jié)流基本的讀取方法的使用(注意:FileInputStream繼承了InputStream)

package com.test.FileInputStream;import java.io.FileInputStream; import java.io.IOException;public class FileInputStreamTest {public static void main(String[] args) {try {System.out.println("方式一:字節(jié)數(shù)組的長(zhǎng)度足夠存儲(chǔ)讀取的內(nèi)容");ReadFile1("C:\\Users\\Administrator\\Desktop\\javaIO\\讀取的測(cè)試文件.txt");System.out.println();System.out.println("方式二:字節(jié)數(shù)組的長(zhǎng)度不足以存儲(chǔ)讀取的內(nèi)容");ReadFile2("C:\\Users\\Administrator\\Desktop\\javaIO\\讀取的測(cè)試文件.txt");} catch (IOException e) {e.printStackTrace();}}/*** 當(dāng)字節(jié)數(shù)組的大小足夠存儲(chǔ)讀取的內(nèi)容的時(shí)候* 只讀取一次,然后打印出來(lái)就可以了*/public static void ReadFile1(String filename) throws IOException{FileInputStream fis = new FileInputStream(filename);byte[] buf = new byte[1024];//從fis中批量讀取字節(jié),放入到buf這個(gè)字節(jié)數(shù)組中, //從第0個(gè)位置開(kāi)始放,最多放buf.length個(gè) //返回的是讀到的字節(jié)的個(gè)數(shù)int bytes = fis.read(buf, 0, buf.length);int j = 1;for(int i=0;i<bytes;i++){//byte類(lèi)型8位,int類(lèi)型32位,為了避免數(shù)據(jù)轉(zhuǎn)換錯(cuò)誤,通過(guò)&0xff將高24位清零System.out.print(Integer.toHexString(buf[i]&0xff)+" ");if(j++%10==0){//每讀取10個(gè)字節(jié)就換行System.out.println();}}fis.close();}/*** 當(dāng)數(shù)組的大小沒(méi)法存儲(chǔ)讀取的全部的字節(jié)的時(shí)候,* 就要對(duì)該字節(jié)數(shù)組進(jìn)行重復(fù)利用,* 每讀取字節(jié)數(shù)組的長(zhǎng)度的內(nèi)容的時(shí)候就打印出來(lái),* 然后再次讀取該字節(jié)數(shù)組長(zhǎng)度的內(nèi)容,* 直到把所有的內(nèi)容讀取出來(lái)*/public static void ReadFile2(String filename) throws IOException{FileInputStream fis = new FileInputStream(filename);byte[] buf = new byte[1024];int bytes = 0;int j = 1;while((bytes = fis.read(buf, 0, buf.length))!=-1){//如果數(shù)組不是足夠大,要進(jìn)行多次的讀取操作for(int i = 0;i<bytes;i++){System.out.print(Integer.toHexString(buf[i]&0xff)+" ");if(j++%10==0){System.out.println();}}}fis.close();} }

讀取的文件內(nèi)容:

讀取結(jié)果截圖:

下面對(duì)比下單字節(jié)讀取與批量讀取文件的效率:

package com.test.FileInputStream;import java.io.FileInputStream; import java.io.IOException; /*** 對(duì)比單字節(jié)讀取與批量讀取同樣的文件的所用的時(shí)間* 2015年8月8日 下午9:24:31**/ public class FileInputStreamTest1 {public static void main(String[] args) {try {ReadFile1("C:\\Users\\Administrator\\Desktop\\javaIO\\問(wèn)塵 - 洛天依.mp3");ReadFile2("C:\\Users\\Administrator\\Desktop\\javaIO\\問(wèn)塵 - 洛天依.mp3");} catch (IOException e) {e.printStackTrace();}}/*** 單字節(jié)讀取文件的方式* @param filename* @throws IOException*/public static void ReadFile1(String filename) throws IOException{FileInputStream fis = new FileInputStream(filename);int b;int i = 1;long start = System.currentTimeMillis();while((b = fis.read())!=-1){ // System.out.print(Integer.toHexString(b&0xff)+" ");if(i++%10==0){ // System.out.println();}}long end = System.currentTimeMillis();System.out.println("單字節(jié)讀取所用的時(shí)間:"+(end-start));fis.close();}/*** 批量字節(jié)讀取的方式* @param filename* @throws IOException*/public static void ReadFile2(String filename) throws IOException{FileInputStream fis = new FileInputStream(filename);byte[] buf = new byte[1024];int b;int j = 1;long start = System.currentTimeMillis();while((b = fis.read(buf, 0, buf.length))!=-1){for(int i = 0;i<b;i++){ // System.out.print(Integer.toHexString(buf[i]&0xff)+" ");if(j++%10==0){ // System.out.println();}}}long end = System.currentTimeMillis();System.out.println("批量讀取所用的時(shí)間:"+(end-start));fis.close();} }


所以,批量讀取,對(duì)于大文件而言效率高,也是我們最常見(jiàn)的讀文件的方式。單字節(jié)讀取不適合大文件,大文件讀取的效率很低。

下面介紹字節(jié)流基本的寫(xiě)出方法的使用(注意:FileOutputStream繼承了OutputStream,實(shí)現(xiàn)了向文件中寫(xiě)出byte數(shù)據(jù)的方法)

package com.test.FileOutputStream;import java.io.FileOutputStream; import java.io.IOException;public class FileOutputStreamTest {public static void main(String[] args) {try {WriteFile("C:\\Users\\Administrator\\Desktop\\javaIO\\寫(xiě)入測(cè)試文件.txt");} catch (IOException e) {e.printStackTrace();}}public static void WriteFile(String filename) throws IOException{//如果該文件不存在,則直接創(chuàng)建,如果存在,刪除后創(chuàng)建FileOutputStream fos = new FileOutputStream(filename); // //如果該文件不存在,則直接創(chuàng)建,如果存在,直接在文件中追加內(nèi)容 // FileOutputStream fos = new FileOutputStream(filename,true);/** 寫(xiě)一個(gè)字符的方法(可以寫(xiě)一個(gè)字符)*/fos.write('A');//寫(xiě)出了‘A’的字節(jié)所占位的最后八位fos.write('B');/** 寫(xiě)一個(gè)整數(shù)的方法*/int i = 10;//write()方法只能寫(xiě)八位,那么寫(xiě)一個(gè)int需要寫(xiě)4次,每次8位fos.write(i>>>24);fos.write(i>>>16);fos.write(i>>>8);fos.write(i);/**寫(xiě)一個(gè)字節(jié)數(shù)組的方法 (可以直接寫(xiě)一個(gè)字節(jié)數(shù)組)*/byte[] gbk = "小灰灰".getBytes("gbk");fos.write(gbk);fos.close();}}

基本的字節(jié)輸入流和字節(jié)輸出流的整合運(yùn)用:(以Copy文件為例)

package com.test.FileOutputStream;import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException;public class CopyFile {public static void main(String[] args) {File srcFile = new File("C:\\Users\\Administrator\\Desktop\\javaIO\\被copy的文件.txt");File destFile = new File("C:\\Users\\Administrator\\Desktop\\javaIO\\copy的文件.txt");try {copyFile(srcFile, destFile);} catch (IOException e) {e.printStackTrace();}}public static void copyFile(File srcFile,File destFile) throws IOException{if(!srcFile.exists()){throw new IllegalArgumentException("文件:"+srcFile+"不存在");}if(!srcFile.isFile()){throw new IllegalArgumentException(srcFile+"不是文件");}FileInputStream fis = new FileInputStream(srcFile);FileOutputStream fos = new FileOutputStream(destFile);byte[] buf = new byte[3*1024];int i;while((i = fis.read(buf,0,buf.length))!=-1){fos.write(buf, 0, i);fos.flush();}fis.close();fos.close();}}

DataOutputStream/DataInputStream的使用:
作用:
對(duì)“流”功能的擴(kuò)展,可以更加方便的讀取int,long,字符等基本類(lèi)型的數(shù)據(jù)。

構(gòu)造方法:
DataOutputStream dos = new DataOutputStream(OutputStream out);
DataInputStream dis = new DataInputStream(InputStream in);
從構(gòu)造方法中可以看到這兩種流就是對(duì)普通流進(jìn)行了包裝,方便讀取基本類(lèi)型的數(shù)據(jù)。

DataOutputStream多出來(lái)的寫(xiě)出的方法:
writeInt()
writeDouble()
writeLong()
writeChars()//采用UTF-16BE編碼寫(xiě)出
writeUTF()//采用UTF-8編碼寫(xiě)出
……

writeInt():
write()方法一次只可以寫(xiě)出最后的8位,但是int類(lèi)型的數(shù)據(jù)是32位(4個(gè)字節(jié)),所以要write()四次才能寫(xiě)出一個(gè)int類(lèi)型的數(shù)據(jù)。

int i = 10;//write()方法只能寫(xiě)八位,那么寫(xiě)一個(gè)int需要寫(xiě)4次,每次8位fos.write(i>>>24);fos.write(i>>>16);fos.write(i>>>8);fos.write(i);

這是我們寫(xiě)一個(gè)int類(lèi)型數(shù)據(jù)的方法。
writeInt()方法可以只寫(xiě)一次就可以寫(xiě)出一個(gè)int類(lèi)型的數(shù)據(jù),其實(shí)查看源碼可以知道其實(shí)也是write()了四次。
writeInt()方法的源碼:

public final void writeInt(int v) throws IOException {out.write((v >>> 24) & 0xFF);out.write((v >>> 16) & 0xFF);out.write((v >>> 8) & 0xFF);out.write((v >>> 0) & 0xFF);incCount(4);}

writeLong(),writeDouble()……也是這樣的原理。
所以可以看出DataOutputStream就是對(duì)基本類(lèi)型的數(shù)據(jù)的寫(xiě)出方法進(jìn)行了包裝,方便我們寫(xiě)出基本類(lèi)型的數(shù)據(jù)。

BufferedInputStream/BufferedOutputStream的使用:
這兩個(gè)流為IO提供了帶緩沖區(qū)的操作,一般打開(kāi)文件進(jìn)行寫(xiě)入或者讀取操作時(shí),都會(huì)加上緩沖,這種流模式提高了IO的性能。
解釋:
從應(yīng)用程序中把數(shù)據(jù)放入文件,相當(dāng)于將一缸水倒入另一個(gè)缸中。
FileOutputStream—–>write()方法相當(dāng)于一滴水一滴水的把水轉(zhuǎn)過(guò)去
DataOutputStream—>writeXxx()方法會(huì)方便一些,相當(dāng)于一瓢一瓢的轉(zhuǎn)移過(guò)去
BufferedOutputStream—>write()方法更方便,相當(dāng)于一瓢一瓢先放入桶中,再?gòu)耐爸械谷氲搅韨€(gè)缸中,性能提高了。
注意:當(dāng)使用BufferedOutputStream的時(shí)候,當(dāng)寫(xiě)完一次后要進(jìn)行沖刷緩沖區(qū)(flush()),否則下次進(jìn)行寫(xiě)入的時(shí)候就沒(méi)法向緩沖區(qū)中存放了。
下面比較一下這些流讀取和寫(xiě)入操作的效率:

package com.test.FileInputStream;import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; /*** 對(duì)比單字節(jié)讀取與批量讀取同樣的文件的所用的時(shí)間* 2015年8月8日 下午9:24:31**/ public class FileInputStreamTest1 {public static void main(String[] args) {try {ReadFile1("C:\\Users\\Administrator\\Desktop\\javaIO\\問(wèn)塵 - 洛天依.mp3");ReadFile2("C:\\Users\\Administrator\\Desktop\\javaIO\\問(wèn)塵 - 洛天依.mp3");ReadFile3("C:\\Users\\Administrator\\Desktop\\javaIO\\問(wèn)塵 - 洛天依.mp3");ReadFile4("C:\\Users\\Administrator\\Desktop\\javaIO\\問(wèn)塵 - 洛天依.mp3");} catch (IOException e) {e.printStackTrace();}}/*** 單字節(jié)讀取文件的方式* @param filename* @throws IOException*/public static void ReadFile1(String filename) throws IOException{FileInputStream fis = new FileInputStream(filename);int b;int i = 1;long start = System.currentTimeMillis();while((b = fis.read())!=-1){ // System.out.print(Integer.toHexString(b&0xff)+" ");if(i++%10==0){ // System.out.println();}}long end = System.currentTimeMillis();System.out.println("單字節(jié)讀取所用的時(shí)間:"+(end-start));fis.close();}/*** 批量字節(jié)讀取的方式* @param filename* @throws IOException*/public static void ReadFile2(String filename) throws IOException{FileInputStream fis = new FileInputStream(filename);byte[] buf = new byte[1024];int b;int j = 1;long start = System.currentTimeMillis();while((b = fis.read(buf, 0, buf.length))!=-1){for(int i = 0;i<b;i++){ // System.out.print(Integer.toHexString(buf[i]&0xff)+" ");if(j++%10==0){ // System.out.println();}}}long end = System.currentTimeMillis();System.out.println("批量讀取所用的時(shí)間:"+(end-start));fis.close();}/*** 字節(jié)緩沖流讀取文件* @param filename* @throws IOException*/public static void ReadFile3(String filename) throws IOException{FileInputStream fis = new FileInputStream(filename);BufferedInputStream bis = new BufferedInputStream(fis);long start = System.currentTimeMillis();int b;int j = 1;while((b=bis.read())!=-1){for(int i=0;i<b;i++){ // System.out.println(Integer.toHexString(b&0xff)+" ");if(j++%10==0){ // System.out.println();}}}long end = System.currentTimeMillis();System.out.println("字節(jié)緩沖流讀取所用的時(shí)間:"+(end-start));bis.close();}/*** 字節(jié)緩沖流批量讀取文件* @param filename* @throws IOException*/public static void ReadFile4(String filename) throws IOException{FileInputStream fis = new FileInputStream(filename);BufferedInputStream bis = new BufferedInputStream(fis);byte[] buf = new byte[1024*3];long start = System.currentTimeMillis();int b;int j = 1;while((b= bis.read(buf, 0, buf.length))!=-1){for(int i = 1;i<b;i++){ // System.out.println(Integer.toHexString(buf[i]&0xff)+" ");if(j++%10==0){ // System.out.println();}}}long end = System.currentTimeMillis();System.out.println("字節(jié)緩沖流批量讀取所用的時(shí)間"+(end-start));bis.close();} }

所用時(shí)間結(jié)果截圖:

由此可以看出:
批量讀取文件的效率>字符緩沖流讀取文件的效率>單字節(jié)讀取文件的效率

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的字节流--IO学习笔记(二)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。