------- android培訓、java培訓、期待與您交流! ----------
字符流的緩衝區
1、緩衝區的出現提高了對數據的讀寫效率。
2、對應類:BufferedWriter BufferedReader
3、緩衝區要結合流纔可以使用。
4、在流的基礎上對流的功能進行了增強。
/*字符流的緩衝區
緩衝區的出現是爲了提高流的操作效率而出現的。所以在創建緩衝區之前,必須要先有流對象。
該緩衝區中提供了一個跨平臺的換行符。newLine();
*/
import java.IO.*;
class BufferedWriterDemo
{
public static void main(String[] args)throws IOException
{
//創建一個字符寫入流對象
FileWriter fw=new FileWriter("buf.txt");
//爲了提高字符寫入流效率。加入緩衝技術。
//只要將需要被提高效率的流對象作爲參數傳遞給緩衝區的構造函數即可。
BufferedWriter bufw=new BufferedWriter(fw);
for(int x=1;x<5;x++)
{
bufw.write("abcd"+x);
bufw.newLine();
bufw.flush();
}
//記住,只要用到緩衝區,就要記得刷新。
//bufw.flush();
//其實關閉緩衝區,就是在關閉緩衝區中的流對象
bufw.close();
}
}
/*字符讀取流緩衝區
該緩衝區提供了一個一次讀一行的方法readLine,方便於對文本數據的獲取
當返回null時,表示獨到文件末尾。
readLine方法返回的時候只返回回車符之前的數據內容。並不返回回車符。
*/
import java.IO.*;
class BufferedReaderDemo
{
public static void main(String[] args)
{
//創建一個讀取流對象和文件相關聯。
FileReader fr=new FileReader("demo.txt");
//爲了提高效率。加入緩衝技術。將字符讀取流對象作爲參數傳遞給緩衝對象的構造函數。
BufferedReader bufr=new BufferedReader(fr);
String line=null;
while((line=bufr.readLine())!=null)
{
System.out.println(line);
}
bufr.close();
}
}
/*
通過緩衝區複製一個.java文件
*/
import java.IO.*;
class CopyTextByBuf
{
public static void main(String[] args)
{
BufferedReader bufr=null;
BufferedWriter bufw=null;
try{
bufr=new BufferedReader(new FileReader("demo.txt"));
bufw=new BufferedWriter(new FileWriter("demo_copy.txt"));
String line=null;
while((line=bufr.readLine)!=null){
bufw.write(line);
bufw.newLine();
bufw.flush();
}
}catch(IOException e){
throw new RuntimeException("讀寫失敗!");
}finally{
try{
if(bufr!=null)
bufr.close();
}catch(IOException e){
throw new RuntimeException("讀取關閉失敗!");
}
try{
if(bufw!=null)
bufw.close();
}
catch(IOException e){
throw new RuntimeException("寫入關閉失敗!");
}
}
}
}
readLine方法的原理:無論是讀一行,或者讀取多個字符。其實最終都是在硬盤上一個一個讀取。所以最終使用的還是
read方法一次讀一個的方法。
模擬緩衝區的特點:
/*
明白了BufferedReader類中特有方法readLine的原理後,可以自定義一個類中包含一個功能和
readLine一致的方法。來模擬一下BufferedReader
*/
import java.IO.*;
class MyBufferedReader{
private FileReader r;
MyBufferedReader(FileReader r){
this.r=r;
}
//可以一次讀一行數據的方法
public String myReadLine()throws IOException {
//定義一個臨時容器。原BufferedReader封裝的是字符數組。
//爲了演示方便。定義一個StringBuilder容器。因爲最終還是要講數據變成字符串。
StringBuilder sb=new StringBuilder();
int ch=0;
while((ch=r.read())!=-1){
if(ch=='\r')
continue;
if(ch=='\n')
return sb.toString();
else
sb.append((char)ch);
}
if(sb.length()!=0)
return sb.toString();
return null;
}
public void myClose()throws IOException
{
r.close();
}
}
class MyBufferedReaderDemo
{
public static void main(String[] args)
{
FileReader fr=new FileReader("buf.txt");
MyBufferedReader myBuf=new MyBufferedReader(fr);
String line=null;
while((line=myBuf.myReadLine())!=null){
System.out.printlm(line);
}
myBuf.myClose();
}
}
裝飾設計模式:
當想要對已有的對象進行功能增強時,可以定義類,將已有對象傳入,基於已有的功能
並提供加強功能。那麼自定義的該類稱爲裝飾類。
裝飾類通常會通過構造方法接收被裝飾的對象。並基於被裝飾的對象的功能提供更強的功能
裝飾模式比繼承要靈活,避免了繼承體系的臃腫,而且降低了類與類之間的關係。
裝飾類因爲增強已有對象,具備的功能和已有的是相同的,只不過提供了更強功能
所以裝飾類和被裝飾類通常都是屬於一個體系的。
字符流:FileReader FileWriter BufferedReader BufferedWriter
字節流:InputStream(讀) OutputStream(寫)
import java.IO.*;
class FileStream
{
public static void main(String[] args)
{
writeFile();
}
public static void readFile()_3
{
FileInputStream fis=new FileInputStream("fos.txt");
/* //available()獲取的是字節的個數。
int num=fis.available();
System.out.println("num"+num);
*/
byte[] buf=new byte[fis.available()];//定義一個剛剛好緩衝區。不用再循環了
fis.read(buf);
System.out.println(new String(buf));
fis.close();
}
public static void readFile()_2
{
FileInputStream fis=new FileInputStream("fos.txt");
byte[] buf=new byte[1024];
int len=0;
while((len=fis.read(buf))!=-1)
{
System.out.println(new String(buf,0,len));
}
fis.close();
}
public static void readFile()_1
{
FileInputStream fis=new FileInputStream("fos.txt");
int ch=0;
while((ch=fis.read())!=-1)
{
System.out.println("ch="+(char)ch);
}
fis.close();
}
public static void writeFile()
{
FileOutputStream fos=new FileOutputStream("fos.txt");
fos.write("abcd".getBytes());
//關閉流資源必須寫
fos.close();
}
}
/*
複製一個圖片
思路:
1、用字節獲取流對象和圖片關聯
2、用字節寫入流對象創建一個圖片文件。用於存儲獲取到的圖片數據。
3、通過循環讀寫,完成數據的存儲。
4、關閉流資源
*/
import java.IO.*;
class CopyPic
{
public static void main(String[] args)
{
FileOutputStream fos=null;
FileInputStream fis=null;
try
{
fos=new FileOutputStream("c:\\2.bmp");
fis=new FileInputStream("C:\\1.bmp");
byte[]buf=new byte[1024];
int len=0;
while((len=fis.read(buf))!=-1){
fos.write(buf,0,len);
}
}
catch (IOException e)
{
throw new RuntimeException("複製文件失敗");
}finally{
try
{
if(fis!=null)
fis.close();
}
catch (IOException e)
{
throw new RuntimeException("讀取關閉失敗");
}
try
{
if(fos!=null)
fos.close();
}
catch (IOException e)
{
throw new RuntimeException("讀取關閉失敗");
}
}
}
}
/*
字符流:FileReader FileWriter BufferedReader BufferedWriter
字節流:FileInputStream FileOutputStream BufferedInputStream BufferedOutputStream
*/
/*
讀取鍵盤錄入
System.out:對應的是標準的輸出設備,控進臺。
System.in:對應的標準輸入設備:鍵盤。
需求:
通過鍵盤錄入數據。
當錄入一行數據後,就將改行數據進行打印。
如果錄入的數據是over ,那麼停止錄入。
*/
import java.IO.*;
class ReadIn
{
public static void main(String[] args)
{
InputStream in=System.in;
StringBuilder sb=new StringBuilder();
while(true)
{
int ch=in.read();
if(ch=='\r')
continue;
if(ch=='\n')
{
String s=sb.toString();
if("over".equals(s))
break;
System.out.println(s.toUpperCase());
sb.delete(0,sb.length());
}
else
sb.append((char)ch);
}
}
}
/*
通過剛纔的鍵盤錄入一行數據並打印其大寫,發現其實就是讀一行數據的原理。也就是readLine方法
能不能直接使用readLine方法來完成鍵盤錄入的一行數據的讀取呢?
readLine方法是字符流BuffeedReader類中的方法。
而鍵盤錄入的read方法是字節流InputStreamReader的方法。那麼能不能講字節流轉成字符流在使用字符流緩衝區的readLine方法呢?
*/
import jav.IO.*;
class transStreamDemo
{
public static void main(String[] args)
{
//獲取鍵盤錄入對象。
InputStreamReader in=System.in;
//將字節流對象轉成字符流對象,使用轉換流。InputStreamReader
InputStream isr =new InputStreamReader(in);
//爲了提高效率,將字符串進行緩衝區高效操作。使用BufferedReader
BufferedReader bufr=new BuffferedReader(isr);
String line=null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
System.out.println(line.toUpperCase());
}
bufr.close();
}
}
InputStreamReader是字節通向字符的橋樑。
OutputStreamWriter是字符通向字節的橋樑。
import jav.IO.*;
class transStreamDemo
{
public static void main(String[] args)
{
//獲取鍵盤錄入對象。
//InputStreamReader in=System.in;
//將字節流對象轉成字符流對象,使用轉換流。InputStreamReader
//InputStream isr =new InputStreamReader(in);
//爲了提高效率,將字符串進行緩衝區高效操作。使用BufferedReader
//BufferedReader bufr=new BuffferedReader(isr);
//鍵盤錄入的最常見寫法。
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
// OutputStream out=System.out;
//OutputStreamWriter osw=new OutputStreamWriter(out);
//BufferedReader bufw=new BufferedRader(osw);
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out));
String line=null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
//System.out.println(line.toUpperCase());
osw.write(line.toUpperCase());
osw.flush();
}
bufr.close();
}
}
流操作的基本規律:最痛苦的就是流對象有很多不知道該用哪一個。
通過三個明確來完成。
1、明確源和目的。源:輸入流。InputStream Reader
目的:輸出流:OutputStream Writer
2、操作的數據是否是純文本。
是:字符流 不是:字節流
3、檔體系明確後在明確要使用那個具體的對象。通過設備來進行區分:源設備:內存硬盤。鍵盤
目的設備:內存 硬盤 控制檯。
需求1、將一個文件中的數據存儲到另一個文件中。複製文件。
源:因爲是源,所以要使用讀取流。InputStream Reader
是不是操作文本文件。是!這是就可以選擇Reader這樣體系就明確了。
接下來明確要使用該體系中的那個對象。明確設備:硬盤上的一個文件。
Reader體系中可以操作文件的對象是FileReader
是否需要提高效率?是!加入Reader體系中緩衝區BufferedReader.
FileReader fr=new FileReader("a.txt");
BufferedReader bufr=new BufferedReader(fr);
目的:OutputStream Writer 是否是純文本?是!Writer
設備:硬盤上一個文件。
Writer體系中可以操作文件的對象FileWriter。
是否提高效率:是!加入Writer體系中緩衝區BufferedWriter
FileWriter fw=new FileWriter("b.txt");
BufferedWriter bufw=new BufferedWriter(fw);
需求2、將鍵盤錄入的數據保存到一個文件中,這個需求中有源和目的都存在,那麼分別分析
源:InputStream Reader 是不是純文本?是!Reader
設備:鍵盤,對應的對象是System.in 不是選擇Reader嗎?System.in對應的不是字節流嗎?爲了操作鍵盤的文本數據方便,
轉換成字符流按照字符串操作是最方便的。所以既然明確了Reader,那麼就將System.in轉換成Reader,用了
Reader體系中轉換流InputStreamReader
InputStreamReader isr=new InputStreamRader(isr);
目的:OutputStream Writer
是否是純文本?是!Writer
設備:硬盤。一個文件使用FileWriter。
FileWriter fw=new FileWriter ("c.txt");
需要提高效率嗎?需要
BufferedWriter bufw=new BufferedWriter(fw);
************************************************************
擴展一下想要把錄入的數據按照指定的編碼表(UTF-8),將數據存到文件中。
目的:OutputStream Writer
是否是純文本?是!Writer。
設備:硬盤上的一個文件使用FileWriter但是FileWriter是使用的默認編碼表。GBK
但是存儲時,需要加入指定編碼表UTF-8。而指定的編碼表只有轉換流可以指定。所以要使用的對象是OutputStreamWriter。而該轉換流對象要接受一個字節輸出流。而且還可以操作的文件的字節輸出流。FileOutputStream
OutputStreamWriter osw =new OutputStreamWriter(osw);
所以記住。轉換流什麼時候使用?字符和字節之間的橋樑通常,涉及到字符編碼轉換時,需要用到轉換流。
class TransStreamDemo2
{
public static void main(String[] args)
{
//鍵盤的最常見寫法
BufferedReader bufr=new BufferedWriter(new InputStreamReader(System.in));
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("d2.txt"),"UTF-8"));
String line=null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
bufr.close();
}
}
------- android培訓、java培訓、期待與您交流! ----------