天天看點

java 操作位元組_Java 位元組流操作2

上篇文章Java 位元組流操作介紹了java中基本的位元組流操作,但是我們常常對于字元操作,如果使用位元組流來實作輸入輸出就顯得麻煩,我們可以使用字元流來實作對我們看得見的字元char進行操作,主要内容如下:

基本流(Reader/Writer)

轉換流(InputStreamReader/OutputStreamEWriter)

檔案字元流(FileReader/FileWriter)

字元數組流(charArrayReader/charArrayWriter)

緩沖字元流(BufferedReader/BufferedWriter)

裝飾類(PrintWriter)

一、基本流

位元組流的基本流是InputStream/OutputStream,這裡的字元流的基本流是Reader/Writer,他們都是抽象類,想要實作更加複雜的操作就必須要子類來擴充。他們内部主要的就是read和write方法,實作單個字元及字元數組的讀取的寫入。此處就不再列出,我們将會從他們的子類中看看這些方法的實作。

二、轉換流

InputStreamReader和OutputStreamWriter這兩個類型流,在整個字元流中是十分重要的流,他們實作了和位元組流的轉換。先看看InputStreamReader:

private final StreamDecoder sd;

public InputStreamReader(InputStream in)

public InputStreamReader(InputStream in, String charsetName)

public InputStreamReader(InputStream in, Charset cs)

public InputStreamReader(InputStream in, CharsetDecoder dec)

public int read() throws IOException {

return sd.read();

}

public int read(char cbuf[], int offset, int length) throws IOException {

return sd.read(cbuf, offset, length);

}

首先定義了一個StreamDecoder 類型的常量(這是一個十分重要的成員),一堆構造方法通過不同的方式指定了外部傳入的InputStream類型的參數和解碼類型。我們看到,read方法中調用的是上述的sd常量(這是一個StreamDecoder類型的常量)的方法。這個StreamDecoder類實際上完成了将位元組轉換成char的操作。

public class Test_InputOrOutput {

public static void main(String[] args) throws IOException{

InputStreamReader inr = new InputStreamReader(new FileInputStream("hello.txt"));

char[] chs = new char[100];

inr.read(chs);

System.out.println(chs);

inr.close();

}

}

上述代碼展示了如何從檔案中按照指定的解碼方式讀取出字元,OutputStreamWriter幾乎是逆操作:

public void write(int c)

public void write(char cbuf[], int off, int len)

public void write(String str, int off, int len)

可以寫int,可以寫char數組,還可以寫字元串(實際上還是調用了getchars方法擷取該字元串的内置char數組,然後調用寫數組的方法)。

public class Test_InputOrOutput {

public static void main(String[] args) throws IOException{

OutputStreamWriter ow = new OutputStreamWriter(new FileOutputStream("hello.txt"));

ow.write("walker");

ow.close();

}

}

三、檔案字元流

FileReader和FileWriter兩個流,繼承的是上述的兩個轉換流。内部的方法非常簡單,隻是幾個構造方法而已。

public FileReader(String fileName) throws FileNotFoundException {

super(new FileInputStream(fileName));

}

public FileReader(File file) throws FileNotFoundException {

super(new FileInputStream(file));

}

public FileWriter(String fileName) throws IOException {

super(new FileOutputStream(fileName));

}

public FileWriter(String fileName, boolean append) throws IOException {

super(new FileOutputStream(fileName, append));

}

public FileWriter(File file) throws IOException {

super(new FileOutputStream(file));

}

從源代碼中可以看出來,這兩個檔案流完全依賴父類。自己基本沒有擴充父類,使用的方法都是父類的。你可以通過傳檔案的路徑或者建構File類作為構造參數傳入。

public class Test_InputOrOutput {

public static void main(String[] args) throws IOException{

FileReader fr = new FileReader("hello.txt");

char[] chars = new char[1024];

fr.read(chars);

System.out.println(chars);

}

}

一樣可以達到讀取字元的效果,實際上上述代碼可以轉換為:

