IO Stream 核心方法
InputStream類
read():int
read(byte[]) :int
read(byte[],int,int):int
OutputStream類
write(int):void //寫入int(32位 4個(gè)字節(jié))的低8位跷叉,其他24個(gè)字節(jié)將被忽略
write(byte[]):void
write(byte[],int,int):void
Reader類
read(Charbuffer):int
read():int
read(char[]):int
read(char[],int,int):int
Writer類
wirte(int):void //寫入一個(gè)character( int 32位,但是char 16位 ,2個(gè)字節(jié))的低16位涌韩,高16位將被忽略
wirte(char[]):void
wirte(char[],int ,int):void
write(String):void
write(String,int,int):void
FileInputStream
FileOutputStream
DataInputStream
DataOutputStream
DataXXX 是InputStream,OutputStream的包裝類呼巷,基于InputStream潦蝇,OutputStream提供了很多操作數(shù)據(jù)的方法癣疟,比如操作int,string等摸袁;
BufferedInputStream
BufferedOutputStream
字節(jié)流
1: 單一字節(jié)讀取 悼潭;
2:批量讀缺蛹伞(自定義數(shù)組大小)舰褪;
3:使用Buffered皆疹,BufferedInputStream中。原理是:先單字節(jié)讀取到buffer中占拍,在從buffer中轉(zhuǎn)移到目標(biāo)位置略就;
BufferedInputStream 中使用buffer減少訪問磁盤的次數(shù),達(dá)到提升性能晃酒;
其中批量讀取最高效表牢;
public synchronized int read() throws IOException {
if (pos >= count) {
fill();
if (pos >= count)
return -1;
}
return getBufIfOpen()[pos++] & 0xff;
}
/**
* Fills the buffer with more data, taking into account
* shuffling and other tricks for dealing with marks.
* Assumes that it is being called by a synchronized method.
* This method also assumes that all data has already been read in,
* hence pos > count.
*/
private void fill() throws IOException {
byte[] buffer = getBufIfOpen();
if (markpos < 0)
pos = 0; /* no mark: throw away the buffer */
else if (pos >= buffer.length) /* no room left in buffer */
if (markpos > 0) { /* can throw away early part of the buffer */
int sz = pos - markpos;
System.arraycopy(buffer, markpos, buffer, 0, sz);
pos = sz;
markpos = 0;
} else if (buffer.length >= marklimit) {
markpos = -1; /* buffer got too big, invalidate mark */
pos = 0; /* drop buffer contents */
} else if (buffer.length >= MAX_BUFFER_SIZE) {
throw new OutOfMemoryError("Required array size too large");
} else { /* grow buffer */
int nsz = (pos <= MAX_BUFFER_SIZE - pos) ?
pos * 2 : MAX_BUFFER_SIZE;
if (nsz > marklimit)
nsz = marklimit;
byte nbuf[] = new byte[nsz];
System.arraycopy(buffer, 0, nbuf, 0, pos);
if (!bufUpdater.compareAndSet(this, buffer, nbuf)) {
// Can't replace buf if there was an async close.
// Note: This would need to be changed if fill()
// is ever made accessible to multiple threads.
// But for now, the only way CAS can fail is via close.
// assert buf == null;
throw new IOException("Stream closed");
}
buffer = nbuf;
}
count = pos;
int n = getInIfOpen().read(buffer, pos, buffer.length - pos); // 這里是真正讀內(nèi)容的地方
if (n > 0)
count = n + pos;
}
字符流
1:編碼問題
2:文本,文本文件
文本:Java的文本(char)是16位無符號(hào)整數(shù)贝次,是字符的unicode編碼(雙字節(jié)編碼 2字節(jié) 16位)崔兴;
文件: byte byte byte ... 的數(shù)據(jù)序列
文本文件:文本文件是文本(char)按照某種編碼方案(utf-8,utf-16be,gbk)序列號(hào)為byte的存儲(chǔ)結(jié)果;
3:字符流(Reader,Writer)
字符的處理,一次處理一個(gè)字符
字符的底層基本的字節(jié)序列敲茄;
InputStreamReader / OutputStreamWriter
InputStreamReader OutputStreamWriter是字符流和字節(jié)流的橋梁位谋,提供需要解析編碼時(shí)的轉(zhuǎn)換;
InputStreamReader:實(shí)現(xiàn)輸入的字節(jié)流(byte)解析為字符流(char),按照編碼解析折汞; OutputStreamWriter:實(shí)現(xiàn)輸出的字符流(char)解析為字節(jié)流(byte),按照編碼解析倔幼;
FileReader / FileWriter
BufferedReader / BufferedWriter,PrinterWriter
序列化
1:對(duì)象序列化:是將Object 轉(zhuǎn)換為byte序列,反之叫對(duì)象的反序列化爽待;
2:序列化流 ObjectOutputStream,ObjectInputStream. 關(guān)鍵反復(fù)writerObject,readObject;
3:序列化需要實(shí)現(xiàn)序列化接口(Serializable)
序列化 - transient 關(guān)鍵字
加了transient 關(guān)鍵字 损同,那么該元素不會(huì)進(jìn)行jvm默認(rèn)的序列化;
ArrayList 中的 transient 序列化
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
* will be expanded to DEFAULT_CAPACITY when the first element is added.
*/
transient Object[] elementData; // non-private to simplify nested class access
}
ArrayList 中的 對(duì) 標(biāo)有transient關(guān)鍵字的元素進(jìn)行序列化
/**
* Save the state of the <tt>ArrayList</tt> instance to a stream (that
* is, serialize it).
*
* @serialData The length of the array backing the <tt>ArrayList</tt>
* instance is emitted (int), followed by all of its elements
* (each an <tt>Object</tt>) in the proper order.
*/
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{
// Write out element count, and any hidden stuff
int expectedModCount = modCount;
s.defaultWriteObject(); //1: 第一步使用默認(rèn)的序列化
// Write out size as capacity for behavioural compatibility with clone()
s.writeInt(size);
// Write out all elements in the proper order.
for (int i=0; i<size; i++) {
s.writeObject(elementData[i]); //第二步 只序列化有用的元素
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
/**
* Reconstitute the <tt>ArrayList</tt> instance from a stream (that is,
* deserialize it).
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
elementData = EMPTY_ELEMENTDATA;
// Read in size, and any hidden stuff
s.defaultReadObject(); //1: 第一步 使用默認(rèn)的序列化
// Read in capacity
s.readInt(); // ignored
if (size > 0) {
// be like clone(), allocate array based upon size not capacity
ensureCapacityInternal(size);
Object[] a = elementData;
// Read in all elements in the proper order.
for (int i=0; i<size; i++) {
a[i] = s.readObject(); //2:第二部 只序列化有用的元素
}
}
}
序列化父子類
1:父類實(shí)現(xiàn)了序列化接口鸟款,子類也能實(shí)現(xiàn)序列化膏燃;
2:子類需要實(shí)現(xiàn)序列化,只需要子類實(shí)現(xiàn)序列化接口何什,父類不一定要實(shí)現(xiàn)序列化接口
3:對(duì)子類對(duì)象進(jìn)行反序列化操作時(shí)组哩,如果父類沒有實(shí)現(xiàn)序列化接口,那么其父類的構(gòu)造函數(shù)會(huì)被顯示的調(diào)用处渣;如果父類實(shí)現(xiàn)了序列化接口伶贰,反序列化可以直接讀取到構(gòu)造中的內(nèi)容,無需顯示調(diào)用罐栈;