最全的IO操作知识总结
模擬BufferedInputStream,編寫一個類
?
?
package toto.IO;
?
import java.io.IOException;
import java.io.InputStream;
?
class MyBufferedInputStream{
??? private InputStream in;
??? privatebyte[] buf = newbyte[1024*4];
??? privateintpos = 0,count = 0;
??? MyBufferedInputStream(InputStream in){
?????? this.in = in;
??? }
??? //從緩沖區中讀取一個字節
??? /**
??? *緩沖區的原理:
??? *其實就是定義了一個臨時容器
??? *然后將獲取到的數據都存入到臨時容器中,通過臨時容器的方法獲取數據,當臨時容器
??? *中的數據取完后,再獲取一批數據進容器、
???
發現自定義的緩沖區出現了秒殺效果
為什么秒殺呢?
因為MP3這樣的媒體數據,對應的二進制數據,很有可能出現連續多個1的情況。而連續的過程中,出現-1,程序就認為讀到了末尾,程序停止讀取。
???
為了避免這種情況,將獲取的一個字節數據,進行提升,變成int ,并在保留原有八位的基礎上補零。補完后,就變成了正數,就避免了-1的這種情況。
??? ?*/
??? publicint myRead() throws IOException{
?????? if(count == 0){
?????????? count = in.read(buf);//通過流對象從硬盤獲取一批數據裝入緩沖去
??????????
?????????? pos = 0;//從0開始取
?????????? byte b = buf[pos];//將數據存入數組
?????????? pos++;//取完之后pos++
?????????? count--;//取走一個減少一個
?????????? returnb&oxff;?? //這里與上的是255。這里進行了自動提升效果。
?????? }elseif(count>0){
?????????? //第二次取時count>0
?????????? byte b = buf[pos];
?????????? pos++;
?????????? count--;
?????????? return b;
?????? }else {
?????????? return -1;
?????? }
??? }
??? publicvoid myClose()throws IOException{
?????? in.close();
??? }
}
?
publicclass Demo1 {
?
???
}
?
?
?
/*package toto.IO;
?
import java.io.IOException;
import java.io.Reader;
?
*//**
?*按照裝飾設計模式的思想
?*自定義MyBufferedReader類
?*一樣提供一個和BufferedReader功能相同的readLine方法。
?*//*
class MyBufferedReader{//extends Reader{
??? 由于它里面中提供Reader中的所有方法,故它要繼承Reader類。這里繼承的原因是里面的方法太多這里不寫了
???
??? private FileReader r;這種方式只能包裝FileReader類,
??? 要想包裝所有的Reader的子類,我們寫成以下方式:
???
??? private Reader r;
???
??? MyBufferedReader(Reader r) {//這里是被包對象
?????? this.r = r;
??? }
??? 提供一個一次讀一行的方法。
??? ?* 1、使用的還是Reader中read()方法,一次讀一個。
??? ?* 2、將讀到一個字符進行臨時存儲。數組和StringBuilder都可以。
??? ?* 這里選用StringBuilder,因為可以省略數組延長部分代碼的編寫。該Builder中使用就是數組
??? ?* 而且可變長度,并且最終變成字符串。
??? ?* 3、因為自負有很多需要循環讀取。
??? ?* 4,讀取到的字符進行判斷,如果是回車符,那么就將StringBuilder中的存儲數據作為字符串返回
???
??? public String myReadLine() throws IOException {
?????? StringBuilder sb = new StringBuilder();
??????
?????? int ch = 0;
?????? while((ch==r.read())!=-1) {//使用初進來的read方法,并且要判斷不等于-1
?????????? if(ch=='\r')//遇到這個轉義字符時,不能將這個數據讀進去,并且將這個數據向下讀一個
????????????? continue;
?????????? if(ch=='\n')
????????????? return sb.toString();
?????????? sb.append((char)ch);//如果兩個都滿足,就將數據向里面轉了。
?????? }
?????? return null;
??? }
???
??? public void myClose() throws IOException{
?????? r.close();
??? }
}
public class MyBufferedReader{
?
???
??? public static void main(String[] args) {
?????? // TODO Auto-generated method stub
?
??? }
?
}
*/
?
?
?
轉換流
/*
?* 轉換流,涉及的對象都在字符流體系中。
?* InputStreamReader字節轉到字符的橋梁。把看不懂得轉換成為看的懂的。
?* OutputStreamWriter:字符轉到字節的橋梁。把看得懂的轉換成為看不懂的。
?* 該類本身是一個字符流,因為它是橋梁,需要把一個指定的字節流傳給構造函數。
?* 將制定的字節流轉成字符流。*/
?
package toto.IO;
?
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
?
publicclass Demo2 {
?
??? publicstaticvoid main(String[] args)throws IOException {
?????? //readIn();
//???? System.out.println('-'+0);
//???? System.out.println('1'+0);
?????? readLineByKey();
??? }
??? /*
??? ?* 讀取鍵盤錄入,并打入的錄入的數據
??? ?* 當錄入了一行數據后,打印錄入的一行數據內容。而其可以不斷的進行錄入
??? ?* 一次打印一行。
??? ?*
??? ?*1,讀取鍵盤通過System.in完成
??? ?*2,需要一次打印一行。那么就需要定義一個臨時容器,將讀取到自己額進行臨時存儲。
??? ?*當讀到回車符的時候就降臨時容器中存儲的數據一次性打印、*/
???
??? publicstaticvoid printLineByKey() throws Exception{
?????? InputStream in = System.in;
?????? int by = 0;
?????? StringBuilder sb = new StringBuilder();
?
?????? while((by==in.read())!=-1){//這里有警告,不知道為什么
?????????? if(by=='\r')
????????????? continue;
?????????? if(by=='\n')
????????????? System.out.println(sb.toString());
?????????? else
????????????? sb.append((char)by);
?????? }
??? }
???
??? publicstaticvoid readIn() throws IOException {
?????? //獲取標準的輸入流,對應的默認設備就是鍵盤。
?????? //從鍵盤獲取到的數據都是字節數據。
?????? InputStream in = System.in;
?????? //讀取鍵盤錄入的一個字節
??????
?????? //通過循環形式,讀取一個字節,打印一個字節
?????? int by = 0;
?????? while((by=in.read())!=-1){
?????????? System.out.println(by);
?????? }
??????
??? }
??? publicstaticvoid readLineByKey() throws IOException {
?????? //字節讀取流
??? ??? InputStream in =System.in;
??? ???
?????? //要想使用readLine方法讀取一樣,就要建立BufferReader對象
?????? //但是該字符流的緩沖區,在對象在初始化時,
?????? //要將一個字符對象作為參數傳遞給BufferReader的構造函數
??? ??? //讀取鍵盤是字節流,如何讓字符流的緩沖區所使用呢?,這時就需要將字節流轉成字節流
??? ??? //想要進行字節和字符流的轉換,就需要IO包中的轉換流
??? ??? //由于早期只有字節流,只有涉及到字符流之后才涉及到轉換,故這個轉換體系在字符流中。
??? ??? //InputStreamReader的前面是字節流,后面是字符流。故通過它轉換。
?????? InputStreamReader isr = new InputStreamReader(in);
??? ??? //因為BufferedReader只能包裝字符流。故只需將isr傳遞進去就行了。
??? ??? BufferedReader bufr = newBufferedReader(isr);
??????
??? ??? String line = null;
??? ???
??? ??? while((line=bufr.readLine())!=null){
??? ???? if(line.equals("over")){
??? ??? ??? break;
??? ???? }
??? ???? //System.out.println(line.toUpperCase());
??? ??? }
??? ??? bufr.close();
??? }
???
}
?
?
?
?
?
package toto.IO;
/*流操作的基本規律
?* 流操作要明確數據源和數據目的(數據匯)
?*
?* 在現有程序中,
?* 源:鍵盤
?* 目的控制臺。
?* 1、需求:將一個硬盤上的文件打印在控制臺上
?* 2、需求:將鍵盤錄入的數據存儲到一個文件中。
?*
?* */
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
?
publicclass TransStreamDemo2 {
?
??? publicstaticvoid main(String[] args) throws IOException {
?????? /*InputStream in = System.in;
?????? InputStreamReader isr = new InputStreamReader(in);
?????? BufferedReader bufr = new BufferedReader(isr);*/
?????? //上面三行可以轉換成一行,讀取鍵盤最方便方式,因為鍵盤錄入的都是文本數據。所以一次讀一行最方便,先將字節流包裝成字符流,再將字符流寫入緩沖區,提高效率。
?????? /*BufferedReader bufr = new
?????????? BufferedReader(new InputStreamReader(System.in));*/
??????
??????
?????? //硬盤上的文件是字節流,要將它轉換成字符流,讀取硬盤上的一個文件的方式:
?????? BufferedReader bufr = new
?????? BufferedReader(new InputStreamReader(new FileInputStream("文件地址")));
??????
??????
?????? /*向控制臺上輸出,使用System.out
OutputStream out = System.out;
?????? OutputStreamWriter osw = new OutputStreamWriter(out);
?????? BufferedWriter bufw = new BufferedWriter(osw);*/
??????
//???? BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
??????
?????? //寫需求1時,上面包裝流中式文件路徑,下面是System.out,當寫需求2時,上面是System.in,下面是要寫到的文件的路徑。當上下都是文件名稱時,相當于文件的復制。
?????? BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("要寫到的文件的地址")));
?????? String line = null;
?????? while((line==bufr.readLine())!=null){
?????????? if("over".equals(line)){
????????????? break;
?????????? }
?????????? bufw.write(line.toUpperCase());
?????????? bufw.newLine();
?????????? bufw.flush();
?????? }
?????? bufw.close();
?????? bufr.close();
??? }
?
}
?
?
IO包中對象其實都是以圍繞讀寫為主,用于操作數據。
IO技術的難點:因為io包中的對象太多,在實際開發,不太容易明確使用哪個對象
?
IO操作的基本規律:
1、?作用的數據源和數據目的。
如果是操作數據源:輸入流。(InputStream ,Reader),讀入的是字節流用InputStream,讀入的是字符流用Reader.
如果是操作數據匯:就是輸入流。(OutputStream,Writer),輸出成字節流用OutputStream,輸出成字符用writer
?
2、?要操作的數據是不是純文本數據。
如果是:使用字符流
如果不是:使用字節流。
3,根據源和目的的設備來確定要操作的對象。
?
?
?
?
無論數據源或者數據匯都有存在設備。
源設備:硬盤(File)。鍵盤(鍵盤對應的是System.in)。內存(內存對應的都是數組)。
目的設備:硬盤(File),控制臺(控制臺對應的是:System.out),內存(內存對應的是數組)。
?
?
這兩個明確可以確定到底要使用上面四個體系中的那個體系。
?
需求一:對文本文件進行復制
1,?這個需求既有源又有目的
源:硬盤上的文件。InputStream Reader
目的:硬盤上的文件。OutputStream or Writer
?
是不是純文本數據呢?是。
源:要使用字符讀取流Reader
目的:要使用字符輸出流Writer
?
那么體系確定后,要使用該體系中那個對象呢?
源:是一個文件。所以要使用字符讀取流中可以操作文件的對象:FileReader
目的:也是一個文件,所以要使用字符寫入流中的可以操作文件的對象:FileWriter
?
FileReader fr = new FileReader(“a.txt”);
FileWriter fw = new FileWriter(“b.txt”);
?
該操作過程中是否需要提高俠侶呢?是。
如果是:加入緩沖技術。
代碼就變成:
BufferedReader bufr = new BufferedReader(newFileReader(“a.txt”));
BufferedWriter bufw = newBufferedWriter(new FileWriter(“b.txt”));
?
?
需求二,將一個硬盤上的文件打印在控制臺上。
1,?明確源和目的
源:硬盤的文件。讀取文件,體系是InputStream or Reader
目的:控制臺。OutputStream or Writer
???? 對于控制臺較為特殊,其默認的目的是System.out
2,?是不是純文本數據
是
源:Reader
目的Writer
3,明確體系中的對象
源:因為是一個文件,FileReader
目的:因為是控制臺對應的對象是System.out,為了便于字符操作,所以將System.out轉換成字符流。
FileReader fr =new FileReader(“a.txt”);? 讀取字符流
OutputStreamWriterout =new OutputStreamWriter(System.out;); //輸出字節流
??????
FileReader fr =new FileReader(“a.txt”);? 讀取字符流
OutputStreamWriterosw = new OutputStreamWriter(System.out);這里也變成了字符流了。
?
??char[] buf = new char[1024];
int len = 0;
while((len=fr.read(buf))!=-1){
???osw.writer(buf,o.len);?? //將數據寫到目的了(buf),即控制體。
}
?
為了提高效率,加入緩沖技術。
BufferedReader buf = new BufferReader(newFileReader(“a.txt”));
BufferedWriter bufw = newBufferedWriter(new OutputStreamWriter(“b.txt”));
?
String line = null;
While((lien=bufr.readLine())!=null){
?????? bufw.write(line);
?????? bufw.newLine();
?????? bufw.flush();
}
?
?
需求三,將錄入的文件寫入硬盤上的文件。
1,明確體系;
源:InputStream。????System.in
目的:硬盤文件? OutputStream,Writer。
2,?明確純文本。
因為鍵盤錄入的都是字節數據。但是該數據最終得轉化成為純文本。
所以可以使用字符流。
源:Reader
目的:Writer。
3,?明確體系對象
源:因為鍵盤錄入,對應的對象是System.in,是一個字節讀取流。
為了可以使用字符讀取留來操作這些數據,可以將其轉換成字符讀取流
?
目的:因為是一個文本文件,所以可以使用FileWriter。
InputStreamReaderisr = new InputStreamReader(System.in);
?
FileWriter fw =new FileWriter(“a.txt”);
?
?? 為了提高效率,加入了緩沖技術
?
Bufferreader bufr = new BufferedReader(newInputStreamReader(System,in));
BufferedWriter bufw = newBufferedWriter(new FileWriter(“a.txt”));
?
需求四:讀取鍵盤錄入,將錄入的信息打印在控制臺上,
1體系:
源:InputStream? Reader
目的:OutputStream,Writer
2純文本:是
源:Reader
目的:Writer
4,?對象:
源:System.in
目的:System.out
因為鍵盤錄入都是純文本,所以用字符流操作很方便。
那么就將源和目的都轉換成字符流
InputStreamReader isr = newInputStreamReader(System.in);
?
OutputStreamWriter osw = newOutputStreamWriter(System.out);
?
需要高效
BufferedReader bufr = newBufferedReader(new InputStreamReaderl(System,in));
BufferedWriter bufw = newBufferedWriter(new OutputStreamWriter(System.out));
?
注意:在使用寫入緩沖區時,記得要進行刷新。flush().
?
?
?
需求五:將一個文本文件中的數據存儲到另一個文本文件中,要求按照UTF-8的編碼形式存儲
1,?體系
源InputStream or Reader
目的:OutputStream or Writer
2,純文本?yes
源:Reader
目的:Writer
3,對象:
因為操作是文本,而且沒有指定編碼。所以可以按照默認編碼形式
。那么就可以使用FileReader
目的:
按照一般思想,會去找FileWriter。但是FileWriter使用的默認編碼。
而需求中要求按照指定編碼UTF-8形式存儲
那么這時就要用到轉換流,因為只有轉換流可以在初始化是指定編碼。
?
目的也是一個文件。那么就明確要使用的對象是FileOutStream。
?
FileReader fr =new FileReader(“a.txt”);
OutlputStreamWriterosw = new OutputStream(new FileOutputStream(“b.txt”),”UTF-8”);
需要提高效率
BufferedReaderbufr = new BufferedReader(new FileReader(a.txt));
???
???BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(newFileOutputStream(“b.txt”),”UTF-8”));
?
package toto.IO;
?
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
?
public class TransStreamDemo {
?
?????? /**
?????? ?* @param args
?????? ?*/
?????? publicstatic void main(String[] args)throws IOException {
????????????? //writeText();
????????????? readText();
?????? }
?????? publicstatic void readAndWrite()throws IOException{
????????????? FileReaderfr = new FileReader("test.txt");//字符流
????????????? //FileWriterfw = new FileWriter("test1.txt");//默認的字符集。
????????????? OutputStreamWriterosw = new OutputStreamWriter(new
??????????????????????????? FileOutputStream("text1.txt"),"utf-8");//字符流
?????????????
????????????? char[] buf = new char[1024];
????????????? intlen = 0;
????????????? while((len=fr.read(buf))!=-1){
???????????????????? osw.write(buf,0,len);
????????????? }
????????????? osw.close();
????????????? fr.close();
?????? }
?????? publicstatic void readText() throws IOException{
????????????? FileReaderfr = new FileReader("test.txt");//這種編碼默認是gbk
????????????? intch = fr.read();
????????????? System.out.println((char)ch);
?????????????
????????????? intch1 = fr.read();
????????????? System.out.println((char)ch1);
????????????? fr.close();
?????? }
?????? publicstatic void writeText() throws IOException{
????????????? FileWriterfw = new FileWriter("test.txt");
????????????? fw.write("你好");
????????????? fw.close();
?????? }
?
}
?
讀取一個UTF-8編碼的文件。
BufferedReader bufr =
New BufferedReader(new FileInputStream(“text.txt”,”utf-8”) )
?
或通過:
InputStreamReaderisr = new InputStreamReader(new FileInputStream(“text.txt”,”utf-8”));
?
char[] buf = new char[1024];
?
………………
?
?
總結
以上是生活随笔為你收集整理的最全的IO操作知识总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java中的反射的应用
- 下一篇: 1千的轮胎气压多少?