概念
流的本質是數據傳輸,根據數據傳輸的特性將流抽象為各種類,方便直接操作。可以類比水流(流就是一個管道里面有流水,這個管道連接了文件和程序)。
分類
根據處理數據類型的不同可以分為:字節(jié)流和字符流
根據數據流向不同可分為:輸入流和輸出流
由上圖可知
java字節(jié)流
InputStream是所有字節(jié)輸入流的祖先,而OutputStream是所有字節(jié)輸出流的祖先。
java字符流
Reader是所有讀取字符串輸入流的祖先,而writer是所有輸出字符串的祖先。
上面的幾個類都是抽象類
Java字節(jié)流
一、FileInputStream和FileOutputStream
第一個類的源端和第二個類的目的端。它們的構造方法允許通過文件的路徑名來構造相應的流。
FileInputStream fis = new FileInputStream("讀取文件的路徑");
注:讀取文件的路徑必須是存在并且可讀的。
FileOutputStream fos = new FileOutputStream("寫入文件的路徑");
注:如輸出文件已存在,則必須是可覆蓋的(如果不想覆蓋則可以后面加一個boolean參數為true)。
FileInputStream使用:
? ? ? 使用read()從此輸入流中讀取一個數據字節(jié)。FileInputStream fis = new FileInputStream("aa.txt");
int b;
while((b = fis.read())!=-1){? ? ? ? //如果已到達文件末尾,則返回 -1。我們可以用-1來判斷是否是最后一個字節(jié)
? ? ? ? System.out.println(b);
}
fis.close();????????????????????????????????? //關流釋放資源一定要關閉資源
FileOutputStream使用:
? 使用write()寫入
FileOutputStream fos = new FileOutputStream("yy.txt");
fos.write("你好啊...".getBytes()); //轉化為字節(jié)數組
fos.close();? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //關流釋放資源一定要關閉資源
拷貝
第一種:一個一個字節(jié)的拷貝效率太慢
FileInputStream fil = new FileInputStream("/Users/Ms.chang/Desktop/IMG_1328.jpg");
第二種:定義一個字節(jié)數組來拷貝(如果是幾M還可也考慮使用,但是如果是一個幾G的電影我們就不可能使用他了)
FileOutputStream fos = new FileOutputStream("/Users/Ms.chang/Desktop/JavaFiel/1.jpg");
int b;
while((b = fil.read())!=-1){
????? fos.write(b);
}
fos.close();
fil.close();
FileInputStream fis = new FileInputStream("/Users/Ms.chang/Desktop/a.mp3");
FileOutputStream fos = new FileOutputStream("/Users/Ms.chang/Desktop/JavaFiel/appe.mp3");
byte [] arr = new byte[fis.available()];//創(chuàng)建跟文件大小一樣的字節(jié)數組
fis.read(arr);//文件上的字節(jié)讀取到內存中
fos.write(arr);//將字節(jié)中字節(jié)數據寫到文件上;
fis.close();
fos.close();
第三種:定義一個小數組
FileInputStream fis = new FileInputStream("/Users/Ms.chang/Desktop/JavaFiel");
FileOutputStream fos = new FileOutputStream("yy.txt");
byte [] arr = new byte[1024 * 8];
int b;
while((b=fis.read(arr))!=-1){? ? //如果忘記加arr返回的就不是讀取的字節(jié)個數,而是字節(jié)的碼表值
fos.write(arr,0,b);
}
fis.close();
fos.close();
二、BufferedInputStream和BufferedOutputStream
它們是過濾器流,其作用是提高輸入輸出的效率。自帶字節(jié)數組。
拷貝
//創(chuàng)建輸入流對象
FileInputStream fis = new FileInputStream("/Users/Ms.chang/Desktop/a.mp3");
//創(chuàng)建輸出流對象
FileOutputStream fos = new FileOutputStream("/Users/Ms.chang/Desktop/JavaFiel/aa.mp3");
//創(chuàng)建緩沖流對象.BufferedInputStream初始化需要放入InputStream類或者他的子類;
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream 需要放入OutputStream類或者子類
BufferedOutputStream bos = new BufferedOutputStream(fos);
int b;
while((b=bis.read())!=-1){
bos.write(b);
}
bis.close();
bos.close();
注:關閉流資源的時候只需要關閉緩沖流對象就可以了
java字符流
一、FileReader和FileWriter
以字符為單位讀取文件,常用于讀文本,數字等類型的文件
FileReader使用
FileReader fr = new FileReader("/Users/Ms.chang/Desktop/JavaFiel/b.txt");
int c;
while((c=fr.read())!=-1){ //通過項目默認的碼表一次讀取一個字符
System.out.print((char)c);
}
fr.close();
FileWriter使用
FileWriter fw = new FileWriter("/Users/Ms.chang/Desktop/JavaFiel/b.txt",true);
fw.write("大家好");
fw.close();
二、BufferedReader和BufferedWriter
BufferedReader br = new BufferedReader(new FileReader("/Users/Ms.chang/Desktop/JavaFiel/b.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("/Users/Ms.chang/Desktop/JavaFiel/tt.txt"));
String line;
while((line = br.readLine())!=null){//readLine()的方法可以獲取到一行的文字
bw.write(line);
bw.newLine();//寫出回車換行符
}
br.close();
bw.close();
三、LineNumberReader
使用這個類可以獲取行號或者添加行號
LineNumberReader lnr = new LineNumberReader(new FileReader("/Users/Ms.chang/Desktop/JavaFiel/b.txt"));
String line;
lnr.setLineNumber(100);//設置行號
while((line = lnr.readLine())!=null){
System.out.println(lnr.getLineNumber() + line);//getLineNumber()獲取行號
}
java的序列化和反序列化
一、什么是序列化和反序列化
把對象轉換為字節(jié)序列的過程稱為對象的序列化。
把字節(jié)序列恢復為對象的過程稱為對象的反序列化。
二、序列化和反序列化的用途
把對象的字節(jié)序列永久地保存到硬盤上,通常存放在一個文件中;
三、怎么實現
public class Person implements Serializable{? 這個類需要實例化必須要實現implements Serializable接口
private String name;
private int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Person() {
super();
}
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
public class Ob {public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
//實例化Person對象
Person p1 = new Person("111",11);
Person p2 = new Person("fsd", 12);
Person p3 = new Person("1s",114);
Person p4 = new Person("fasdfvad", 122);
//創(chuàng)建Person列表
Listlist<Person> = new ArrayList<>();
//給列表添加元素
list.add(p1);
list.add(p2);
list.add(p3);
list.add(p4);
//使用ObjectOutputStream類來進行序列化? 初始化參數需要放入OutputStream類或者子類
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/Users/Ms.chang/Desktop/JavaFiel/aaa.txt"));
//把列表序列化
oos.writeObject(list);
oos.close();//關閉流資源
//使用ObjectInputStream類來反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("/Users/Ms.chang/Desktop/JavaFiel/aaa.txt"));
ArrayListlist1 =(ArrayList) ois.readObject();//readObject()來反序列化
//從數字中遍歷出Person對象打印
for (Person person : list1) {
System.out.println(person);
}
ois.close();//關閉流資源
}