FileInputStream-FileOutputStream:
1.構造方法:
new ( "文件的 絕對路徑/相對路徑" ) ;
//注意構造方法的參數是字符串類型
//絕對路徑為帶磁盤目錄的,如:C:\java-prictice\javaseplus\text
//相對路徑:(IDEA默認當前路徑:當前模塊的根)+相對路徑
//通過“電腦”復制文件位置的時候,要在上邊的那個路徑的后面+ “\具體文件名”,否則此路徑只是代表你看到界面的上一個目錄;
//把路徑粘貼到構造方法里的時候,IDEA工具會自動把“ \ ”轉換為“ \\ ”,實際上,把“ \\ ”改為“ / ”也是正確的;
FileInputStream 引用文件,代表將此文件作為讀的對象;
FileOutputStream 引用文件,代表將此文件作為寫的對象(輸出在此文件中),若此文件不存在,則會自動創建;
2.常用方法:
1)FileInputStream . read ( bytes數組 ) //讀取流的字節,並將讀取的字節放到byte數組里,返回讀取字節個數(int)[ 若讀到文件末尾,則返回-1 ]
2)FileInputStream . available ( int ) //返回流當前未讀取的字節個數
3)FileInputStream . skip ( int ) //跳過幾個字節不讀
3.注意:
1)為方便 finally語句中對流的關閉,所以一般在try外邊聲明空指針引用,在try里邊new流對象;
2)聲明的byte數組長度不宜過長,因為內存中很難找到一條特別長的連續空間;
3)每個流不能一起(並列)關閉,避免出現異常導致有些流無法關閉;
4.拷貝文件:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
//File字節流拷貝
public class FileInputStreamTest {
public static void main(String[] args) {
//聲明 FileInputStream 引用為空
FileInputStream fis=null;
//聲明 FileOutputStream 引用為空
FileOutputStream fos=null;
//拷貝的重要操作(拋出異常的部分)放到try-catch里
try {
//創建文件字節輸入流
fis=new FileInputStream("C:\\java-prictice\\javaseplus\\pra\\debug.txt");
//創建文件字節輸出流
fos=new FileOutputStream("C:\\java-prictice\\javaseplus\\pra\\debugFISCopy.txt",true);
//創建長度為100的數組bytes,元素類型為byte(字節)
byte [] bytes=new byte[100];
//聲明“讀取字節個數”的變量
int readCount;
//讀取fis的“bytes.length”個字節,同時判斷是否退出循環
//循環退出條件:讀取字節個數為 -1
while ((readCount=fis.read(bytes))!=-1){
//將此時bytes里裝的字節寫入fos對象里
fos.write(bytes,0,readCount);
}
//刷新輸出流
fos.flush();
} catch (FileNotFoundException e) {//用IDEA工具生成
e.printStackTrace();
} catch (IOException e) {//用IDEA工具生成
e.printStackTrace();
} finally {//fis與fos分開關閉,避免彼此的影響
if (fis!=null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos!=null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
FileReader-FileWriter:
1.構造方法:
FileReader 構造方法參考 《FileInputStream-FileOutputStream》
FileWriter 構造方法:
//此流的writer方法,會將寫的字符覆蓋整個文本(原文件中的字符會被刪除,然后錄入寫的字符)
FileWriter fileWriter1=new FileWriter("C:\\Program Files\\Git\\bin");
//此流的writer方法,會將寫的字符添加到文本后面(原文件中的字符不變)
FileWriter fileWriter2=new FileWriter("C:\\Program Files\\Git\\bin",true);
2.常用方法:
參照 《FileInputStream-FileOutputStream》與下面的《拷貝文件》;
3.注意:
字節流拷貝文件時,數組聲明為byte類型,那用字符流時,自然就聲明為char類型;
字符流綁定的文件格式只能是“ . txt ” 格式;
4.拷貝文件:
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
//File字符流拷貝
public class FileWriteTest {
public static void main(String[] args) {
FileReader in=null;
FileWriter out=null;
try {
in=new FileReader("C:\\java-prictice\\javaseplus\\pra\\debug.txt");
out=new FileWriter("C:\\java-prictice\\javaseplus\\pra\\debugFWCopy.txt",true);
char [] chars=new char[3];
int readCount;
while ((readCount=in.read(chars))!=-1){
out.write(chars,0,readCount);
}
out.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (in!=null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (out!=null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
BufferedReader-BufferedWriter:
1.BufferedReader,BufferedWriter,都是自帶緩沖的流,換句話說,不需要提供數組,也可以拷貝文本;
2.構造方法:
BufferedReader 參數:字符輸入流(FileRead)
BufferedWriter 參數:字符輸出流(FileWriter)
InputStreamReader 參數:字節輸入流(FileInputStream)//將字節輸入流轉換為字符輸出流
OutputStreamWriter 參數:字節輸出流(FileOutputStream)//將字節輸出流轉換為字符輸出流
綜上,可以這么寫:
BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream("C:\\java-prictice\\javaseplus\\pra\\debug.txt")));
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("C:\\java-prictice\\javaseplus\\pra\\debugBRCopy.txt",true)));
3.常用方法:
BufferedReader . readLine ( ) //讀取流當前行
BufferedWriter . write ( ) //寫入流當前行
4.拷貝文件代碼:
import java.io.*;
//Buffered字符流拷貝
public class BufferedReadTest {
public static void main(String[] args) {
BufferedReader br=null;
BufferedWriter bw=null;
try {
br=new BufferedReader(new InputStreamReader(new FileInputStream("C:\\java-prictice\\javaseplus\\pra\\debug.txt")));
bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("C:\\java-prictice\\javaseplus\\pra\\debugBRCopy.txt",true)));
String read;
while ((read=br.readLine())!=null){
bw.write(read);
//讓文本一行一行的寫出來
bw.write("\n");
}
bw.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (br!=null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bw!=null){
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
DataOutputStream-DataInputStream:
1.DataOutputStream,DataInputStream 都是數據專屬流,這個流可以將數據連同數據的類型一並寫入文件;
2.注意:
DataOutputStream 寫的文件,只能用 DataInputStream 去讀,並且讀的時候,讀的順序必須和寫的順序一樣,才可以正常取出數據;
專屬流讀和寫的文件都不是普通文檔(用記事本看不到正常信息);
3.“讀寫”訓練:
import java.io.*;
public class DataOutputStreamTest {
public static void main(String[] args) {
DataOutputStream dos=null;
DataInputStream dis=null;
try {
dos=new DataOutputStream(new FileOutputStream("C:\\java-prictice\\javaseplus\\pra\\DOS.txt",true));
dis=new DataInputStream(new FileInputStream("C:\\java-prictice\\javaseplus\\pra\\DOS.txt"));
byte b=100;
short s=200;
int i=300;
long l=400l;
float f=500.0f;
double d=600.0;
boolean sex=true;
char c='c';
dos.writeByte(b);
dos.writeShort(s);
dos.writeInt(i);
dos.writeLong(l);
dos.writeFloat(f);
dos.writeDouble(d);
dos.writeBoolean(sex);
dos.writeChar(c);
dos.flush();
System.out.println(dis.readByte());
System.out.println(dis.readShort());
System.out.println(dis.readInt());
System.out.println(dis.readLong());
System.out.println(dis.readFloat());
System.out.println(dis.readDouble());
System.out.println(dis.readBoolean());
System.out.println(dis.readChar());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (dis!=null){
try {
dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (dos!=null){
try {
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
點擊查看輸出結果
100
200
300
400
500.0
600.0
true
c
Process finished with exit code 0
PrintStream:
1.PrintStream 屬於標准字節輸出流,默認輸出到控制台上;
2.舉個栗子:
import java.io.PrintStream;
public class pra{
public static void main(String[] args) {
PrintStream ps=System.out;
ps.println("輸出到控制台上");
}
}
運行結果:
------------------------
輸出到控制台上
Process finished with exit code 0
3.改變 PrintStream 的輸出方向:
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.Date;
public class PrintStreamTest {
public static void main(String[] args) {
//向日志中導入msg字符串
Logger.log("調用了 System 的 gc() ,建議啟動垃圾回收器");
Logger.log("調用了 UserSystem 的 book()");
Logger.log("用戶嘗試登錄,驗證失敗");
}
}
//日志類
class Logger {
public static void log(String msg) {//獲取字符串msg
//聲明空引用
PrintStream printStream=null;
try {
//printStream流 綁定此文件
printStream = new PrintStream(new FileOutputStream("C:\\java-prictice\\javaseplus\\pra\\log.txt",true));
//改變System.out的輸出方向(輸出的東西會進入printStream流)
System.setOut(printStream);
//獲取此時刻時間
Date nowTime =new Date();
//自定義時間格式
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
//將nowTime轉換為我們的自定義格式,然后將msg字符串拼接上,最后輸出
System.out.println(sdf.format(nowTime)+" : "+msg);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
4.注意:標准輸出流不需要手動 clsoe 流;
File 類:
1.概述:File 類與IO流四大家族無繼承關系,所以File類不能完成文件的讀與寫;
2.構造方法:new ( " 路徑 " ) ;
3.常用方法:
引用 . createNewFile ( ) //在指定位置創建一個空文件(成功就返回true,如果已存在就不創建,然后返回false)
引用 . mkdir ( ) // 在指定位置創建一個文件夾
引用 . mkdirs ( ) // 在指定位置創建一個多重文件夾
引用 . exists ( ) // 判斷文件或文件夾是否存在
引用 . isFile ( ) // 判斷是否是一個文件,返回 boolean
引用 . isDirectory ( ) // 判斷是否是一個目錄,返回 boolean
引用 . getAbsolutePath ( ) // 獲取文件的絕對路徑,與文件是否存在沒關系
引用 . getParent ( ) // 返回此文件路徑的父路徑(String),如果此路徑名沒有指定父目錄,則返回null
引用 . getName ( ) // 獲取文件或文件夾的名稱,不包含上級路徑
引用 . length ( ) // 返回此文件大小(字節)
引用 . lastModified ( ) // 獲取文件最后一次被修改的時間
引用 . listFiles ( ) // 返回當前目錄下的所有子文件(返回值類型為 FIle數組)
序列化 / 反序列化:
1.概述:
2.自定義的類需要實現 Serializable 接口,才支持序列化和反序列化;
3.序列化版本號:
實現了 Serializable 接口的類,系統會為其自動生成一個序列化版本號,但是最好咱們手動生成版本號,舉個栗子:
import java.io.Serializable;
class Car implements Serializable{
private static final long serialVersionUID = 8342087006090942735L;
}
java虛擬機識別一個類,首先看類名,其次看序列化版本號;
4.被 transient 關鍵字修飾的屬性不參與序列化:
private transient String name;
ObjectInputStream-ObjectOutputStream:
此體系知識請參考《上邊的》
結合栗子理解:
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class ObjectInputStreamTest {
public static void main(String[] args) throws Exception{//將所有異常拋出
//ObjectOutputStream 綁定Cars文件(若無則新建)
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("Cars"));
//ObjectInputStream 綁定已存在的Cars文件
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("Cars"));
//創建專門裝Car的集合cars
List<Car> cars=new ArrayList<>();
//向cars集合中添加元素
cars.add(new Car(1,"大眾"));
cars.add(new Car(2,"法拉利"));
cars.add(new Car(3,"豐田"));
//將集合cars寫入oos綁定文件中(反序列化)
oos.writeObject(cars);
//讀取ois綁定文件中的所有對象(序列化),並強轉為List<Car>類型,最后將所有對象裝到carsList集合中
List<Car> carsList= (List<Car>) ois.readObject();
//遍歷carsList集合
for (Car car:carsList) {
System.out.println(car);
}
oos.flush();
oos.close();
ois.close();
}
}
class Car implements Serializable{
private static final long serialVersionUID = -2630683108946058933L;
private int no;
private String brand;
public Car() {
}
public Car(int no, String model) {
this.no = no;
this.brand = model;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getModel() {
return brand;
}
public void setModel(String model) {
this.brand = model;
}
@Override
public String toString() {
return "Car{" +
"no=" + no +
", model='" + brand + '\'' +
'}';
}
}
控制台輸出結果:
---------------------------
Car{no=1, model='大眾'}
Car{no=2, model='法拉利'}
Car{no=3, model='豐田'}
Process finished with exit code 0
IO+Properties:
1.優點:
對於以后需要經常改變的數據,可以單獨寫到一個文件中,使用程序動態讀取;將來只需要修改這個文件的內容, java代碼不需要改動,不需要重新編譯,服務器也不需要重啟,就可以拿到動態的信息;類似這種機制的這種文件被稱為配置文件;
2.當配置文件中的內容格式為:
key1=value
key2=value
我們把這種配置文件叫做屬性配置文件;
3.注意:
java 規范中有要求:屬性配置文件建議以 “ . properties ”結尾;這種以 ”. properties “結尾的文件在java中被稱為:屬性配置文件;
Properties 是專門存放屬性配置文件內容的一個類;
4.栗子老師:
import java.io.FileReader;
import java.util.Properties;
public class IOProperties {
public static void main(String[] args) throws Exception{
//FileReader綁定文件
FileReader reader=new FileReader("C:\\java-prictice\\javaseplus\\pra\\IOPropertiesTest.txt");
Properties pro=new Properties();
//將FileReader綁定文件載入Pro集合
pro.load(reader);
//通過key獲取value
System.out.println(pro.getProperty("username"));
System.out.println(pro.getProperty("password"));
System.out.println(pro.getProperty("data"));
System.out.println(pro.getProperty("不存在的key,會輸出 null"));
}
}
運行結果:
-----------------------------
a01
123456a01
null
null
Process finished with exit code 0
隨筆:
節點流:本身作為包裝流的構造方法的參數;
包裝流:包裝流的構造方法的參數是節點流;