Java IO

1,概述java

Java IO是Java用來讀寫數據(輸入和輸出)的API。這裏主要介紹如下幾點內容:c++

Java流式輸入/輸出
Java流類的分類 輸入
/輸出流類 常見的節點流和處理流 文件流 緩衝流 數據流 轉換流 Print流 Object流

2,Java流式輸入和輸出數組

在Java程序中,對於數據的輸入輸出操做以"流"(Stream)方式進行;J2SDK提供了各類各樣的"流"類,用以獲取不一樣種類的數據;程序中經過標準的方法輸入或輸出數據。各種用途彙總以下:緩存

  • 文件訪問
  • 網絡訪問
  • 內存緩存訪問
  • 線程內部通訊(管道)
  • 緩衝
  • 過濾
  • 解析
  • 讀寫文本 (Readers / Writers)
  • 讀寫基本類型數據 (long, int etc.)
  • 讀寫對象

3,Java流的分類網絡

java.io包中定義了多個流類型(類或抽象類)來實現輸入/輸出功能。能夠從不一樣的角度對其進行分類:app

  • 按數據流的方向不一樣能夠分爲輸入流和輸出流;
  • 按處理數據單位不一樣能夠分爲字節流和字符流(一個字節1 byte=8 bits,一個字符Unicode=2字節);
  • 按照功能不一樣能夠分爲節點流和處理流;

輸入和輸出:四個抽象類(凡是Stream結尾的否是字節流)dom

  字節流 字符流
輸入流 InputStream Reader
輸出流 OutputStream Writer

 

 

 

節點流和處理流:編碼

節點流爲能夠從一個特定的數據源(節點)讀寫數據(好比:文件,內存)spa

處理流是「鏈接」在已經存在的流(節點流或處理流)之上,經過對數據的處理爲程序提供更爲強大的讀寫功能:線程

4,InputStream & OutputStream,Reader & Writer

4.1,InputStream

繼承自InputStream的流都是用於向程序中輸入數據,且數據的單位爲字節(byte,8bits),下圖中深色爲節點流,淺色爲處理流。

InputStream的基本方法:

//讀取一個字節並以整數的形式返回(0~255) //若是返回-1表示已到輸入流的末尾
int read() throws IOException //讀取一系列字節並存儲到一個數組buffer //返回實際讀取的字節數,若是讀取前已到輸入流的末尾返回-1
int read(byte[] buffer) throws IOException //讀取length個字節 //並存儲到一個字節數組buffer,從length位置開始 //返回實際讀取的字節數,若是讀取前已到輸入流的末尾返回-1
int read(byte[] buffer, int offset, int length) throws IOException //關閉流釋放內存資源
void close() throws IOException //跳過n個字節不讀,返回實際跳過的字節數
long skip(long n) throws IOException

4.2,OutputStream

繼承自OutputStream的流是用於從程序中輸出數據,切數據的單位是字節(byte,8bits),下圖中深色爲節點流,淺色爲處理流。

OutputStream的基本方法:

//向輸出流中寫入一個字節數據,該字節數據位參數b的低8位
void write(int b) throws IOException //將一個字節類型的數組中的數據寫入輸出流
void writer(byte[] b) throws IOException //將一個字節類型的數組中的數據從指定位置(off)開始len個字節寫入到輸出流
void write(byte[] b, int off, int len) throws IOException //關閉流釋放內存資源
void close() throws IOException //將輸出流中緩衝的數據所有寫出到目的地
void flush() throws IOException

4.3,Reader

繼承自Reader的流都是用於向程序中輸入數據,且數據的單位是字符(16bits,例如一箇中文是兩個字節表示);下圖中深色爲節點流,淺色爲處理流:

Reader的基本方法

//讀取一個字符並以整數的形式返回(0~255) //若是返回-1表示已到輸入流的末尾
int read() throws IOException //讀取一系列字符並存儲到一個數組buffer //返回實際讀取的字符數,若是讀取前已到輸入流的末尾返回-1表示已到輸入流的末尾
int read(char[] cbuf) throws IOException //讀取length個字符 //並存儲到一個數組buffer,從length位置開始 //返回實際讀取的字符數,若是讀取前已到輸入流的末尾返回-1表示已到輸入流的末尾
int read(char[] cbuf, int offset, int length) throws IOException //關閉流釋放內存資源
void close() throws IOException //跳過n個字符不讀,返回實際跳過的字節數
long skip(long n) throws IOException

