Java---IO加強(1)
RandomAccessFile
★隨機訪問文件,自身具備讀寫的方法。
new RandomAccessFile()之后,若文件不存在會自動創建,存在則不創建。——該類其實內部既封裝了字節輸入流,又封裝了字節輸出流。
該類若用write()方法寫整數,每次只寫它的最后一個字節。而采用writeInt()方法,則可把一個整數完整地寫入。
★通過skipBytes(int x),seek(int x)來達到隨機訪問。
通過seek方法設置數據的指針就可以實現對文件數據的隨機讀寫。InputStream中的skip()方法只能從頭往后跳,不能反向;而seek()方法可雙向隨便定位。
★數據修改方面的特點
用RandomAccessFile類可以實現數據的修改,當然文件中的數據一般要有規律,以方便在編程時能夠進行定位,讓數據寫對地方。
而用“流”實現數據修改時,則通常需要把數據從流讀到數組當中,在數組中進行數據修改,然后再把修改后的數組再重新寫到流中。
序列化
★ 序列化介紹
將一個對象存放到某種類型的永久存儲器上稱為保持。如果一個對象可以被存放到磁盤或磁帶上,或者可以發送到另外一臺機器并存放到存儲器或磁盤上,那么這個對象就被稱為可保持的。(在Java中,序列化、持久化、串行化是一個概念。)
java.io.Serializable接口沒有任何方法,它只作為一個“標記者”,用來表明實現了這個接口的類可以考慮串行化。類中沒有實現Serializable的對象不能保存或恢復它們的狀態。
(用IO流將數據讀入文件都叫序列化)
★ 對象圖
當一個對象被串行化時,只有對象的數據被保存;方法和構造函數不屬于串行化流。如果一個數據變量是一個對象,那么這個對象的數據成員也會被串行化。樹或者對象數據的結構,包括這些子對象,構成了對象圖。
★ 瞬時 transient
防止對象的屬性被序列化。
演示transient:
package io.sreializable; import java.io.Serializable; /** * 對象類 * @author 陳浩翔 * * 2016-4-22 */ public class Address implements Serializable{//實現可序列化接口 //靜態變量是不會被序列化的。對于非靜態變量,一般情況下都會被序列化,但如果聲明成transient型則不會。 private static String address;//靜態變量不屬于對象的! transient int num;//瞬時變量---該變量是不會被序列化的---不會出現在對象圖中的 private String Name;//姓名 private int age;//年齡 private String tel;//電話 public Address(int num, String name, int age, String tel) { this.num = num; Name = name; this.age = age; this.tel = tel; } public static String getAddress() { return address; } public static void setAddress(String address) { Address.address = address; } public int getNum() { return num; } public void setNum(int num) { this.num = num; } public String getName() { return Name; } public void setName(String name) { Name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getTel() { return tel; } public void setTel(String tel) { this.tel = tel; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((Name == null) ? 0 : Name.hashCode()); result = prime * result + age; result = prime * result + ((tel == null) ? 0 : tel.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Address other = (Address) obj; if (Name == null) { if (other.Name != null) return false; } else if (!Name.equals(other.Name)) return false; if (age != other.age) return false; if (tel == null) { if (other.tel != null) return false; } else if (!tel.equals(other.tel)) return false; return true; } @Override public String toString() { return "Address [num=" + num + ", Name=" + Name + ", age=" + age + ", tel=" + tel + "]"; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package io.sreializable; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; /** * * @author 陳浩翔 * * 2016-4-22 */ public class Serializable { //直接拋異常了。。。做項目千萬不要這樣 public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException { Address a1 = new Address(1, "aaa", 23, "12345678911"); Address a2 = new Address(2, "bbb", 24, "12345678912"); Address a3 = new Address(3, "ccc", 25, "12345678913"); Address a4 = new Address(4, "ddd", 26, "12345678914"); Address a5 = new Address(5, "eee", 27, "12345678915"); //對象序列化---輸出,寫 ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("hx.txt")); out.writeObject(a1); out.writeObject(a2); out.writeObject(a3); out.writeObject(a4); out.writeObject(a5); out.close(); //反序列化----讀 ObjectInputStream in = new ObjectInputStream(new FileInputStream("hx.txt")); System.out.println(in.readObject()); System.out.println(in.readObject()); System.out.println(in.readObject()); System.out.println(in.readObject()); System.out.println(in.readObject()); //如果對象讀完了,還讀文件,就會拋出EOF異常java.io.EOFException } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
運行圖片:
可以看到,瞬時變量的值并沒有被存儲起來,也就是沒有被序列化?。?/p>
緩沖輸入輸出流
介紹:
(BufferedInputStream和BufferedOutputStream)
第一種方式:
DataInputStream in = new DataInputStream( new BufferedInputStream( new FileInputStream("Test.txt"));
1
2
3
第二種方式:
DataInputStream in = new DataInputStream( new FileInputStream("Test.txt"));
1
2
第三種方式:
BufferedInputStream in = new BufferedInputStream( new DataInputStream( new FileInputStream("Test.java"));
1
2
3
下面我們來看實現它們運行速度的比較:
因為BufferedInputStream并沒有一次讀一行的方法,只能讀字節,
所以在文件中,我存儲的是一行占97個字節的字符串。
我讓它一次讀97個字節,所以和另外2種一次讀一行也就差不多了。。
這是存一行字符串的時候的文件大?。?/p>
后面的字符串,每行都和第一行的一樣大小!
文件一共112KB。
運行代碼:
package io.buffer; import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; /** * 測試3種方法 流 的讀取速度 * @author 陳浩翔 * * 2016-4-22 */ public class BufferedStreamDemo { //在這里,我們簡化了,直接拋異常了。 public static void main(String[] args) throws Exception { //test1(); //test2(); test3(); } /** * 先new緩沖流 * @throws Exception */ private static void test3() throws Exception { long time1 = System.currentTimeMillis(); BufferedInputStream in = new BufferedInputStream( new DataInputStream( new FileInputStream("chx.txt"))); byte b[] = new byte[97]; int n = 0; while((n=in.read(b))!=-1){ System.out.println(new String(b,0,n)); } long time2 = System.currentTimeMillis(); System.out.println((time2-time1)+"毫秒"); //測試程序運行時間需要多次運行取平均值的 } /** * 不用緩沖流 * @throws Exception */ private static void test2() throws Exception { long time1 = System.currentTimeMillis(); DataInputStream in = new DataInputStream( new FileInputStream("chx.txt")); String str = null; while((str=in.readLine())!=null){ System.out.println(str); } long time2 = System.currentTimeMillis(); System.out.println((time2-time1)+"毫秒"); //測試程序運行時間需要多次運行取平均值的 } /** * 在中間new緩沖流 * @throws Exception */ private static void test1() throws Exception { long time1 = System.currentTimeMillis(); DataInputStream in = new DataInputStream( new BufferedInputStream( new FileInputStream("chx.txt"))); String str = null; while((str=in.readLine())!=null){ System.out.println(str); } long time2 = System.currentTimeMillis(); System.out.println((time2-time1)+"毫秒"); //測試程序運行時間需要多次運行取平均值的 } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
運行結果:
我是取多次運行后,最接近平均值來截圖的!
第一種方式運行后的結果:
第二種方式運行后的結果:
第三種方式運行后的結果:
☆示例測試技術總結:
可以清楚的看到,第一種方式所用的時間是最短的!!??!
第二種方式最慢,和第一種方法相比,慢了8倍?。。?!
方案1是最優的
1)有buffer比沒有更快;
2)buffer放在中間層包裝比放在外層更快;
3)按行或按塊操作 比 按字節或字符操作更快(用Object流操作的速度 比 字節字符方式 更快)
4)緩沖區要結合流才可以使用,在流的基礎上對流的功能進行了增強。
Java 數據結構
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。