java输入、输出流的简单入门
? ? ? 程序在運行期間可能需要從外部的存儲媒介或其他程序中讀取所需要的數據,這就需要使用輸入流,輸入流的指向稱為它的源;另一方面,程序在處理數據后,可能需要將處理的結果寫入到永久的存儲媒介中或傳送給其他的應用程序,這就需要使用輸出流。
? ? ? ?通俗的解釋就是,以我當前程序為主,我要和其他的事物進行交流,所以我必須要搭一個通道(這個通道就是流),讓我和它可以交流,我獲取該事物的數據就叫輸入,我給予該事物數據就叫輸出。
那么輸入輸出有兩種形式,一是以字節的形式輸入輸出;二是以字符的形式輸入輸出。
java.io包提供大量的流類,所有輸入流都是抽象類InputStream(字節輸入流)或Reader(字符輸入流)的子類,而所有輸出流都是抽象類OutputStream(字節輸出流)或抽象類Writer(字符輸出流)的子類。
一、File類
構造方法:
File(String filename);//沒有路徑,即在當前目錄
File(String directoryPath,String filename);
File(File dir,String filename);
filename是文件名,directoryPath是文件路徑,dir是目錄
注:文件夾即目錄也是一種文件,知識沒有后綴名罷了
常用方法:
public boolean canRead():是否可讀
public boolean canWrite():是否可寫
public boolean exists():是否存在
public long length():獲取文件長度(單位字節)
public boolean isFile():是否是一個文件(而不是目錄)
public boolean isDirectory():是否是目錄
public boolean isHidden():是否隱藏
public long last Modified():獲取最后修改時間(從1970年至今的毫秒數)
public String getName():獲取文件名字
public String getAbsolutePath():獲取文件絕對路徑
public String getParent():獲取文件父目錄
注:當構造一個File實例時,它只是說明了它把“文件夾-文件”這個模式抽象成了一個java對象,也就是說我可以用這個對象來操作實際的文件了。但是有一點就是,它并不會檢測這個java對象實際對應的文件是否真實存在,所以需要判斷,如果不存在就需要創建。。。
創建目錄
File對象調用public boolean mkdir()創建一個目錄,如果創建成功,返回true,否則返回false(所以你的那個File對象的filename參數的字符串應該是沒有文件后綴的,才會創建出文件夾)
public boolean mkdirs()區別:這個如果父目錄不存在,幫忙創建;上面不加s,會顯示創建失敗。
列出目錄中的文件
如果File對象是一個目錄,那么該對象調用下列方法可列出該目錄下的文件和子目錄:
public String[] list(FilenameFiler obj):以字符串形式返回目錄下指定類型所有文件
public File[] listFiles(FilenameFiler obj):以File對象形式返回目錄下指定類型所有文件
其中,FilenameFiler是一個接口,在調用以上兩個方法之前,需要實現該接口中的方法:
public boolean accept(File dir,String name)
形如:String filename[] = file.list(filenamefiler);即可遍歷完成。通俗講,在實現接口里制定一個篩選規則,對當前文件目錄依次遍歷。先把文件的信息傳到accept方法中,讓accept方法進行判斷,如果滿足條件,即返回true,即會把文件信息存到數組中,返回false則不會存到數組中,這就完成了一次篩選。list()參數其實也可以省略。這里有使用此函數打印文件目錄的示例:https://blog.csdn.net/qq_36923376/article/details/89884797
創建文件
如果File對象所指的文件不存在,可調用public boolean createNewFile()方法創建。
刪除文件
調用public boolean delete()可以刪除當前文件
運行可執行文件
的 當要執行機器上可執行文件時,可使用java.lang包中的Runtime類。
Runtime ec = Runtime.getRuntime();//創建對象
ec.exec(String command);//即可打開本地機器上的可執行文件,command是文件的絕對路徑
二、字節輸入輸出流
輸入流
輸入流基本步驟:
- 設定輸入流的源
- 創建指向源的輸入流
- 讓輸入流讀取源中的數據
- 關閉輸入流
構造方法
- FileInputStream(String name);
- FileInputStream(File file);
創建時會拋出IO異常,比如你要讀的文件實際不存在,所以需要捕獲處理。
使用輸入流對象讀取字節
int read():讀取單個字節,返回0-255之間一個整數,如果未讀出字節就返回-1
int read(byte b[]):從源中讀取b.length個字節到b中,返回實際讀取的字節數目,如果未讀出字節就返回-1。
int read(byte b[],int off,int len):從源中讀取len個字節到b中,返回實際讀取的字節數目,如果未讀出字節就返回-1。從off位置開始存放讀取的數據。
注:FileInputStream順序讀取文件,只要不關閉流,每次調用read() 方法就順序讀取源中其余內容,直到源末尾或流被關閉。盡管程序結束時會自動關閉所有打開的流,但是當程序使用完流后,顯式的關閉任何打開的流仍是一個良好的習慣。
import java.io.File; import java.io.FileInputStream; import java.io.IOException;public class Main{public static void main(String args[]){int n=-1;byte a[] = new byte[100];String separator = File.separator;String localdisk ="E:";String filepath = localdisk+separator+"1017"+separator+"make"+separator;String filename = "aaa.txt";File file = new File(filepath,filename);try {FileInputStream in = new FileInputStream(file);while((n=in.read(a))!=-1) {//這個地方String s = new String(a,0,n);System.out.println(s);}in.close();} catch (IOException e) {e.printStackTrace();}}} //txt內容:你好123i45like哈哈78bananas90很高興輸出流
輸出流基本步驟:
- 給出輸出流的目的地
- 創建指向目的地的輸出流
- 讓輸出流把數據寫入到目的地
- 關閉輸出流
構造方法
- FileOutputStream(String name);
- FileOutputStream(File file);
創建時會拋出IO異常,需捕獲。
注:這里構造函數還可以有第二個參數,FileOutputStream(File file,boolean append);append如果為true,則會在目的地文件的末尾繼續寫入字節,如果為false或缺省,則會把目的地文件內容清空即刷新文件使得文件的長度為0,從頭開始寫。如果輸出流指向的文件不存在,Java就會創建該文件。
?
使用輸出流對象寫字節
void write(int n):輸出流調用該方法向目的地寫數據
void write(byte b[]):輸出流調用該方法向目的地寫入一個字節數組
void write(byte b[],int off,int len):給定字節數組中起始于偏移量off處取len個字節寫到目的地。
注:FileOutputStream順序地寫文件,只要不關閉流,每次調用write() 方法就順序地向目的地寫入內容,直到流被關閉。需要注意的是,在操作系統把程序所寫到輸出流上的那些字節保存到磁盤上之前,有時被存放在內存緩沖區中,通過調用close()方法,可以保證操作系統把流緩沖區的內容寫到它的目的地,即關閉輸出流可以把該流所用的緩沖區的內容沖洗掉。
public class Main{public static void main(String args[]){File file = new File("F:\\haha\\bbb","aaa.txt");try {FileOutputStream out = new FileOutputStream(file,false); //注意這里的第二個參數,上面有講解String a = "啥事啊";byte[] b = a.getBytes();System.out.println(file.getName()+":"+file.length()+"byte");out.write(b);System.out.println(file.getName()+":"+file.length()+"byte");} catch (IOException e) {e.printStackTrace();}}}三、字符輸入輸出流
前言:文件字節輸入、輸出流的read和write方法使用字節數組讀寫數據,即以字節為單位處理數據。因此字節流不能很好地操作Unicode字符,比如,一個漢字在文件中占用2個字節,如果使用字節流,讀取不當會出現“亂碼”現象。
輸入流
FileReader是Reader的間接子類,是InputStreamReader的直接子類。
構造方法:
- FileReader(String filename);
- FileReader(File filename);
?
讀取方法:
同樣使用read方法,和上述一致,只不過把字節數組換成字符數組,不再贅述。
輸出流
FileWriter是Writer的子類,是OutputStreamWriter的直接子類。
構造方法:
- FileWriter(String filename,boolean append);
- FileWriter(File filename,boolean append);
注:同樣,第二個參數和上面字節流一樣,可以省略。
寫入方法:
同樣使用write方法,和上述一致,只不過把字節數組換成字符數組,不再贅述。
import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException;public class Main{public static void main(String args[]){File file = new File("F:\\haha\\bbb","aaa.txt");try {int n= -1;FileReader in = new FileReader(file);FileWriter out = new FileWriter(file,true);char[] c = {'a','b','c','d','e','f','g'};System.out.println(file.getName()+":"+file.length()+"byte");out.write(c,0,c.length); //把c數組中的字符全部寫入out.flush(); //別忘了刷新System.out.println(file.getName()+":"+file.length()+"byte");while((n=in.read(c))!=-1) { //讀取文件,一次讀c.length長度,一次就讀完了,進入while輸出,第二次檢測是-1,說明讀完了,不進入循環System.out.println(c);}out.close();} catch (IOException e) {e.printStackTrace();}}}注:對于Writer流,write方法將數據首先寫入到緩沖區,每當緩沖區溢出時,緩沖區的內容被自動寫入到目的地,如果關閉流,緩沖區的內容會like被寫入到目的地。流調用flush()方法可以立刻沖洗當前緩沖區,即將當前緩沖區的內容寫入到目的地。
四、緩沖流
Java提供了更高級的流:BufferedReader流和BufferedWriter流,二者的源和目的地必須是字符輸入流和字符輸出流。
構造函數分別是:
BufferedReader(Reader in);
BufferedWriter(Writer out);
相比將與字符輸入輸出流的優點:
BufferedReader流能夠讀取文本行,方法是readLine(),如:String strline = inline.readLine()
BufferedWriter流可以向文件寫入一個回行符,方法是newLine();
解釋:可以把BufferedReader流和BufferedWriter流稱為上層流,它們的字符流參數稱為底層流,java采用緩存技術將上層流和底層流連接。
當BufferedWriter流調用flush()刷新緩存或調用close()方法關閉時,即使緩存沒有溢出,底層流也會立刻將緩存的內容寫入目的地。一般先關閉上層流再關閉底層流。在編寫代碼時只需關閉上層流,那么上層流的底層流將自動關閉。
五、InputStreamReader
? ? ? ? ? public class InputStreamReader extends Reader
? ? ? ? InputStreamReader是從字節流到字符流的橋接器:它讀取字節并使用特定的編碼格式轉換為字符。它使用的字符集可以通過名稱指定,也可以明確指定,或者可以接受平臺的默認字符集。
每次調用一個InputStreamReader的read()方法都可能導致從底層字節輸入流中讀取一個或多個字節。為了能夠有效地將字節轉換為字符,可以從基礎流中提取比滿足當前讀取操作所需的更多字節。
為了獲得最高效率,請考慮在BufferedReader中包裝InputStreamReader。例如:
BufferedReader in= new BufferedReader(new InputStreamReader(InputStream in,Charset cs));在下面的例子中,將使用URL類爬取百度首頁的源碼,網頁是utf-8編碼,所以爬過來的數據應用utf-8解碼
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL;public class Main1{public static void main(String args[]){try {URL url = new URL("http://www.baidu.com");InputStream in = url.openStream();BufferedReader buff = new BufferedReader(new InputStreamReader(in,"utf-8"));String n=null;while((n=buff.readLine())!=null) {System.out.println(n);}} catch (IOException e) {e.printStackTrace();}}}?
?
?
五、隨機流
能否建立一個流,通過這個流既能讀文件也能寫文件呢?即隨機流誕生!
RandomAccessFile類創建的流稱作隨機流,當準備對一個文件進行讀寫操作時,創建一個指向該文件的隨機流即可。
構造方法:
RandomAccessFile(String name, String mode);
RandomAccessFile(File file, String mode);
參數mode取r(只讀)或rw(可讀寫),決定創建流對文件的訪問權利。
注:RandomAccessFile流指向文件時,不刷新文件。
? ? ? ? RandomAccessFile類中有一個方法seek(long a)用來定位RandomAccessFile流的讀寫位置,其中參數a確定讀寫位置距離文件開頭的字節個數。另外流還可以調用getFilePointer()方法獲取流的當前讀寫位置。
RandomAccessFile類有好多讀寫的函數,可自行查閱api
? ? ?需要注意的是,RandomAccessFile流的readLine()方法在讀取含有非ASCII字符的文件時(比如漢字)會出現“亂碼”現象,因此,需要把readLine()讀取的字符用“iso-8859-1”編碼重新編碼存放到byte數組中,然后再用當前機器的默認編碼將該數組轉化為字符串,操作如下:
1.讀取
String str = in.readLine();
2.用“iso-8859-1”重新編碼
byte[] b = str,getBytes("iso-8859-1");
3.用當前機器的默認編碼將該數組轉化為字符串
String content = new String(b);
如果機器默認編碼是GB2312,等價于String content = new String(b,“GB2312”);
?
?
?
?
?
?
?
?
?
?
總結
以上是生活随笔為你收集整理的java输入、输出流的简单入门的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 华硕飞行堡垒atk驱动在哪_11月8日华
- 下一篇: Spark大数据-TMDB电影数据分析(