4.4,Writer

繼承自Writer的流都是用於程序中輸出數據,且數據的單位爲字符(16bits);下圖中深色爲節點流,淺色爲處理流:

Writer基本方法:

//向輸出流中寫入一個字符數據,該字符數據爲參數c的低16位
void write(int c) throws IOException //將一個字符類型的數組中的數據寫入輸出流
void writer(char[] cbuf) throws IOException //將一個字符類型的數組中的數據從指定位置(offset)開始len個字節寫入到輸出流
void write(char[] cbuf, int offset, int len) throws IOException //將一個字符串中的字符寫入到輸出流
void write(String string) throws IOException //將一個字符串從offset開始的length個字符寫入到輸出流
void write(String string, int offset, int length) throws IOException //關閉流釋放內存資源
void close() throws IOException //將輸出流中緩衝的數據所有寫出到目的地
void flush() throws IOException

5,經常使用的節點流和處理流

5.1,節點流類型

  類型 字符流 字節流
File(文件)

FileReader

FileWriter

FileInputStream

FileOutputStream

Memory Array

CharArrayReader

CharArrayWriter

ByteArrayInputStream

ByteArrayOutputStream

Memory String

StringReader

StringWriter

---
Pipe(管道,線程)

PipedReader

PipedWriter

PipedInputStream

PipedOutputStream

 

 

 

 

 

 

 

 

 

 

 

 

5.1.1,File(訪問文件)

FileInputStream和FileOutputStream分別繼承自OutputStream和OutputStream,用於向文件中輸入和輸出字節。

FileInputStream和FileOutputStream的構造方法:

FileInputStream: FileInputStream(File file) Creates a FileInputStream by opening a connection to an actual file, the file named by the File object file in the file system. FileInputStream(FileDescriptor fdObj) Creates a FileInputStream by using the file descriptor fdObj, which represents an existing connection to an actual file in the file system. FileInputStream(String name) Creates a FileInputStream by opening a connection to an actual file, the file named by the path name name in the file system. OutputStream: FileOutputStream(File file) Creates a file output stream to write to the file represented by the specified File object. FileOutputStream(File file, boolean append) Creates a file output stream to write to the file represented by the specified File object. FileOutputStream(FileDescriptor fdObj) Creates a file output stream to write to the specified file descriptor, which represents an existing connection to an actual file in the file system. FileOutputStream(String name) Creates a file output stream to write to the file with the specified name. FileOutputStream(String name, boolean append) Creates a file output stream to write to the file with the specified name.

FileInputStream和FileOutputStream類支持其父類InputStream和OutputStream所提供的數據讀寫方法。

注意:

在實例化FileInputStream和FileOutputStream時要用ty-catch語句加以處理,由於可能拋出FileNotFoundException。

在讀寫數據時也要用try-catch語句加以處理,由於可能拋出IOException。

例子:

1,FileInputStream & FileOutputStream

FileInputStream:

 public static void main(String[] args) { int b = 0; FileInputStream fis = null; try { fis = new FileInputStream("d:\\share\\java\\io\\TestFileInputStream.java"); } catch (FileNotFoundException e) { System.out.println("找不到指定文件"); System.exit(-1); } try { long num = 0; while((b = fis.read()) != -1) { System.out.print((char)b); num++; } fis.close(); System.out.println("共讀取了" + num + "個字節"); } catch (IOException e) { System.out.println("文件讀取錯誤"); System.exit(-1); } }

結果:對於中文亂碼,由於是一個字節一個字節的讀取,因此只讀取了半個中文

控制檯輸出: import java.io.*; public class TestFileInputStream { public static void main(String[] args) { int b = 0; FileInputStream in = null; try { in = new FileInputStream("d:\\share\\java\\io\\TestFileInputStream.java"); } catch (FileNotFoundException e) { System.out.println("ÕÒ²»µ½Ö¸¶¨Îļþ"); System.exit(-1); } try { long num = 0; while((b=in.read())!=-1){ System.out.print((char)b); num++; } in.close(); System.out.println(); System.out.println("¹²¶ÁÈ¡ÁË "+num+" ¸ö×Ö½Ú"); } catch (IOException e1) { System.out.println("Îļþ¶ÁÈ¡´íÎó"); System.exit(-1); } } }共讀取了700個字節