public class Test_InputOrOutput {

public static void main(String[] args) throws IOException{

InputStreamReader ins = new InputStreamReader(new FileInputStream("hello.txt"));

char[] chars = new char[1024];

ins.read(chars);

System.out.println(chars);

}

}

//因為FIleReader的内部還是通過super調用父類的構造方法

四、字元數組流

和之前介紹的位元組數組流類似,都是為了能提高效率防止記憶體浪費而設計的。看看我們上面的一段代碼:

public class Test_InputOrOutput {

public static void main(String[] args) throws IOException{

FileReader fr = new FileReader("hello.txt");

char[] chars = new char[1024];

fr.read(chars);

System.out.println(chars);

}

}

這段程式其實是不完善的,因為我們預設hello檔案中的字元容量小于等于1024,那如果檔案足夠大,我們勢必要建立更大的字元數組(這是一種浪費記憶體)。我們可以使用字元數組流來實作動态擴容,解決記憶體空間。上述代碼可以改寫:

public class Test_InputOrOutput {

public static void main(String[] args) throws IOException{

FileReader fr = new FileReader("hello.txt");

int x = 0;

CharArrayWriter chw = new CharArrayWriter();

while ((x = fr.read()) != -1){

chw.write(x);

}

System.out.println(chw.toString());

chw.close();

}

}

這樣,即使檔案再大,我們也不會浪費很多記憶體空間。至于StingReader和StringWriter兩個流其實是類似的,因為String的本質是char數組, 是以他們必然也是有數組作為最基本的操作。

五、緩沖字元流

字元的緩沖流和位元組的緩沖流是類似的。都是裝飾流。

public class Test_InputOrOutput {

public static void main(String[] args) throws IOException{

BufferedReader bins = new BufferedReader(new FileReader("hello.txt"));

BufferedWriter bws = new BufferedWriter(new FileWriter("hello.txt",true));

int x;

while ((x = bins.read()) != -1){

System.out.println((char)x);

bws.write(x);

}

}

}

//緩沖讀和緩沖寫

六、PrintWriter

這是一個繼承與Writer的流,他是一個非常友善的類,可以直接指定檔案名作為參數,可以指定編碼類型,還支援自動緩沖技術,可以自動轉換多種基本類型為字元串形式寫入檔案中。在我們日常使用寫入檔案時,可以優先考慮使用該類。

protected Writer out;

private final boolean autoFlush;

//構造方法

public PrintWriter (Writer out) {

this(out, false);

}

public PrintWriter(OutputStream out) {

this(out, false);

}

public PrintWriter(String fileName) throws FileNotFoundException {

this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName))),

false);

public PrintWriter(File file) throws FileNotFoundException {

this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file))),

false);

}

//寫入一個character

public void write(int c) {

try {

synchronized (lock) {

ensureOpen();

out.write(c);

}

}

catch (InterruptedIOException x) {

Thread.currentThread().interrupt();

}

catch (IOException x) {

trouble = true;

}

}

//寫入一個字元串

public void write(String s) {

write(s, 0, s.length());

}

//重載print方法

public void print(boolean b) {

write(b ? "true" : "false");

}

public void print(char c) {

write(c);

}

public void print(int i) {

write(String.valueOf(i));

}

public void println() {

newLine();

}

public void println(int x) {

synchronized (lock) {

print(x);

println();

}

}

public void println(String x) {

synchronized (lock) {

print(x);

println();

}

}

上述代碼中的print和println并非和我們的标準輸出流(System.out.println)同義,這裡的print表示寫入到檔案中。

public class Test_InputOrOutput {

public static void main(String[] args) throws IOException{

PrintWriter pw = new PrintWriter("hello.txt");

pw.println('x');

pw.close();

}

}

使用了PrintWriter寫入到檔案中,非常的簡單友善,可以指定檔案路徑,File,OutputStream作為構造方法的形參。這一切的轉換都封裝了,自動提供緩沖流。這是一種比較好的輸出流,在之後的使用中,如果遇到輸出到檔案,應該優先考慮PrintWriter。

标簽:Java,位元組,void,throws,char,new,操作,public,String

來源: https://www.cnblogs.com/Bkxk/p/11731792.html