JAVA_IO流四大家族(1)
JAVA_IO四大家族體系:
JAVA_IO流四大家族(1)
JAVA_IO流四大家族(2)
文章目錄
- JAVA_IO四大家族體系:
- JAVA_IO流四大家族(1)
- JAVA_IO流四大家族(2)
- 常識介紹
- IO流,什么是IO?
- IO流的分類:
- JAVA中主要研究:
- 四個家族首領
- java.io包下需要掌握的流有16個:
- FileInputStream
- read方法
- read方法1代碼
- read方法1實現截圖
- read方法2代碼
- 改造后for循環
- read方法2實現截圖
- read方法3代碼
- IDEA默認的當前路徑是哪里?
- 毫無疑問,報錯
- 兩個解決辦法:
- 第一個 辦法
- 重點
- 第二個 辦法
- 操作過程(如何看長度)
- 第一次調用`read(bytes)`如下圖:
- 第二次調用`read(bytes)`如下圖:
- 第三次調用`read(bytes)`:
- 操作過程(如何看讀取出的數據)
- 操作過程注意點
- 總結實現代碼
- 改版后的while循環
- available方法
- 作用如下:
- 注意:
- skip方法
- 實現代碼
- FileOutputStream
- 實現代碼1(清空再寫入)
- 注意點
- 實現代碼2(以追加的方式)
- 注意點
- 實現截圖
- 如何寫入一個String字符串
常識介紹
IO流,什么是IO?
I:Input
O:Output
通過IO可以完成硬盤文件的讀寫
IO流的分類:
一種方式是按照流的方向進行分類:
以內存為參照物,
往內存中去,叫做輸入,或者叫做讀,
從內存中出來,叫做輸出,或者叫做寫
另一種方式是按照讀寫數據方式不同進行分類:
有的流是按照字節的方式讀取數據,一次讀取一個字節byte,等同于一次讀取8個二進制位,這種流是萬能的,什么類型的文件都能讀取。包括:文本文件,圖片,聲音文件,視頻
假設文件file.txt,采用字節流是這樣讀的:
a中國bc張三fe
第一次讀:一個字節,正好讀到’a‘,
第二次讀:一個字節,正好讀完‘中’字符的一半
第三次讀:一個字節,正好讀到‘中’字符的另外一半
有的流是按照字符的方式讀取數據的,一次讀取一個字符,這種流是為了方便讀取普通文本文件而存在的,這種流不能讀取:圖片,聲音,視頻等文件,只能讀取純文本文件,連word文件都沒法讀取。
假設文件file.txt,采用字符流是這樣讀的:
a中國bc張三fe
第一次讀:'a’字符('a’字符在windows系統中占有一個字節)
第二次讀:'中’字符('a’字符在windows系統中占有兩個字節)
綜上所述:流的分類
輸入流,輸出流
字節流,字符流
JAVA中主要研究:
怎么new流對象
調用流對象的哪個方法讀,哪個方法寫
四個家族首領
java.io.InputStream 字節輸入流
java.io.OutputStream 字節輸出流
java.io.Reader 字符輸入流
java.io.Writer 字符輸出流
四大家族首領都是抽象類(abstract class)
所有的流都實現了:java.io.Closeable接口,都是可關閉的,都有close()方法。
流畢竟是一個管道,這個是內存和硬盤之間的通道,用完之后一定要關閉,不然會耗費很多資源。養成好習慣,用完流一定要關閉
所有的輸出流都實現了:
java.io.Flushable接口,都是可刷新的,都有flush()方法;養成好習慣,輸出流在最終輸出之后,一定要記得flush()刷新一下,這個刷新表示將通道/管道當中剩余未輸出的數據強行輸出完(清空管道)刷新的作用就是清空管道
注意:如果沒有flush()可能會導致丟失數據;還有只有輸出流有flush(),輸入流并沒有
注意:在java中只要“類名”以Stream結尾的都是字節流,以“Reader/Writer”結尾的都是字符流
java.io包下需要掌握的流有16個:
文件專屬:
java.io.FileInputStream
java.io.FileOutputStream
java.io.FileReader
java.io.FileWriter
轉換流:(將字節流轉換為字符流)
java.io.InputStreamReader
java.io.OutputStreamWriter
緩沖流專屬:
java.io.BufferedReader
java.io.BufferedWriter
java.io.BufferedInputStream
java.io.BufferedOutputStream
數據流專屬:
java.io.DataInputStream
java.io.DataOutputSteam
標準輸出流:
java.io.PrintWriter
java.io.PrintStream
對象專屬流:
java.io.ObjectInputStream
java.io.ObjectOutputStream
FileInputStream
read方法
調用一次read方法,文件指針會往后移動一位,即如下圖
當執行到f下一個位置時,read返回值就為-1,那么這種read()讀取實現的話,就可以用循環來實現
read方法1代碼
/* * 1.文件字節輸出流,萬能的,任何類型的文件都可以采用這個流來讀 * 2.字節的方式,完成輸入的操作,完成讀的操作(硬盤--->內存) * */import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException;public class FileInputStreamTest01 {public static void main(String[] args) {//創建文件字節輸入流對象// 文件路徑:(IDEA會自動把\編程\\,因為java中\代表轉義)FileInputStream fis=null;try {fis=new FileInputStream("G:\\test.txt");//開始讀int readData =fis.read();//這個方法的返回值是:讀取到的“字節”本身System.out.print(readData+"\n");readData =fis.read();//這個方法的返回值是:讀取到的“字節”本身System.out.print(readData+"\n");readData =fis.read();//這個方法的返回值是:讀取到的“字節”本身System.out.print(readData+"\n");} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {//在finally語句塊中確保流一定關閉if(fis!=null){//避免空指針異常//關閉流的前提是:流不是空try {fis.close();} catch (IOException e) {e.printStackTrace();}}}} }read方法1實現截圖
read方法2代碼
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException;public class FileInputStreamTest02 {public static void main(String[] args) {FileInputStream fis=null;try {fis=new FileInputStream("G:\\test.txt");while(true){int readData=fis.read();if(readData==-1){break;}System.out.println(readData);}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if(fis!=null){try {fis.close();} catch (IOException e) {e.printStackTrace();}}}} }改造后for循環
int readData=0;while((readData=fis.read())!=-1){System.out.println(readData);}read方法2實現截圖
read方法3代碼
IDEA默認的當前路徑是哪里?
首先得搞懂這個問題,我們在src下面創建一個tempfile
然后執行以下代碼:
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException;public class FileInputStreamTest03 {/*** int read(byte[] b)* 一次最多讀取b.length個字節* 減少硬盤和內存的交互,提高程序的執行效率* 往byte數組當中讀* */public static void main(String[] args) {FileInputStream fis=null;try {//相對路徑的話呢?相對路徑一定是從當前所在的位置作為起點開始找//IDEA默認的當前路徑是哪里?工程project的根就是IDEA的默認當前路徑fis=new FileInputStream("tempfile");} catch (FileNotFoundException e) {e.printStackTrace();}finally {if(fis!=null){try {fis.close();} catch (IOException e) {e.printStackTrace();}}}} }毫無疑問,報錯
找不到指定文件,很簡單的原因,當前路徑想錯了
兩個解決辦法:
第一個 辦法
先找到文件所在path
重點
IDEA默認的當前路徑是哪里?工程project的根就是IDEA的默認當前路徑
把tempfile文件拷貝一份,放在工程project的根,也就是當前的上層目錄
拷貝完成,然后再次執行上述代碼
運行成功
第二個 辦法
把如下代碼
fis=new FileInputStream("tempfile");變成
fis=new FileInputStream("src//tempfile");
執行結果如下
操作過程(如何看長度)
開始讀,采用byte數組,一次讀取多個字節,最多讀取“數組.length”個字節
byte []bytes=new byte [4];//準備一個4個長度的數組,一次最多讀取4個字節第一次調用read(bytes)如下圖:
int readCount= fis.read(bytes);這個方法的返回值是:讀取到的字節數量(不是字節本身),數據已經放在了bytes數組中去
第二次調用read(bytes)如下圖:
這次讀取到了兩個字節
第三次調用read(bytes):
讀不到任何數據返回-1
readCount= fis.read(bytes);//第三次1個字節都沒有讀取到,返回-1 System.out.println(readCount);//-1操作過程(如何看讀取出的數據)
//這個方法的返回值是:讀取到的字節數量(不是字節本身)int readCount= fis.read(bytes);System.out.println(readCount);//第一次讀到了4個字節System.out.println(new String(bytes));readCount= fis.read(bytes);System.out.println(new String(bytes));// System.out.println(readCount);//第二次只能讀到2個字節第二次只讀取兩個字節,然后它把讀取到的5和6放在1和2位置處,但是原來數組中3和4還依然存在,這也就符合我們下圖所表示的
操作過程注意點
問題來了,我們應該是讀取了多少個,就寫多少個,(不應該全部轉換)而不是寫數組的全部進入String中,應該用如下形式
總結實現代碼
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException;public class FileInputStreamTest04 {public static void main(String[] args) {FileInputStream fis=null;try {fis=new FileInputStream("src//tempfile");//準備一個byte數組byte[]bytes=new byte[4];int readCount=0;while(true){readCount=fis.read(bytes);if(readCount==-1){break;}System.out.print(new String(bytes,0,readCount));}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if(fis!=null){try {fis.close();} catch (IOException e) {e.printStackTrace();}}}} }改版后的while循環
int readCount1=0;while((readCount1=fis.read(bytes))!=-1){System.out.print(new String(bytes,0,readCount1));}available方法
int available()返回流當中剩余的沒有讀到的字節數量
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException;public class FileInputStreamTest05 {public static void main(String[] args) {FileInputStream fis=null;try {fis=new FileInputStream("");System.out.println("總字節數量"+fis.available());//讀取1個字節int readByte=fis.read();//還剩下可以讀的字節數量是5;System.out.println("剩下多少字節沒有讀:"+fis.available()+"字節");} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if(fis!=null){try {fis.close();} catch (IOException e) {e.printStackTrace();}}}} }作用如下:
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException;public class FileInputStreamTest05 {public static void main(String[] args) {FileInputStream fis=null;try {fis=new FileInputStream("src//tempfile");System.out.println("總字節數量"+fis.available());//這個方法有什么用?byte []bytes=new byte[fis.available()];//這種方式不太適合太大的文件,因為byte數組不能太大//不需要循環了//直接讀一次就行了int readCount=fis.read(bytes);System.out.print(new String(bytes));//一次到位} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if(fis!=null){try {fis.close();} catch (IOException e) {e.printStackTrace();}}}} }注意:
這種方式不太適合太大的文件,因為byte數組不能太大
skip方法
跳過幾個字節不讀取
long skip (long n)實現代碼
public class FileInputStreamTest05 {public static void main(String[] args) {FileInputStream fis=null;try {fis=new FileInputStream("src//tempfile");fis.skip(3);System.out.print(fis.read());} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if(fis!=null){try {fis.close();} catch (IOException e) {e.printStackTrace();}}}} }
字符4的ASCII碼值是52
FileOutputStream
實現代碼1(清空再寫入)
import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException;public class FileOutputStreamTest01 {/** 文件字節輸出流,負責寫* 從內存到硬盤* */public static void main(String[] args) {FileOutputStream fos=null;try {fos=new FileOutputStream("myfile");//開始寫byte[]bytes={97,98,99,100};fos.write(bytes);fos.write(bytes,0,2);//再寫出ab//寫完之后,最后一定要刷新fos.flush();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if(fos!=null){try {fos.close();} catch (IOException e) {e.printStackTrace();}}}} }注意點
實現代碼2(以追加的方式)
注意點
實現截圖
執行前:
執行后:
如何寫入一個String字符串
import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException;public class FileOutputStreamTest01 {/** 文件字節輸出流,負責寫* 從內存到硬盤* */public static void main(String[] args) {FileOutputStream fos=null;try {//myfile文件不存在時會自動新建//這種方式謹慎使用,這種方式會將原文件清空,然后重新寫入fos=new FileOutputStream("myfile",true);String s="我是一個中國人,我自豪";byte[] bytes3=s.getBytes();fos.write(bytes3);//寫完之后,最后一定要刷新fos.flush();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if(fos!=null){try {fos.close();} catch (IOException e) {e.printStackTrace();}}}} }總結
以上是生活随笔為你收集整理的JAVA_IO流四大家族(1)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IO和属性配置文件之组合拳
- 下一篇: FileInputStream和File