FileOutputStream:

    public static void main(String[] args) { int b = 0; FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream("d:/share/java/HelloWorld.java"); fos = new FileOutputStream("d:/share/java/io/HW.java");//沒有回自動新建一個文件
            while ((b = fis.read()) != -1) { fos.write(b); } fis.close(); fos.close(); } catch (FileNotFoundException e) { System.out.println("找不到指定的文件"); System.exit(-1); } catch (IOException e) { System.out.println("文件複製錯誤"); System.exit(-1); } System.out.println("文件已複製"); }

輸出:能夠在d:/share/java/io中看到複製的文件HW.java

2,FileReader & FileWriter

FileReader:

 public static void main(String[] args) { int c = 0; FileReader fr = null; try { fr = new FileReader("d:\\share\\java\\io\\TestFileReader.java"); while((c = fr.read()) != -1) { System.out.print((char)c); } fr.close(); } catch (FileNotFoundException e) { System.out.println("找不到指定文件"); } catch (IOException e) { System.out.println("讀取文件出錯"); } }

FileWriter:

例一:

    public static void main(String[] args) { FileWriter fw = null; try { fw = new FileWriter(new File("d:\\unicode.dat")); for(int i = 0; i <= 50000; i++) {//char最大爲65535
 fw.write(i); } fw.close(); } catch (IOException e) { e.printStackTrace(); System.out.println("文件寫入錯誤"); System.exit(-1); } }

結果:D盤中的unicode.dat文件中的內容。

例二:

    public static void main(String[] args) throws Exception { FileReader fr = new FileReader("d:/java/io/TestFileWriter2.java"); FileWriter fw = new FileWriter("d:/java/io/TestFileWriter2.bak"); int b; while((b = fr.read()) != -1) { fw.write(b); } fr.close(); fw.close(); }

 5.2,處理流

處理流須要套接在節點流和其餘處理流之上使用

處理類型 字符流 字節流
Buffering

BufferReader

BufferWriter

BufferedInputStream

BufferedOutputStream

Converting between

bytes and character

InputStreamReader

OutputStreamWriter

 
Object Serialization ---

ObjectInputStream

ObjectOutputstream

Data Conversion ---

DataInputStream

DataOutputStream

Counting LineNumberReader LineNumberInputStream
Peeking ahead PushbackReader

PushbackInputStream

Printing PrintWriter PrintStream

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

5.2.1,緩衝流

緩衝流要「套接」在相應的節點流之上,對讀寫的數據提供了緩衝的功能,提升了讀寫的效率,同時增長了一些新的方法。

J2SDK提供了四種緩衝流,其經常使用的構造方法:

BufferedReader BufferedReader(Reader in) Creates a buffering character-input stream that uses a default-sized input buffer. BufferedReader(Reader in, int sz) Creates a buffering character-input stream that uses an input buffer of the specified size. BufferedWriter BufferedWriter(Writer out) Creates a buffered character-output stream that uses a default-sized output buffer. BufferedWriter(Writer out, int sz) Creates a new buffered character-output stream that uses an output buffer of the given size. BufferedInputStream BufferedInputStream(InputStream in) Creates a BufferedInputStream and saves its argument, the input stream in, for later use. BufferedInputStream(InputStream in, int size) Creates a BufferedInputStream with the specified buffer size, and saves its argument, the input stream in, for later use. BufferedOutputStream BufferedOutputStream(OutputStream out) Creates a new buffered output stream to write data to the specified underlying output stream. BufferedOutputStream(OutputStream out, int size) Creates a new buffered output stream to write data to the specified underlying output stream with the specified buffer size.
緩衝輸入流支持其父類的mark和reset方法
BufferedReader提供了readLine方法用於讀取一行字符串(以\r或\n分隔)
BufferedWriter提供了newLine方法用於寫入一個行分隔符
對於輸出的緩衝流,寫出的數據會先在內存中緩存,使用flush方法將會使內存中的數據馬上寫出。

