Core Java - 流(Stream) - 字節流和字符流(一)

0. 概述:java

Java中基於流的I/O構建在4個抽象類之上, 其中2個是字節流,另外2個是字符流。數組

字節流:網絡

InputStream / OutputStreamapp

當操做字節或其它二進制對象時,應當使用字節流。函數

 

字符流:spa

Reader / Writercode

當操做字符或字符串時,應當使用字符流。對象

 

1. InputStreamblog

InputStream:   輸入字節流,它是一個抽象類。ip

經常使用主要方法:

int read()

返回表明下一個可用字節的整數,當文件達到末尾時,返回-1。

 

int read(bute buffer[])

嘗試讀取buffer.length個字節到buffer中,返回實際成功讀取的字節數;文件到末尾返回-1。

 

int read(bute buffer[], int offset, int numBytes)

嘗試讀取numBytes個字節到buffer中,從buffer[offset]開始保存讀取的字節;

返回實際成功讀取的字節數;文件到末尾返回-1。

 

2. OutputStream

OutputStream: 輸出字節流,它是一個抽象類。

OutputStream有不少子類,它們分別負責向不一樣的介質寫入數據

例如:

FileOutputStream           寫入數據到文件

TelnetOutputStream       寫入數據到網絡鏈接

ByteArrayOutputStream  寫入數據到字節數組

 

經常使用主要方法:

void write(int b)

向輸出流中寫入單個字節。

 

void write(byte buffer[])

向輸出流中寫入一個完整的字節數組。

 

void write(byte buffer[], int offset, int numBytes)

從buffer[offset]開始將numBytes個字節寫入輸出流中。

 

void flush()

結束輸出狀態,刷新輸出緩衝區。

 

3. FileInputStream

文件讀取字節流。

經常使用構造函數:

FileInputStream(String filePath)  (更經常使用)

FileInputStream(File fileObj)

一個同構輸入流來讀取文件內容的例子,演示了3種方式(單字節讀取, 字節數組讀取, 忽略部分字節讀取)

代碼以下:

package corejava8.io.stream;

import java.io.*;

public class FileInputStreamDemo {
    public static void main(String args[]) {
        int size;

        // Use try-with-resources to close the stream
        try (FileInputStream f = new FileInputStream("src/corejava8/io/stream/FileInputStreamDemo.java")) {
            System.out.println("Total Available Bytes: " + (size = f.available()));
            int n = size / 40;
            
            // 經過循環每次單字節讀取
            System.out.println("First " + n + " bytes of the file one read() at a time");
            for (int i = 0; i < n; i++) {
                System.out.print((char) f.read());
            }
            System.out.println("\nStill Available: " + f.available());
            System.out.println("--------------------------------------------------------------");
            
            // 字節數組讀取
            System.out.println("Reading the next " + n + " with one read(b[])");
            byte b[] = new byte[n];
            if (f.read(b) != n) {
                System.err.println("couldn’t read " + n + " bytes.");
            }
            System.out.println(new String(b, 0, n));
            System.out.println("\nStill Available: " + (size = f.available()));
            System.out.println("--------------------------------------------------------------");
            
            // 忽略部分字節讀取
            System.out.println("Skipping half of remaining bytes with skip()");
            f.skip(size / 2);
            System.out.println("Still Available: " + f.available());
            System.out.println("Reading " + n / 2 + " into the end of array");
            if (f.read(b, n / 2, n / 2) != n / 2) {
                System.err.println("couldn't read " + n / 2 + " bytes.");
            }
            System.out.println(new String(b, 0, b.length));
            System.out.println("\nStill Available: " + f.available());
        } catch (IOException e) {
            System.out.println("I/O Error: " + e);
        }
    }
}

運行結果以下:

Total Available Bytes: 1704

First 42 bytes of the file one read() at a time

package corejava8.io.stream;

 

import java.

Still Available: 1662

--------------------------------------------------------------

Reading the next 42 with one read(b[])

io.*;

 

public class FileInputStreamDemo {

 

 

Still Available: 1620

--------------------------------------------------------------

Skipping half of remaining bytes with skip()

Still Available: 810

Reading 21 into the end of array

io.*;

 

public class Fm.err.println("couldn

 

Still Available: 789

 

4. FileOutputStream

文件輸出字節流,用於向文件中寫入字節。

4個經常使用構造函數:

FileOutputStream(String filePath)

FileOutputStream(File fileObj)

FileOutputStream(String filePath, boolean append)

FileOutputStream(File fileObj, boolean append)

在開始下面的例子前,咱們先提到流關閉的一個細節,那就是

在JDK 7以前的遺留代碼,都使用顯式地調用close()方法來關閉流,這種辦法

比較笨拙。

老的代碼:

try {
      FileOutputStream f0 = new FileOutputStream("file1.txt");
      // 文件寫入操做  
    } catch(IOException e) {
      System.out.println("An I/O Error Occurred");
    } finally {
      try {
        if(f0 != null) f0.close();
      } catch(IOException e) {
        System.out.println("Error Closing file1.txt");
      }
    }
}

新的代碼(JDK 7及之後的代碼):

帶資源的try(try with resources)

try (FileOutputStream f0 = new FileOutputStream("file1.txt")) {
  // 文件寫入操做  
} catch(IOException e) {
  System.out.println("An I/O Error Occurred");
}

 是否是代碼變得更加簡潔了?

 

咱們的例子:

package corejava8.io.stream;

import java.io.*;

public class FileOutputStreamDemo {
    public static void main(String args[]) {
        String source = "Now is the time for all good men\n" + " to come to the aid of their country\n"
                + " and pay their due taxes.";
        byte buf[] = source.getBytes();
        // Use try-with-resources to close the files.
        try (FileOutputStream f0 = new FileOutputStream("file1.txt");
                FileOutputStream f1 = new FileOutputStream("file2.txt");
                FileOutputStream f2 = new FileOutputStream("file3.txt")) {
            // write to first file
            for (int i = 0; i < buf.length; i++)
                f0.write(buf[i]);
            
            // write to second file
            f1.write(buf);
            
            // write to third file
            f2.write(buf, 3, buf.length - 3);
        } catch (IOException e) {
            System.out.println("An I/O Error Occurred");
        }
    }
}

運行結果以下:

第一個,第二個文件內容都是:

Now is the time for all good men
to come to the aid of their country
and pay their due taxes.

第三個文件跳過第一個單詞,內容以下:

is the time for all good men
to come to the aid of their country
and pay their due taxes.

上述代碼中:

byte buf[] = source.getBytes();

用於獲取源數據(字符串)的字節數組。

相關文章
相關標籤/搜索