DataInputStream
DataInputStream 是資料輸入流。它繼承於FilterInputStream。
DataInputStream 是用來裝飾其它輸入資料流,它“允許應用程式以與機器無關方式從底層輸入資料流中讀取基本 Java 資料類型”。應用程式可以使用DataOutputStream(資料輸出資料流)寫入由DataInputStream(資料輸入流)讀取的資料。
DataInputStream 函數列表:
DataInputStream(InputStream in)final int read(byte[] buffer, int offset, int length)final int read(byte[] buffer)final boolean readBoolean()final byte readByte()final char readChar()final double readDouble()final float readFloat()final void readFully(byte[] dst)final void readFully(byte[] dst, int offset, int byteCount)final int readInt()final String readLine()final long readLong()final short readShort()final static String readUTF(DataInput in)final String readUTF()final int readUnsignedByte()final int readUnsignedShort()final int skipBytes(int count)
範例程式碼:
關於DataInputStream中API的詳細用法:
import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.ByteArrayInputStream;import java.io.File;import java.io.InputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.FileNotFoundException;import java.lang.SecurityException;/** * DataInputStream 和 DataOutputStream測試程式 * * @author skywang */public class DataInputStreamTest { private static final int LEN = 5; public static void main(String[] args) { // 測試DataOutputStream,將資料寫入到輸出資料流中。 testDataOutputStream() ; // 測試DataInputStream,從上面的輸出資料流結果中讀取資料。 testDataInputStream() ; } /** * DataOutputStream的API測試函數 */ private static void testDataOutputStream() { try { File file = new File("file.txt"); DataOutputStream out = new DataOutputStream( new FileOutputStream(file)); out.writeBoolean(true); out.writeByte((byte)0x41); out.writeChar((char)0x4243); out.writeShort((short)0x4445); out.writeInt(0x12345678); out.writeLong(0x0FEDCBA987654321L); out.writeUTF("abcdefghijklmnopqrstuvwxyz嚴12"); out.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * DataInputStream的API測試函數 */ private static void testDataInputStream() { try { File file = new File("file.txt"); DataInputStream in = new DataInputStream( new FileInputStream(file)); System.out.printf("byteToHexString(0x8F):0x%s\n", byteToHexString((byte)0x8F)); System.out.printf("charToHexString(0x8FCF):0x%s\n", charToHexString((char)0x8FCF)); System.out.printf("readBoolean():%s\n", in.readBoolean()); System.out.printf("readByte():0x%s\n", byteToHexString(in.readByte())); System.out.printf("readChar():0x%s\n", charToHexString(in.readChar())); System.out.printf("readShort():0x%s\n", shortToHexString(in.readShort())); System.out.printf("readInt():0x%s\n", Integer.toHexString(in.readInt())); System.out.printf("readLong():0x%s\n", Long.toHexString(in.readLong())); System.out.printf("readUTF():%s\n", in.readUTF()); in.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } // 列印byte對應的16進位的字串 private static String byteToHexString(byte val) { return Integer.toHexString(val & 0xff); } // 列印char對應的16進位的字串 private static String charToHexString(char val) { return Integer.toHexString(val); } // 列印short對應的16進位的字串 private static String shortToHexString(short val) { return Integer.toHexString(val & 0xffff); }}
運行結果:
byteToHexString(0x8F):0x8fcharToHexString(0x8FCF):0x8fcfreadBoolean():truereadByte():0x41readChar():0x4243readShort():0x4445readInt():0x12345678readLong():0xfedcba987654321readUTF():abcdefghijklmnopqrstuvwxyz嚴12
結果說明:
(1) 查看file.txt文本。16進位的資料顯示如下:
001f 對應的int值是31。它表示的含義是後面的UTF-8資料的長度。字串“abcdefghijklmnopqrstuvwxyz嚴12”中字母“ab...xyz”的長度是26,“嚴”對應的UTF-8資料長度是3;“12”長度是2。總的長度=26+3+2=31。
(2) 返回byte對應的16進位的字串
源碼如下:
private static String byteToHexString(byte val) { return Integer.toHexString(val & 0xff);}
想想為什麼代碼是:
return Integer.toHexString(val & 0xff);
而不是
return Integer.toHexString(val);
我們先看看 byteToHexString((byte)0x8F); 在上面兩種情況下的輸出結果。
return Integer.toHexString(val & 0xff); 對應的輸出是“0xffffff8f”
return Integer.toHexString(val); 對應的輸出是“0x8f”
為什麼會這樣呢?
原因其實很簡單,就是“byte類型轉換成int類型”導致的問題。
byte類型的0x8F是一個負數,它對應的2進位是10001111;將一個負數的byte轉換成int類型時,執行的是有符號轉型(新增位都填充符號位的數字)。0x8F的符號位是1,因為將它轉換成int時,填充“1”;轉型後的結果(2進位)是11111111 11111111 11111111 10001111,對應的16進位為0xffffff8f。
因為當我們執行Integer.toHexString(val);時,返回的就是0xffffff8f。
在Integer.toHexString(val & 0xff)中,相當於0xffffff8f & 0xff,得到的結果是0x8f。
(3) 返回char和short對應的16進位的字串
“返回char對應的16進位的字串”對應的源碼如下:
private static String charToHexString(char val) { return Integer.toHexString(val);}
“返回short對應的16進位的字串”對應源碼如下:
private static String shortToHexString(short val) { return Integer.toHexString(val & 0xffff);}
比較上面的兩個函數,為什麼一個是 “val” ,而另一個是 “val & 0xffff”?
通過(2)的分析,我們類似的推出為什麼 “返回short對應的16進位的字串” 要執行“val & 0xffff”。
但是,為什麼 “返回char對應的16進位的字串” 要執行 “val” 即可。原因也很簡單,java中char是無符號類型,佔兩個位元組。將char轉換為int類型,執行的是無符號轉型,新增為都填充0。
DataOutputStream
DataOutputStream 是資料輸出資料流。它繼承於FilterOutputStream。
DataOutputStream 是用來裝飾其它輸出資料流,將DataOutputStream和DataInputStream輸入資料流配合使用,“允許應用程式以與機器無關方式從底層輸入資料流中讀寫基本 Java 資料類型”。
範例程式碼
關於DataOutStream中API的詳細用法:
import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.ByteArrayInputStream;import java.io.File;import java.io.InputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.FileNotFoundException;import java.lang.SecurityException;/** * DataInputStream 和 DataOutputStream測試程式 * * @author skywang */public class DataInputStreamTest { private static final int LEN = 5; public static void main(String[] args) { // 測試DataOutputStream,將資料寫入到輸出資料流中。 testDataOutputStream() ; // 測試DataInputStream,從上面的輸出資料流結果中讀取資料。 testDataInputStream() ; } /** * DataOutputStream的API測試函數 */ private static void testDataOutputStream() { try { File file = new File("file.txt"); DataOutputStream out = new DataOutputStream( new FileOutputStream(file)); out.writeBoolean(true); out.writeByte((byte)0x41); out.writeChar((char)0x4243); out.writeShort((short)0x4445); out.writeInt(0x12345678); out.writeLong(0x0FEDCBA987654321L); out.writeUTF("abcdefghijklmnopqrstuvwxyz嚴12"); out.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * DataInputStream的API測試函數 */ private static void testDataInputStream() { try { File file = new File("file.txt"); DataInputStream in = new DataInputStream( new FileInputStream(file)); System.out.printf("byteToHexString(0x8F):0x%s\n", byteToHexString((byte)0x8F)); System.out.printf("charToHexString(0x8FCF):0x%s\n", charToHexString((char)0x8FCF)); System.out.printf("readBoolean():%s\n", in.readBoolean()); System.out.printf("readByte():0x%s\n", byteToHexString(in.readByte())); System.out.printf("readChar():0x%s\n", charToHexString(in.readChar())); System.out.printf("readShort():0x%s\n", shortToHexString(in.readShort())); System.out.printf("readInt():0x%s\n", Integer.toHexString(in.readInt())); System.out.printf("readLong():0x%s\n", Long.toHexString(in.readLong())); System.out.printf("readUTF():%s\n", in.readUTF()); in.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } // 列印byte對應的16進位的字串 private static String byteToHexString(byte val) { return Integer.toHexString(val & 0xff); } // 列印char對應的16進位的字串 private static String charToHexString(char val) { return Integer.toHexString(val); } // 列印short對應的16進位的字串 private static String shortToHexString(short val) { return Integer.toHexString(val & 0xffff); }}
運行結果:
byteToHexString(0x8F):0x8fcharToHexString(0x8FCF):0x8fcfreadBoolean():truereadByte():0x41readChar():0x4243readShort():0x4445readInt():0x12345678readLong():0xfedcba987654321readUTF():abcdefghijklmnopqrstuvwxyz嚴12