例一:

    public static void main(String[] args) { try { FileInputStream fis = new FileInputStream("d:\\share\\java\\HelloWorld.java"); BufferedInputStream bis = new BufferedInputStream(fis); int c = 0; System.out.println(bis.read()); System.out.println(bis.read()); bis.mark(100); for(int i = 0; i <= 10 && (c=bis.read()) != -1; i++) { System.out.print((char)c + " "); } System.out.println(); bis.reset(); for(int i = 0; i <= 10 && (c=bis.read()) != -1; i++) { System.out.print((char)c + " "); } bis.close(); } catch (IOException e) { e.printStackTrace(); } }

輸出:

47
42 a l ; s k j d f ; a l ; s k j d f ;

例二:

    public static void main(String[] args) { try { BufferedWriter bw = new BufferedWriter(new FileWriter("d:\\dat2.txt")); BufferedReader br = new BufferedReader(new FileReader("d:\\dat2.txt")); String s = null; for(int i = 1; i<=100; i++) { s = String.valueOf(Math.random()); bw.write(s); bw.newLine(); } bw.flush(); while((s = br.readLine()) != null) {//讀一行
 System.out.println(s); } bw.close(); br.close(); } catch (IOException e) { e.printStackTrace(); } }

輸出:

dat2.txt文件:

控制檯輸出:

 5.2.2,轉換流

InputStreamReader和OutputStreamWriter用於字節數據到字符數據之間的轉換。

InputStreamReader須要和InputStream套接(把InputStream轉換成InputStreamReader)

OutputStreamWriter須要和OutputStream套接(把OutputStreamWriter轉換成OutputStream)

轉換流在構造時能夠指定其編碼集合,例如:

InputStream is = new InputStreamReader(System.in, "IOS8859_1");

例一:

  public static void main(String[] args) { try { OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d:\\bak\\char.txt")); osw.write("miscalkjsdlasjdlajslkdalksd"); System.out.println(osw.getEncoding()); osw.close(); osw = new OutputStreamWriter(new FileOutputStream("d:\\bak\\char.txt", true), "ISO8859_1");//true,追加
            osw.write("sadasdasdasdasd"); System.out.println(osw.getEncoding()); osw.close(); } catch (Exception e) { e.printStackTrace(); } }

結果:

UTF8//系統默認的編碼
ISO8859_1

例二:

    public static void main(String[] args) { try { InputStreamReader isr = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(isr); String s = null; s = br.readLine(); while(s != null) { if("exit".equalsIgnoreCase(s)) break; System.out.println(s.toUpperCase()); s = br.readLine(); } br.close(); } catch (Exception e) { e.printStackTrace(); } }

輸出:

add111
ADD111
exit

5.2.3,數據流

DataInputStream 和DataOutputStream分別繼承自InputStream 和 OutputStream,它屬於處理流,須要分別套接在InputStream 和 OutputStream類型的節點流上。

DataInputStream 和DataOutputStream提供了能夠存取與機器無關的Java原始類型數據(如:int,double等)的方法。

DataInputStream 和DataOutputStream的構造方法:

DataInputStream(InputStream in) Creates a DataInputStream that uses the specified underlying InputStream. DataOutputStream(OutputStream out) Creates a new data output stream to write data to the specified underlying output stream.

ByteArrayInputStream 和 ByteArrayOutputStream

例子:

    public static void main(String[] args) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream();//在內存中分配了一個字節數組
            DataOutputStream dos = new DataOutputStream(baos); dos.writeDouble(Math.random()); dos.writeBoolean(true); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); System.out.println(bais.available()); DataInputStream dis = new DataInputStream(bais); System.out.println(dis.readDouble()); System.out.println(dis.readBoolean()); dos.close(); dis.close(); } catch (Exception e) { e.printStackTrace(); } }

結果:

9
0.5620896958440097
true

5.2.4,Print流

Print流(只有輸出流沒有輸入流)

PrintWriter和PrintStream都屬於輸出流,分別針對於字符和字節

PrintWriter和PrintStream提供了重載的print方法

Println方法用於多種數據類型的輸出

PrintWriter和PrintStream的輸出操做不會拋出異常,用戶經過檢測錯誤狀態獲取錯誤信息

