22.01_IO流(序列流)(了解)
序列流可以把多個字節(jié)輸入流整合成一個, 從序列流中讀取數(shù)據(jù)時, 將從被整合的第一個流開始讀, 讀完一個之后繼續(xù)讀第二個, 以此類推.
- 整合兩個:
SequenceInputStream
(InputStream
,InputStream
)
FileInputStream fis1 = new FileInputStream("a.txt");
FileInputStream fis2 = new FileInputStream("b.txt");
SequenceInputStream sis = new SequenceInputStream(fis1, fis2); //整合2個輸入流
FileOutputStream fos = new FileOutputStream("c.txt"); //輸出流
int a ;
while((a = sis.read()) != -1) {
fos.write(a);
}
sis.close(); //sis關(guān)閉的時候纳令,會將內(nèi)部的輸入流都關(guān)閉掉
fos.close();
22.02_IO流(序列流整合多個)(了解)
- 整合多個: SequenceInputStream(Enumeration)
Vector<FileInputStream> v = new Vector<>();
v.add(new FileInputStream("a.txt"));
v.add(new FileInputStream("b.txt"));
v.add(new FileInputStream("c.txt"));
// 利用枚舉,將多個輸入流整合成一個
SequenceInputStream sis = new SequenceInputStream(v.elements());
FileOutputStream fos = new FileOutputStream("d.txt");
int data ;
while( (data = sis.read()) != -1) {
fos.write(data);
}
sis.close();
fos.close();
22.03_IO流(內(nèi)存輸出流)(掌握)
該輸出流可以向內(nèi)存中寫數(shù)據(jù), 把內(nèi)存當作一個緩沖區(qū), 寫出之后可以一次性獲取出所有數(shù)據(jù)
- 2.使用方式
- 創(chuàng)建對象:
new ByteArrayOutputStream()
- 寫出數(shù)據(jù):
write(int)
,write(byte[])
- 獲取數(shù)據(jù):
toByteArray()
- 創(chuàng)建對象:
FileInputStream fis = new FileInputStream("a.txt");
ByteArrayOutputStream baos = new ByteArrayOutputStream(); //相當于在內(nèi)存中創(chuàng)建了可以增長的數(shù)組
int b ;
while( (b = fis.read()) != -1) {
baos.write(b); // 此時其實是寫數(shù)據(jù)到了內(nèi)存里面
}
byte[] arr = baos.toByteArray(); //將緩沖區(qū)的數(shù)組全部拿出來克胳, 并賦值給arr數(shù)組
System.out.println(new String(arr));
System.out.println(baos.toString()); //使用平臺默認碼表將緩沖區(qū)內(nèi)容轉(zhuǎn)為字符串
fis.close();
22.04_IO流(內(nèi)存輸出流之面試題)(掌握)
- 定義一個文件輸入流,調(diào)用
read(byte[] b)
方法,將a.txt文件中的內(nèi)容打印出來(byte數(shù)組大小限制為5)
FileInputStream fis = new FileInputStream("a.txt"); //創(chuàng)建字節(jié)輸入流,關(guān)聯(lián)a.txt
ByteArrayOutputStream baos = new ByteArrayOutputStream(); //創(chuàng)建內(nèi)存輸出流
byte[] arr = new byte[5]; //創(chuàng)建字節(jié)數(shù)組,大小為5
int len;
while((len = fis.read(arr)) != -1) { //將文件上的數(shù)據(jù)讀到字節(jié)數(shù)組中
baos.write(arr, 0, len); //將字節(jié)數(shù)組的數(shù)據(jù)寫到內(nèi)存緩沖區(qū)中
}
System.out.println(baos); //將內(nèi)存緩沖區(qū)的內(nèi)容轉(zhuǎn)換為字符串打印
fis.close();
22.05_對象操作流ObjecOutputStream(了解)
該流可以將一個對象寫出, 或者讀取一個對象到程序中. 也就是執(zhí)行了序列化和反序列化的操作.
- 寫出:
new ObjectOutputStream(OutputStream)
,writeObject()
//無論是字節(jié)輸出流,還是字符輸出流都不能直接寫出對象
Person p1 = new Person("我啊", 20);
Person p2 = new Person("你啊", 56);
// 這個其實也是裝飾模式
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt"));
oos.writeObject(p1);
oos.writeObject(p2);
oos.close();
22.06_對象操作流ObjectInputStream(了解)
- 讀取:
new ObjectInputStream(InputStream)
,readObject()
// 讀取對象(反序列化)
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt"));
Person p1 = (Person) ois.readObject(); //可能有ClassNotFoundException
Person p2 = (Person) ois.readObject(); //當讀取到文件末尾平绩,繼續(xù)讀取,會出現(xiàn)EOFException
System.out.println(p1);
System.out.println(p2);
ois.close();
22.07_對象操作流優(yōu)化(了解)
// 1.讀寫多個對象時毯欣,將對象添加到集合里馒过,寫出集合,就不用考試多少個對象問題
ArrayList<Person> list = new ArrayList<>();
list.add(new Person("我啊", 20));
list.add(new Person("你啊", 56));
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt"));
oos.writeObject(list);
oos.close();
// 2.讀取多個對象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt"));
@SuppressWarnings("unchecked")
ArrayList<Person> aList = (ArrayList<Person>) ois.readObject();
for (Person person : aList) { //泛型在運行期會被擦除,索引運行期相當于沒有泛型
System.out.println(person);
}
ois.close();
關(guān)于Java泛型的一點思考
其實學好酗钞、學扎實編程語言的基礎(chǔ)腹忽,十分重要,對日后編程有十分有幫助砚作。如果你掌握了編程語言的高級語法窘奏,基礎(chǔ)十分扎實(內(nèi)功深厚),那么你寫出的代碼葫录,將比其他人寫的代碼有水平很多着裹。
另外就是如果你又扎實深厚的基礎(chǔ),那么也能大大減少日后編程中犯低級錯誤米同。
ArrayList<Integer> l1 = new ArrayList<>();
l1.add(100);
ArrayList l2 = null;
l2 = l1; //泛型擦除 骇扇,證明Java泛型是偽泛型,JVM編譯時,并沒有核對泛型信息,繞過了類型檢查
從反射也能說明Java泛型图仓,只是編譯時有效该肴,運行后會去泛型化
l2.add("dftd");
//
System.out.println(l2.get(0).getClass());
System.out.println(l2.get(1).getClass());
System.out.println(l1.size());
Integer temp = l1.get(1); //泛型擦除盆繁,帶來的隱患,報錯
22.08_IO流(加上id號)(了解)
- 要寫出的對象必須實現(xiàn)
Serializable
接口才能被序列化 - 不用必須加id號
/**
* serialVersionUID 序列化版本號,為了序列化時,如果增加了屬性婿脸,或方法,反序列化之前的版本柄驻,能提示出問題所在狐树。
* 其實不加也行,因為加不加凿歼,在反序列老版本對象都會出現(xiàn)異常錯誤褪迟。
*/
private static final long serialVersionUID = 1L;
22.09_IO流(打印流的概述和特點)(掌握)
該流可以很方便的將對象的toString()
結(jié)果輸出, 并且自動加上換行, 而且可以使用自動刷出的模式
System.out就是一個PrintStream, 其默認向控制臺輸出信息
PrintStream ps = System.out;
ps.println("xxoo");
ps.println(97); // 底層將 數(shù)字97 轉(zhuǎn)為了字符串
ps.write(97); //打印∪吆蕖a
ps.close();
----------------------分割線--------------------
PrintWriter pw2 = new PrintWriter(new FileOutputStream("a.txt"), true);
pw2.println(97); // 自動刷出功能答憔,只針對 println() 方法
pw2.write(97); // 并不會寫到文件里
pw2.close(); // 因為流操作都會要close味赃,所以自定刷出其實沒有什么卵用
// PrintStream 和 PrintWriter分別打印的是字節(jié)流和字符流
// 二者只操作數(shù)據(jù)目的,不操作 數(shù)據(jù)源
22.10_標準輸入輸出流概述和輸出語句
-
System.in
是InputStream
, 標準輸入流, 默認可以從鍵盤輸入讀取字節(jié)數(shù)據(jù) -
System.out
是PrintStream
, 標準輸出流, 默認可以向Console中輸出字符和字節(jié)數(shù)據(jù) - 2.修改標準輸入輸出流(了解)
System.setIn(new FileInputStream("a.txt")); //改變標準輸入流
System.setOut(new PrintStream("b.txt")); //改變標準輸出流
InputStream is = System.in; //此時已經(jīng)指向文件了虐拓,而不是鍵盤了
PrintStream ps = System.out; //此時不再指向控制臺心俗,而是b.txt
int data ;
while( (data = is.read()) != -1) {
ps.write(data);
}
is.close(); // 因為關(guān)聯(lián)的文件,所以要關(guān)閉輸入流和輸出流
ps.close();
22.11_IO流(修改標準輸入輸出流拷貝圖片)(了解)
System.setIn(new FileInputStream("xxoo.jpg")); //改變標準輸入流
System.setOut(new PrintStream("copy.jpg")); //改變標準輸出流
InputStream is = System.in;
PrintStream ps = System.out;
byte[] data = new byte[1024 * 10];
int len;
while( (len = is.read(data)) != -1) {
ps.write(data, 0, len);
}
is.close();
ps.close();
22.11_IO流(兩種方式實現(xiàn)鍵盤錄入)(了解)
// 2種鍵盤錄入
// InputStreamReader轉(zhuǎn)換流
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = br.readLine();
br.close();
System.out.println(str);
Scanner sc = new Scanner(System.in); // 第二種鍵盤輸入
String str2 = sc.nextLine();
sc.close();
System.out.println(str2);
22.12_隨機訪問流概述和讀寫數(shù)據(jù))(了解)
-
RandomAccessFile
類不屬于流蓉驹,是Object
類的子類城榛。但它融合了InputStream
和OutputStream
的功能。 - 支持對隨機訪問文件的讀取和寫入态兴。
- 這個
seek()
跳字節(jié)讀取的功能狠持,可以用于多線程下載和上傳。
RandomAccessFile raf = new RandomAccessFile("a.txt", "rw");
raf.write(97); //寫入 a
int x = raf.read(); // 讀取 (發(fā)現(xiàn)讀取的不是97瞻润,說明指針移到了下一個字節(jié))
System.out.println(x);
raf.seek(10); //當當前指針遇到10的位置
raf.write(120);
raf.close();
22.13_IO流(數(shù)據(jù)輸入輸出流)(了解)
- DataInputStream, DataOutputStream可以按照基本數(shù)據(jù)類型大小讀寫數(shù)據(jù)
- 例如按Long大小寫出一個數(shù)字, 寫出時該數(shù)據(jù)占8字節(jié). 讀取的時候也可以按照Long類型讀取, 一次讀取8個字節(jié).
DataOutputStream dos = new DataOutputStream(new FileOutputStream("a.txt"));
dos.writeInt(997); //寫入真實的 997 喘垂,
dos.writeInt(998);
dos.close();
DataInputStream dis = new DataInputStream(new FileInputStream("a.txt"));
System.out.println(dis.readInt()); // 按照 int讀取一個值
System.out.println(dis.readInt());
dis.close();
// 因為write(int a) 雖然接收是int,但是實際是byte類型的轉(zhuǎn)換绍撞,實際寫入時正勒,不會超過byte的取值范圍
// 00000000 00000000 00000011 11100101 int類型的997
// 11100101 真實寫入的值, write寫入會去掉int的前24位,而11100101找不到對應(yīng)的碼表傻铣,就會是亂碼
// 00000000 00000000 00000000 11100101 讀取之后的int已經(jīng)是 229了
FileOutputStream fos = new FileOutputStream("a.txt");
fos.write(997); //結(jié)果發(fā)現(xiàn)寫入之后是亂碼的
fos.close();
22.14_Properties的概述和作為Map集合的使用(了解)
-
Properties
類表示了一個持久的屬性集章贞,本質(zhì)是一個雙列集合,因為鍵值都是字符串非洲,所以沒有泛型鸭限。 -
Properties
可保存在流中或從流中加載。 - 屬性列表中每個鍵及其對應(yīng)值都是一個字符串两踏。
Properties pp = new Properties();
pp.put("verson", "2.3.0");
System.out.println(pp);
22.15_Properties的特殊功能使用(了解)
-
Properties
的特殊功能
Properties pp = new Properties();
pp.setProperty("verson", "3.2.0"); //向里面添加鍵值對
pp.setProperty("type", "android");
// 遍歷 (強轉(zhuǎn)是因為泛型問題)
Enumeration<String> enu = (Enumeration<String>) pp.propertyNames();
while(enu.hasMoreElements()){
String key = enu.nextElement() ;
System.out.println( key + "-->" + pp.get(key)); // 根據(jù)key败京,獲取value
}
22.16_Properties的load()和store()功能(了解)
Properties pp = new Properties();
pp.load(new FileInputStream("config.list")); //將文件上的鍵值對讀取到集合中
System.out.println(pp);
// 修改配置
pp.setProperty("name", "Java EE");
// 寫入配置文件
pp.store(new FileOutputStream("config.list"), "我是描述信息,可以為null");
END缆瓣。
我是小侯爺喧枷。
在魔都艱苦奮斗,白天是上班族弓坞,晚上是知識服務(wù)工作者隧甚。
如果讀完覺得有收獲的話,記得關(guān)注和點贊哦渡冻。
非要打賞的話戚扳,我也是不會拒絕的。