外媒:多家矽谷巨頭反對英偉達收購 ARM,英特爾、高通等在列
什麼是IO流?
I :input
O :output
通過io就可以完成硬碟檔案的讀寫。
IO 流的分類?
-
一種方式是按照流的方向進行分類。
以記憶體作為參照物,
往記憶體中去,叫做輸入(input),或者叫做讀(Read)。
從記憶體中出來,叫做輸出(Output),或者叫做寫(Write)。
-
另一種方式是按照讀取資料的方式不同進行分類。
(1)按照位元組讀取資料
一次性讀取一個位元組 byte ,等同於一次性讀取8個二進位制。這種流是萬能的,什麼型別的檔案都能讀 取,包括:文字檔案、圖片、聲音檔案、視屏。
舉例; 檔案 filel.txt,採取位元組流的方式讀取。
a我愛bc中d國
第一次讀:一個位元組,到‘ a’
第二次讀:一個位元組,正好讀到 '我' 字元的一半
第三次讀:一個位元組,正好讀到 '我' 字元的另一半
(2)按照字元讀取資料
一次讀取一個字元,這種流是為了讀取普通文字檔案而存在的,不能讀取圖片、視訊、音樂等檔案。只能讀取純文字檔案,連word都不行。
舉例; 檔案 filel.txt,採取位元組流的方式讀取。
a我愛bc中d國
第一次讀:' a' 字元
第二次讀:'我'字元。
綜上所述,流的分類;
輸入流、輸出流
位元組流、字元流
java中的流都已經寫好了,java所有的流都在 java.io.* ;下
java IO 流四大家族
java.io.InputStream ; 位元組輸入流
java.io.OutputStream ; 位元組輸出流
java.io.Reader ; 字元輸入流
java.io.Writer ; 字元輸出流
都是抽象類 。
所有的流
java.io.Closeable
介面,都有close()
方法,都是可關閉的,流相當於記憶體和硬碟之間的管道用完後要及時關閉,否則會佔用很多資源。
所有的輸出流都實現了java.io.Flushable
介面,都是可重新整理的,都有flush()
方法表示將通道當中剩餘未輸出的資料強行輸出完(清空管道),輸出流在最終輸出之後一定要記得重新整理一下清空管道。(如果沒有flush()
可能會導致丟失資料)
注意:在 java 中只要類名以stream
結尾的都是位元組流;以 Reader/Writer 結尾的都是字元流。
java.io.* 中需要掌握的流
-
檔案專屬
java.io.FileInputStream(掌握)
java.io.FileOutputStream(掌握)
java.io.FileReader
java.io.FileWriter
-
轉換流(將位元組流轉換為字元流)
java.io.InputStreamReader
java.io.OutputStreamWriter
-
資料流專屬
java.io.DataInputStream
java.io.DataOutputStream
-
標準輸出流
java.io.PrintStream
java.io.PrintWriter(掌握)
-
物件專屬流
java.io.ObjectInputStream(掌握)
java.io.ObjectOutputStream(掌握)
位元組流讀取檔案
(一個一個的讀)
程式碼演示:
/*
java.io.FileInputStream
檔案位元組輸入流,萬能的。任何型別的檔案都可以用這個讀。
*/
public static void main(String[] args) {
FileInputStream q1 = null;
try {
q1 = new FileInputStream("test.txt"); //儲存內容是; a
int readDate = q1.read();
System.out.println(readDate);//97 ,輸出為ascii值
} catch (FileNotFoundException e) {
// FileNotFoundException 是 IOException 的子類。所以只寫catch IOException 也可以。
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
} finally {
//關閉流。前提是 流不為空。當流是null,沒有必要關閉,也是避免空指標異常。
if (q1 != null) {
try {
q1.close();
} catch (IOException e) {
e.printStackTrace();}}}}}
-
使用陣列讀
public static void main(String[] args) { FileInputStream fls = null; try { //idea 預設都當前路徑在哪裡? (預設讀檔案的檔案位置) fls = new FileInputStream("test.txt"); //檔案內容;abcdef //採用byte讀取位元組,一次讀取多個位元組,最多讀取 "陣列.length" 個字元 byte [] bytes = new byte[4]; //準別一個 4 長度的a陣列,一次最多讀取4字元 int readTxt = fls.read(bytes); //這個方法返回的是 讀取的位元組數量。 System.out.println(readTxt); //第一次讀到了四個位元組,輸出4 //System.out.println(new String(bytes)); //abcd 。別忘了引用包,java.lang.String; System.out.println(new String(bytes,0,readTxt)); //(idea此時不能自動引包). //表示從陣列bytes的第0個下標開始,讀取長度為readTxt的位元組陣列 readTxt = fls.read(bytes); //第二次只能讀取兩個位元組,輸出2, 後兩個位元組覆蓋前兩個陣列。 System.out.println(readTxt); //System.out.println(new String(bytes)); //efcd System.out.println(new String(bytes,0,readTxt)); //readTxt = fls.read(); //第三次一個位元組都沒有讀到,返回-1。 因為後面沒有資料了。 } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fls != null){ try { fls.close(); } catch (IOException e) { e.printStackTrace(); } }}}}
此時可以按照設定好的byte陣列長度進行讀取檔案, 一次讀取四個位元組。
-
如何讀取檔案中所有的字元?
public static void main(String[] args) { FileInputStream fls = null; try { fls = new FileInputStream("/Users/caoxingxing/Desktop/test.txt"); /*byte [] bytes = new byte[4]; while (true){ int readCount = fls.read(bytes); if (readCount == -1){ break; } System.out.print(new String(bytes,0,readCount)); //如果連續輸出字元,去ln。 }*/ byte [] bytes = new byte[4]; int readCount = 0; while ((readCount = fls.read(bytes)) != -1){ //改進後的while迴圈。 System.out.print(new String(bytes,0,readCount)); //一次讀取4個位元組,讀取長度為readCount的陣列 } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fls != null){ try { fls.close(); } catch (IOException e) { e.printStackTrace(); }}} }}
-
available ();方法
int read = fis.read(); System.out.println("剩餘" + fis.available() + "位元組"); //剩餘多少位元組
byte [] bytes = new byte[fis.available()]; //陣列長度為字元床總長度 int read = fis.read(bytes); System.out.println(new String(bytes)); //不適用太大的檔案,因為byte 有一定限制。
獲取陣列長度的位元組。=獲取全部位元組並輸出。
-
skip(); 跳過讀取。
//skip跳過幾個位元組不讀取。 public static void main(String[] args) { FileInputStream fls = null; try { fls = new FileInputStream("test.txt"); //檔案內容:abcd fls.skip(2); System.out.println(fls.read()); //輸出:cd } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { if (fls != null){ try { fls.close(); } catch (IOException e) { e.printStackTrace(); }}}}}
-
使用FileOutputStream寫入檔案
//檔案位元組輸出流,負責寫
//從記憶體到硬碟
public static void main(String[] args) {
FileOutputStream fos = null;
try {
//以追加的方式在檔案末尾寫入,不會晴空原始檔內容。檔案末尾加true
fos = new FileOutputStream("myfile",true); //檔案不存在時會自動重建,
// 後加“true”,每次寫入後,不格式化檔案。
//不加的話,每次寫入檔案後會清空檔案 重新寫入。
//例如;不加true,每一次程式執行,檔案都是顯示:123。
//加true後,程式執行兩次,檔案:123123
//開始寫
//byte [] bytes = {97,98,99,100};
//fos.write(bytes); //abcd
//fos.write(bytes,0,2); //在寫出ab,輸出:abcdab
//寫完之後記得重新整理一下,不然看不到新寫的資訊、
fos.flush();
String s = "123";
byte [] bytes2 = s.getBytes();
fos.write(bytes2);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//列印新增 "s" 後的檔案
FileInputStream fls = null;
try {
fls = new FileInputStream("myfile");
byte [] bytess = new byte[fls.available()];
int read = fls.read(bytess);
System.out.println(new String(bytess));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fls != null){
try {
fls.close();
} catch (IOException e) {
e.printStackTrace();
} } } }}
- 使用FileOutputStream 和 FileInputStream 拷貝檔案
public static void main(String[] args) {
FileInputStream fls = null;
FileOutputStream fos = null;
//使用位元組流可以拷貝 文字、視訊、音訊等。(目前只會拷貝單個檔案,資料夾還不行)
try {
fls = new FileInputStream("我自己的io作業01");
fos = new FileOutputStream("/Users/caoxingxing/Desktop/test.txt",true);
//若不加true,每一次拷貝檔案都會覆蓋原檔案內容。
byte [] bytes = new byte[4]; //一次四個位元組
int readCount = 0;
while ((readCount = fls.read(bytes)) != -1){
fos.write(bytes,0,readCount);
}
//寫入檔案記得重新整理。
fos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//連個close要分開處理異常(try、catch)。 不然可能會影響另一個流的關閉。
if (fos != null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
if (fls != null){
try {
fls.close();
} catch (IOException e) {
e.printStackTrace();
} }} }
FileReader
public static void main(String[] args) {
FileReader reader = null;
try {
reader = new FileReader("我自己的io作業01");
/*char [] chars = new char[4];
int readCount = 0;
while ((readCount = reader.read(chars)) != -1){
System.out.println(new String(chars,0,readCount));
}*/
//按字元的方式讀取
char [] chars = new char[4]; //一次讀取四個位元組,也可以增加。例如:1024*512。
reader.read(chars);
for (char c : chars){ //遍歷 chars,儲存到c中。
System.out.println(c);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null){
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
} }} }}
FileWriter檔案字元輸出流
//檔案字元輸出流,負責寫的
//只能輸出普通文字。world檔案不是普通文字。
public class FileWriterrr01 {
public static void main(String[] args) {
FileWriter fw = null;
try {
fw = new FileWriter("我自己的io作業01",true); //append :追加。
char [] chars = {'豆','雷','樓','姆','˜'};
fw.write(chars); //檔案增加chars的內容。
fw.write(chars,2,3); //寫入陣列下標為2-3的資料。
fw.write("