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

歡迎訪問 生活随笔!

生活随笔

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

java

详细领略Java的输入流和输出流

發布時間:2023/12/31 java 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 详细领略Java的输入流和输出流 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

狼北前言

說到java的輸入流和輸出流,IO流分為兩種的(字節流和字符流),那么我們首先就得了解什么是java的字節流和字符流,然后我才來了解怎么操作這些流來寫入文件中和寫出文件。所以我這篇文章分為兩大部分,第一部分是“IO流”,第二部分是“操作io流”。廢話不多說讓猿猴帶你一起來領略這里面的一二。(對博主感興趣可以加博主的抖音號langbei57048

Java的IO流

什么是流

Java中的流是對字節序列的抽象,我們可以想象有一個水管,只不過現在流動在水管中的不再是水,而是字節序列。和水流一樣,Java中的流也具有一個“流動的方向”,通常可以從中讀入一個字節序列的對象被稱為輸入流;能夠向其寫入一個字節序列的對象被稱為輸出流。

字節流

Java中的字節流處理的最基本單位為單個字節(字節規定一個字節由八個二進制位構成)它通常用來處理二進制數據。Java中最基本的兩個字節流類是InputStream和OutputStream,它們分別代表了最基本的輸入字節流和輸出字節流。

字符流

Java中的字符流處理的最基本的單元是Unicode碼元(大小2字節),它通常用來處理文本數據。所謂Unicode碼元,也就是一個Unicode代碼單元,范圍是0x0000~0xFFFF。在以上范圍內的每個數字都與一個字符相對應,Java中的String類型默認就把字符以Unicode規則編碼而后存儲在內存中。然而與存儲在內存中不同,存儲在磁盤上的數據通常有著各種各樣的編碼方式。使用不同的編碼方式,相同的字符會有不同的二進制表示。實際上字符流是這樣工作的:

輸出字符流:把要寫入文件的字符序列(實際上是Unicode碼元序列)轉為指定編碼方式下的字節序列,然后再寫入到文件中;

輸入字符流:把要讀取的字節序列按指定編碼方式解碼為相應字符序列(實際上是Unicode碼元序列)從而可以存在內存中。
字符流與字節流的區別

經過以上的描述,我們可以知道字節流與字符流之間主要的區別體現在以下幾個方面:

字節流操作(讀寫)的基本單元為字節;字符流操作的基本單元為Unicode碼元。

字節流默認不使用緩沖區;字符流使用緩沖區。

字節流通常用于處理二進制數據,實際上它可以處理任意類型的數據,但它不支持直接寫入或讀取Unicode碼元;字符流通常處理文本數據,它支持寫入及讀取Unicode碼元。

只是讀寫文件,和文件內容無關的,一般選擇字節流。

字節流使用場景

字節流適合所有類型文件的數據傳輸,因為計算機字節(Byte)是電腦中表示信息含義的最小單位,因為在通常情況下一個ACSII碼就是一個字節的空間來存放。

字符流使用場景

字符流只能夠處理純文本數據(文本文件),其他類型數據不行,但是字符流處理文本要比字節流處理文本要方便。

字符流按字符讀數據:一次讀兩個字節,返回了這兩個字節所對應的字符的int型數值(編碼)。寫入文件時把這兩個字節的內容解碼成這個字符在Unicode碼下對應的二進制數據寫入。即把原始文件中的二進制數據以字符形式讀出,再將字符以二進制形式寫入,所以得到的文件以字符方式存儲。而圖片的數據是按字節存儲的,所以打開圖片時解碼出錯了!字節流按字節讀數據:而字節不需要編碼、解碼,只有字節與字符之間轉換時才需要編碼、解碼!所以可以正常讀取圖片數據。


操作IO流

我們在進行Android java 開發的時候,經常會遇到各種IO流操作。IO流操作一般分為兩類:字符流和字節流。以“Reader”結尾都是字符流,操作的都是字符型的數據;以“Stream”結尾的都是字節流,操作的都是byte數據。現將各種常見IO流總結如下:

一、字節流

1.InputStream 和 OutputStream

InputStream 和 OutputStream為各種輸入輸出字節流的基類,所有字節流都繼承這兩個基類。

2.FileInputStream 和 FileOutputStream

這兩個從字面意思很容易理解,是對文件的字節流操作,也會最常見的IO操作流。

都是有兩個構造函數:

輸入流 FileinputStream(File file或者String filePath)

輸出流FileoutputStream(File file或者String filePath)

方法:

①read() :從輸入流中一次讀取一個字節,讀完一個字節自動讀取數據的下一個字節,返回0到255范圍內的int字節值。如果因為已經到達流末尾而沒有可用的字節,則返回*-1*。在輸入數據可用、檢測到流末尾或者拋出異常前,此方法一直阻塞。

理解read()讀取的字節為什么返回int型變量

1、方法解釋中的-1相當于是數據字典告訴調用者文件已到底,可以結束讀取了,這里的-1是Int型 那么當文件未到底時,我們讀取的是字節,若返回byte類型,那么勢必造成同一方法返回類型不同的情況這是不允許的2、我們讀取的字節實際是由8位二進制組成,二進制文件不利于直觀查看,可以轉成常用的十進制進行展示,因此需要把讀取的字節從二進制轉成十進制整數,故返回int型3、 因此結合以上3點,保證返回類型一致以及直觀查看的情況,因此該方法雖然讀取的是字節但返回int型

②read(byte[] b) :從輸入流中讀取一定數量的字節,并將其讀取存儲在緩沖區數組 b 中。以整數形式返回實際讀取的字節數。在輸入數據可用、檢測到文件末尾或者拋出異常前,此方法一直阻塞。如果因為流位于文件末尾而沒有可用的字節,則返回值 -1;每次讀取的字節數是緩沖區數組的最大儲存字節數(new byte[2] 數組最多儲存2個字節,那么read(byte)每一次只能讀到2字節,并且數組是滿的狀態),下一次調用讀取的字節存入這個數組會替代掉上一次數組的內容(返回的是讀了多少個字節而讀到的字節內容儲存到了b緩沖區中)

eg:我們文本文件儲存的是123456

//注意下面我是簡單寫法,拋出異常那些都沒寫File file=new File("D://text.txt");FileInputStream fileInputStream=new FileInputStream(file); //獲取文件輸入流byte[] b=new byte[2]; //new一個字節數數據來當緩沖區,數組大小為2個字節 int i=0;while (n!=-1) //當n不等于-1,則代表沒到末尾{ n=fileInputStream.read(b);//讀取到緩存區中返回每一次實際讀取到字節數組中的字節數 System.out.println(n); //在文件內容字節足夠時讀到的就是2個字節,但是結尾不夠2 個字節了,那么讀到的就是剩下的字節數System.out.println(Arrays.toString(b)); //讀取后的字節數組內容 i++;System.out.println("執行次數:"+i); }System.out.println(new String(b));}

? 結果是:read(b)因為我們設置b數組大小是2個字節,所以每次讀出都是倆2字節,但最后不夠2個字節(只剩下一個字節),所以read(b)返回讀到的字節數是1,但是緩存區的數組是【最后一個字節,前一次留下來的】,因為只剩一個字節只能替代b數據的第一項

③read(byte[] bytes,int off ,int len) 參數的byte照樣是緩存區數組,off是讀取字節的開始位置,len是每次讀取的的字節數

那么這個和上面read(b)的區別就是他指定了每一次讀出多少個字節,而不再用每一次讀滿一個緩存數組的形式,并且這一個可以指定讀取字節開始的位置。返回的也是實際每次讀取到的字節數而不是字節,字節都儲存在緩存數組里。(比如,new bety[10], read(bety,0,9),那么每次讀進數組的是9個字節,那么每次數據就會剩下一個字節項,那么下一次用read讀,讀到的第一個字節就會放在數組的最后一個位置,而剩下的8個字節替換掉上次的前8個字節,想想就復雜 )。

我們常用的是read(b)接下來我們來完整的演示使用過程吧!

/* * 以字節為單位讀取文件,常用于讀二進制文件,如圖片、聲音、影像等文件。*/public static void readFileByBytes(String inFile, String outFile) {File file = new File(fileName); //①寫好文件路徑try {byte[] tempbytes = new byte[100]; //②創建數組當緩存區int byteread = 0;InputStream in = new FileInputStream(inFile); //③獲取文件輸入流OutputStream out = new FileOutputStream(outFile); //④獲取打開文件while ((byteread = in.read(tempbytes)) != -1) {//⑤每次讀取100個字節進入緩存數組out.write(tempbytes, 0, byteread); //⑥立即從緩沖區中寫入文件,每次寫入的字節數必須和實際讀到的字節數相同}} catch (Exception e1) {e1.printStackTrace();} finally {if (in != null) {try {in.close();} catch (IOException e1) {}try {out.close();} catch (IOException e1) {}}}}

3.BufferedInputStream 和 BufferedOutputStream

BufferedInputStream是帶緩沖區的輸入流,它繼承于FilterInputStream。默認緩沖區大小是8M,能夠減少訪問磁盤的次數,提高文件讀取性能。

BufferedOutputStream是帶緩沖區的輸出流,它繼承于FilterOutputStream,能夠提高文件的寫入效率。

它們提供的“緩沖功能”本質上是通過一個內部緩沖區數組實現的。例如,在新建某輸入流對應的BufferedInputStream后,當我們通過read()讀取輸入流的數據時,BufferedInputStream會將該輸入流的數據分批的填入到緩沖區中。每當緩沖區中的數據被讀完之后,輸入流會再次填充數據緩沖區;如此反復,直到我們讀完輸入流數據。(其實書寫的步驟是一樣的,內在區別)

public static void readAndWrite(String[] args) { try {BufferedInputStream bis = new BufferedInputStream(new FileInputStream("f:/a.mp3"));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("f:/b.mp3"));byte[] b=new byte[1024];int len=0;while(-1!= (len = bis.read(b, 0, b.length))) {bos.write(b, 0, len);}} catch (FileNotFoundException e) {System.out.println("文件找不到");e.printStackTrace();} catch (IOException e) {e.printStackTrace();}finally{if (null! = bos){bos.close();}if (null! = bis){bis.close();}} }

4.DataInputStream和DataOutputStream

DataInputStream 是數據輸入流,它繼承于FilterInputStream。
DataOutputStream 是數據輸出流,它繼承于FilterOutputStream。
二者配合使用,“允許應用程序以與機器無關方式從底層輸入流中讀寫基本 Java 數據類型”。

/*** DataOutputStream的API測試函數*/ private static void testDataOutputStream() {DataOutputStream out = null;try {File file = new File("file.txt");out = new DataOutputStream(new FileOutputStream(file));out.writeBoolean(true);out.writeByte((byte)0x41);out.writeChar((char)0x4243);out.writeShort((short)0x4445);out.writeInt(0x12345678);out.writeLong(0x0FEDCBA987654321L);out.writeUTF("abcdefg");} catch (FileNotFoundException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {try {out.close();} catch(IOException e) {}} }/*** DataInputStream的API測試函數*/ private static void testDataInputStream() {DataInputStream in = null;try {File file = new File("file.txt");in = new DataInputStream(new FileInputStream(file));System.out.printf("byteToHexString(0x8F):0x%s\n", byteToHexString((byte)0x8F));System.out.printf("charToHexString(0x8FCF):0x%s\n", charToHexString((char)0x8FCF));System.out.printf("readBoolean():%s\n", in.readBoolean());System.out.printf("readByte():0x%s\n", byteToHexString(in.readByte()));System.out.printf("readChar():0x%s\n", charToHexString(in.readChar()));System.out.printf("readShort():0x%s\n", shortToHexString(in.readShort()));System.out.printf("readInt():0x%s\n", Integer.toHexString(in.readInt()));System.out.printf("readLong():0x%s\n", Long.toHexString(in.readLong()));System.out.printf("readUTF():%s\n", in.readUTF());} catch (FileNotFoundException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {try {in.close();} catch(IOException e) {}}


二.字符流


二、字符流

1.InputStreamReader 和 OutputStreamWriter

InputStreamReader 和 OutputStreamWriter為各種輸入輸出字符流的基類,所有字符流都繼承這兩個基類。實際上,這兩個類內部各自持有一個inputStream 和 outputStream對象,相當于是對inputStream 和 outputStream進行了包裝,將輸入字節流轉換成字符流,便于讀寫操作。

/*** 以字符為單位讀取文件,常用于讀文本,數字等類型的文件*///用reader的read()一次只讀一個字符public static void readFileByChars(String fileName) {File file = new File(fileName);Reader reader = null;try {System.out.println("以字符為單位讀取文件內容,一次讀一個字節:");//1. 一次讀一個字符 reader = new InputStreamReader(new FileInputStream(file));//可以是任意的InputStream類,不一定必須FileInputStreamint tempchar;while ((tempchar = reader.read()) != -1) {if (((char) tempchar) != '\r') {System.out.print((char) tempchar);}}reader.close();} catch (Exception e) {e.printStackTrace();}----------------------------------------------------------------------------------------//用用reader的read(b)一次讀數組大小個字符try {System.out.println("以字符為單位讀取文件內容,一次讀多個字節:");//2. 一次讀多個字符char[] tempchars = new char[30];int charread = 0;reader = new InputStreamReader(new FileInputStream(fileName));while ((charread = reader.read(tempchars)) != -1) {for (int i = 0; i < charread; i++) {if (tempchars[i] != '\r') {System.out.print(tempchars[i]);}}}} catch (Exception e1) {e1.printStackTrace();} finally {if (reader != null) {try {reader.close();} catch (IOException e1) {}}} }

2.FileReader 和 FileWriter

FileReader 和 FileWriter分別繼承自 inputStreamReader 和 outputStreamWriter。它是對讀取文件操作系統的封裝,所有的讀寫都是直接操作文件系統。因此如果是頻繁讀寫操作,不建議使用FileReader 和 FileWriter,性能將會非常低,這時你需要使用BufferedReader。

(1)FileWriter類

構造方法:

FileWriter fw = new FileWriter(String fileName); //創建字符輸出流類對象和已存在的文件相關聯。文件不存在的話,并創建。
FileWriter fw = new FileWriter(String fileName,boolean append); //創建字符輸出流類對象和已存在的文件相關聯,并設置該該流對文件的操作是否為續寫。

主要方法:

write(char[] buffer, int offset, int count) //將字符數組寫入,offset為數組的起始地址,count為需要寫入的字符數
void write(String str) //寫入字符串。當執行完此方法后,字符數據還并沒有寫入到目的文件中去。此時字符數據會保存在緩沖區中。
viod flush() //刷新該流中的緩沖。將緩沖區中的字符數據保存到目的文件中去。
viod close() //關閉此流。在關閉前會先刷新此流的緩沖區。在關閉后,再寫入或者刷新的話,會拋IOException異常。

(2)FileReader類

構造方法:

FileReader fr = new FileReader(String fileName); //使用帶有指定文件的String參數的構造方法。創建該輸入流對象。并關聯源文件。

主要方法:

int read(); // 讀取單個字符。返回作為整數讀取的字符,如果已達到流末尾,則返回 -1。
int read(char []cbuf); //將字符讀入數組。返回讀取的字符數。如果已經到達尾部,則返回-1。
void close(); //關閉此流對象。釋放與之關聯的所有資源。

public static void readAndWrite() {FileReader fr = null;FileWriter fw = null;try {fr = new FileReader("C:\\my.txt");fw = new FileWriter("D:\\you.txt");//1.讀一個字符,寫一個字符方法int ch = 0; while ((ch = fr.read()) != -1) { fw.write(ch); } //2.讀一個數組大小,寫一個數組大小方法。char []buf = new char[1024];int len = 0;while((len = fr.read(buf)) != -1){fw.write(buf, 0, len); }//3.直接寫一個字符串fw.write("hello world!");} catch (Exception e) {System.out.println(e.toString());} finally {if (fr != null)try {fr.close();} catch (Exception e2) {throw new RuntimeException("關閉失敗!");}if (fw != null){try {fw.close();} catch (IOException e) {throw new RuntimeException("關閉失敗!");}}} }

4.BufferedReader 和 BufferedWriter

(1)BufferedReader和BufferedWriter類各擁有8192字符的緩沖區。當BufferedReader在讀取文本文件時,會先盡量從文件中讀入字符數據并置入緩沖區,而之后若使用read()方法,會先從緩沖區中進行讀取。如果緩沖區數據不足,才會再從文件中讀取,使用BufferedWriter時,寫入的數據并不會先輸出到目的地,而是先存儲至緩沖區中。如果緩沖區中的數據滿了,才會一次對目的地進行寫出。
(2)從標準輸入流System.in中直接讀取使用者輸入時,使用者每輸入一個字符,System.in就讀取一個字符。為了能一次讀取一行使用者的輸入,使用了BufferedReader來對使用者輸入的字符進行緩沖。readLine()方法會在讀取到使用者的換行字符時,再一次將整行字符串傳入

/*** 以行為單位讀取文件,常用于讀面向行的格式化文件*/ public static void readWithBufferedReader(String fileName) {File file = new File(fileName);BufferedReader reader = null;try {reader = new BufferedReader(new FileReader(file));String tempString = null;int line = 1;// 一次讀入一行,直到讀入null為文件結束while ((tempString = reader.readLine()) != null) {System.out.println("line " + line + ": " + tempString);line++;}reader.close();} catch (IOException e) {e.printStackTrace();} finally {if (reader != null) {try {reader.close();} catch (IOException e1) {}}} }

System.in是一個位流,為了轉換為字符流,可使用InputStreamReader為其進行字符轉換,然后再使用BufferedReader為其增加緩沖功能。例如:

public static void readAndWrite() { try { //緩沖System.in輸入流 //System.in是位流,可以通過InputStreamReader將其轉換為字符流 BufferedReader bufReader = new BufferedReader(new InputStreamReader(System.in)); //緩沖FileWriter BufferedWriter bufWriter = new BufferedWriter(new FileWriter("/sdcard/log/test.txt")); String input = null; //每讀一行進行一次寫入動作 while(!(input = bufReader.readLine())) { bufWriter.write(input); //newLine()方法寫入與操作系統相依的換行字符,依執行環境當時的OS來決定該輸出那種換行字符 bufWriter.newLine(); } bufReader.close(); bufWriter.close(); } catch(ArrayIndexOutOfBoundsException e) { System.out.println("沒有指定文件"); } catch(IOException e) { e.printStackTrace(); }}

三、 RandomAccessFile

RandomAccessFile不屬于InputStream和OutputStream類系的。實際上,它和這兩個類系毫不相干,甚至不使用InputStream和OutputStream類中已經存在的任何功能;它是一個完全獨立的類。這可能是因為RandomAccessFile能在文件里面前后移動,所以它的行為與其它的I/O類有些根本性的不同。
RandomAccessFile的基本功能有:定位用的getFilePointer( ),在文件里移動用的seek( ),以及判斷文件大小的length( )、skipBytes()跳過多少字節數。此外,它的構造函數還要一個表示以只讀方式(“r”),還是以讀寫方式(“rw”)打開文件的參數。實際它和C的fopen()一模一樣,都是直接對文件句柄操作。

/** * 隨機讀取文件內容 */public static void readFileByRandomAccess(String fileName) { RandomAccessFile randomFile = null; try { // 打開一個隨機訪問文件流,按只讀方式 randomFile = new RandomAccessFile(fileName, "rw"); long fileLength = randomFile.length(); // 設置讀寫文件的起始位置 randomFile.seek(0); // 一次讀取多個數據 byte[] bytes = new byte[10]; int byteread = 0; while ((byteread = randomFile.read(bytes)) != -1) { System.out.write(bytes, 0, byteread); } //一次寫入多個數據 randomFile.write(bytes); // 一次讀取單個數據 randomFile() // 一次寫入單個數據 randomFile.writeDouble(47.0001); } catch (IOException e) { e.printStackTrace(); } finally { if (randomFile != null) { try { randomFile.close(); } catch (IOException e1) { } } }}

總結

以上是生活随笔為你收集整理的详细领略Java的输入流和输出流的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 国产wwwwww| 另类二区| 少妇人妻好深好紧精品无码 | 人妻夜夜爽天天爽 | 欧美一级看片 | 黄色a免费 | 澳门av网站 | 人妻人人澡人人添人人爽 | 日韩一区二区在线观看视频 | 天堂中文在线官网 | 潘金莲一级淫片aaaaa | 欧美日本高清 | 欧美国产在线一区 | 操色网 | 日韩中文字幕免费观看 | 色噜噜狠狠一区二区 | 永久免费无码av网站在线观看 | 青青草华人在线 | 女人脱了内裤趴开腿让男躁 | 国产50页 | 欧美1区2区| 欧美成人精品一区二区免费看片 | 全毛片| 国产无套丰满白嫩对白 | 精品人妻无码专区视频 | 日韩精品一区二区三区视频 | 亚洲福利在线视频 | 无码人妻丰满熟妇精品 | 亚洲综合一区在线观看 | 中文字幕第2页 | 欧美乱三级 | www.三级.com| 一区二区三区免费看视频 | av之家在线| 人人草在线 | 欧美亚洲日本国产 | 三级a做爰全过程 | 成人毛片在线免费观看 | 黑人精品一区二区 | 精品乱子伦一区二区三区 | 亚洲精品99 | 欧美伊人影院 | 懂色av一区二区三区蜜臀 | 欧洲高潮三级做爰 | 国产精品偷伦视频免费看 | 91福利一区二区 | 欧洲女性下面有没有毛发 | 免费在线不卡av | 亚洲精品国产精品国自产网站按摩 | 天降女子在线观看 | 九草网| 色综合天天综合网天天狠天天 | 污免费在线观看 | 欧美日韩网站 | 成人免费视频一区 | 肉嫁高柳家 高清 | 先锋影音中文字幕 | www国产com | 国产精品精华液网站 | 91插插插插插插插 | 毛片毛片毛片毛片 | 日本一级片在线播放 | 国产不雅视频 | 午夜亚洲精品 | 特黄一级大片 | 亚洲精品久久久久久久久久 | 亚洲性xx| 秋霞影院一区二区 | 奇米影视777第四色 2019中文字幕在线免费观看 | 精品人妻伦一二三区久久 | 美女久久视频 | 99精品偷自拍 | 91最新入口 | 欧美成人午夜77777 | 亚洲成人av免费 | 免费人成在线观看 | 久久人人做 | 国产综合一区二区 | 日韩欧美在线不卡 | 成年女人毛片 | av中文在线天堂 | 成人在线免费电影 | 日韩福利在线视频 | 精品夜夜澡人妻无码av | 永久视频在线 | 日产精品久久久 | 夜色视频网 | 日韩av在线第一页 | 888奇米影视| 亚洲综合天堂 | 国产精品人妻 | 国产 欧美 自拍 | 激情无码人妻又粗又大 | 男女搞黄网站 | 婷婷午夜天 | 激情六月综合 | 欧美变态另类刺激 | 男人舔女人下部高潮全视频 | 宅男视频污 |