PrintWriter和PrintStream有自動flush方法

構造方法:

PrintWriter(File file) Creates a new PrintWriter, without automatic line flushing, with the specified file. PrintWriter(File file, String csn) Creates a new PrintWriter, without automatic line flushing, with the specified file and charset. PrintWriter(OutputStream out) Creates a new PrintWriter, without automatic line flushing, from an existing OutputStream. PrintWriter(OutputStream out, boolean autoFlush) Creates a new PrintWriter from an existing OutputStream. PrintWriter(String fileName) Creates a new PrintWriter, without automatic line flushing, with the specified file name. PrintWriter(String fileName, String csn) Creates a new PrintWriter, without automatic line flushing, with the specified file name and charset. PrintWriter(Writer out) Creates a new PrintWriter, without automatic line flushing. PrintWriter(Writer out, boolean autoFlush) Creates a new PrintWriter. PrintStream(File file) Creates a new print stream, without automatic line flushing, with the specified file. PrintStream(File file, String csn) Creates a new print stream, without automatic line flushing, with the specified file and charset. PrintStream(OutputStream out) Creates a new print stream. PrintStream(OutputStream out, boolean autoFlush) Creates a new print stream. PrintStream(OutputStream out, boolean autoFlush, String encoding) Creates a new print stream. PrintStream(String fileName) Creates a new print stream, without automatic line flushing, with the specified file name. PrintStream(String fileName, String csn) Creates a new print stream, without automatic line flushing, with the specified file name and charset.

例一:

  public static void main(String[] args) { try { PrintStream ps = null; FileOutputStream fos = new FileOutputStream("d:\\bak\\log.dat"); ps = new PrintStream(fos); if(ps != null) { System.setOut(ps);//把ps設置成System.out.println();再也不輸出在控制檯了
 } int ln = 0; for(char c = 0; c <= 60000; c++) { System.out.print(c + ""); if( ln++ >= 100) { System.out.println(); ln = 0; } } } catch (Exception e) { e.printStackTrace(); } }

結果:d:\\bak\\log.dat,log.data文件

 例二:

    public static void main(String[] args) { try { PrintStream ps = System.out; BufferedReader br = new BufferedReader(new FileReader("d:\\bak\\log.dat")); String s = null; while((s = br.readLine()) != null) { ps.println(s); } br.close(); } catch (IOException e) { e.printStackTrace(); } }

結果:

例三:

    public static void main(String[] args) { try { String s = null; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); FileWriter fw = new FileWriter("d:\\bak\\logfile.log", true);//日誌
            PrintWriter pw = new PrintWriter(fw); while ((s = br.readLine()) != null) { if("exit".equalsIgnoreCase(s)) break; System.out.println(s.toUpperCase()); pw.println("--------"); pw.println(s.toUpperCase()); pw.flush(); } pw.println("=====" + new Date() + "======"); pw.flush(); pw.close(); } catch (IOException e) { e.printStackTrace(); } }

結果:

控制檯: 12121212121 adasdasdasdasd ADASDASDASDASD exit

文件:d:\\bak\\logfile.log,logfile.log文件

 5.2.5,Object流

直接將Object寫入或寫出

transient關鍵字

serializable接口

externalizable接口

例一:

public class Test { public static void main(String[] args) { try { T t = new T(); t.k = 18; FileOutputStream fos = new FileOutputStream("d:/bak/testobjectio.dat"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(t); oos.flush(); oos.close(); FileInputStream fis = new FileInputStream("d:/bak/testobjectio.dat"); ObjectInputStream ois = new ObjectInputStream(fis); T t2 = (T) ois.readObject(); System.out.println(t2.i + "//" + t2.j + "//" + t2.d + "//" + t2.k); } catch (Exception e) { e.printStackTrace(); } } } class T implements Serializable { int i = 10; int j = 9; double d = 2.3; int k = 15; }

結果:

10//9//2.3//18

例二:

用transient修飾變量k

class T implements Serializable { int i = 10; int j = 9; double d = 2.3; transient int k = 15; }

結果:

10//9//2.3//0

transient修飾的變量k不會被寫入進去,因此取出來的k爲空,爲默認值0
相關文章
相關標籤/搜索