字節流
操作圖片數據就要用到字節流。
字符流使用的是字符數組char[],字節流使用的是字節數組byte[]。字節流讀寫文件
針對文件的讀寫,JDK專門提供了兩個類,分別是FileInputStream和FileOutputStream。
FileInputStream是InputStream的子類,它是操作文件的字節輸入流,專門用於讀取文件中的數據
FileOutputStream,它是OutputStream的子類,專門用於讀取文件中的數據如果是通過FileOutputStream向一個已經存在的文件中寫入數據,那么該文件中的數據首先會被清空,再寫入新的數據。
若希望在存在的文件內容之后追加新內容,則可使用FileOutputStream的構造函數FileOutputStream(String fileName, boolean append)來創建文件輸出流對象,並把append 參數的值設置為true
FileInputStream 讀FileOutputstream 寫
讀取
FileInputStream fis=new FileInputStream ("a.txt");byte[] buf=new byte[fis].available(0)]; //定義一個剛剛好的緩沖區,不用再循環了
fis.read(buf);
System.out.println(new String(buf));
fis.close();字節文件輸入流FIleInputStream
該類的構造方法
FileInputStream(File file) 通過file對象創建類FileInputStream(FileDescriptor fdObj) 參數fdObj為文件描述符,通過文件描述符創建類
FileInputStream(String name) 參數name為文件路徑名,通過文件路徑創建類方法
int available() 返回可以從該文件輸入流中讀取的字節數void close() 關閉文件輸入流,同時釋放系統資源
protected void finalize() 確認文件輸入流不在被引用的狀態,並可以調用close方法java.io.channels.FileChannel getChannel() 返回與該文件輸入流有關的FileChannel對象
FileDescriptor getFD() 返回連接到文件系統(正被該FileInputStream使用)中實際文件的FileDescriptor對象int read() 從該輸入流中讀取一個數據字節,並以int類型返回
int read(byte[] b) 讀取輸入流中b.length個字節的數據,並存入字節數組b中int read(byte[] b, int off, int len) 讀取輸入流中從偏移量off開始的len個字節的數據,並存入字節數組b中
long skip(long n) 跳過輸入流中的數據,同時丟棄n個字節的數據字節文件輸出流FileOutputStream
構造方法
FileOutputStream(File file) 通過file對象創建FileOutputSteam
FileOutputStream(File file, boolean append) 通過file對象創建類,append為true或false表示是否在文件末尾追加
FileOutputStream(FileDescriptor fdObj) 參數fdObj為文件描述符,通過文件描述符創建FileOutputStreamFileOutputStream(String name) 參數name為文件路徑名,通過文件路徑創建FileOutputStream
FileOutputStream(String name, boolean append) 參數name為文件路徑名,通過文件路徑創建FileOutputStream, append為true或false表示是否在文件末尾追加
方法
void close() 關閉該文件輸出流,同時釋放系統資源
protected void finalize() 斷開到文件的連接,確認該文件輸出流不處在被引用狀態,並可以調用close方法
FileDescriptor getFD() 返回與該流有關的文件描述符FileDescriptor對象void write(byte[] b) 將b.length個字節的數據從指定字節數組寫入到該文件輸出流中
void write(byte[] b, int off, int len) 將指定字節數組中的部分數據(從偏移量off開始的len個字節)寫入到該文件輸出流void write(int b) 將指定字節b寫入到該文件輸出流
輸入流過濾器FilterInputStream
過濾流提供了在讀寫數據的同時可以對數據進行處理的功能,同時還提供了同步機制,使得某一時刻只有一個線程可以訪問一個數據流,以防止多個線程同時對一個數據流進行操作所帶來的意想不到的結果。為了使用一個過濾流,必須首先把過濾流連接到某個輸入輸出流上,通常通過在構造方法的參數中指定所要連接的輸入輸出流來實現。
構造方法
FilterInputStream(InputStream in); 指定InputStream輸入流方法
public int available() 該方法用於返回可以該輸入流中讀取的字節數public void close() 該方法用於關閉輸入流,並釋放系統資源
public void mark(int readlimit) 該方法用於標記輸入流中的當前位置public boolean markSupported() 該方法用於測試該輸入流是否支持mark和reset方法
public int read() 該方法用於從輸入流中讀取一個數據字節
public int read(byte[] b) 該方法用於從輸入流中讀取byte.length個字節的數據並存入到一個字節數組b中public int read(byte[] b,int off,int len) 該方法用於從輸入流中讀取從偏移量off開始len個字節的數據並存入到一個字節數組b中
public void reset() 該方法用於將流重新定位到對該輸入流最后一次調用mark方法時的位置
public long skip(long n) 該方法用於跳過輸入流中n個字節的數據,並丟棄文件的拷貝
文件的拷貝就需要通過輸入流來讀取文件中的數據,通過輸出流將數據寫入文件。
練習:復制圖片
FileOutputStream fw=null;
FileInputStream fr=null;
try {
fos=new FileOutputStream("b.jpg");
fis=new FileInputStream("a.jpg");
byte[] buf=new byte[1024];
int num=0;
while ((num=fis.read(buf))!=-1) {
fis.write(buf,0,num);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(fis!=null)
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
字節流的緩沖區
在IO包中提供兩個帶緩沖的字節流,分別是BufferedInputStream和BufferdOutputStream,這兩個流都使用了裝飾設計模式。它們的構造方法中分別接收InputStream和OutputStream類型的參數作為被包裝對象,在讀寫數據時提供緩沖功能。
為了提高效率也可以定義一個字節數組作為緩沖去。在拷貝文件時,可以一次性讀取多個字節的數據,並保存在字節數組中,然后將字節數組中的數據一次性寫入文件
字節緩沖區輸入流BufferedInputStream
是InputStream類的間接子類,其直接父類是FilterInputStream。
構造方法
BufferedInputStream(InputStream in) 以InputStream對象in為參數創建類
BufferedInputStream(InputStream in, int size) 以InputStream對象in為參數創建類,並且通過參數size指定緩存區大小方法
public int available() 該方法用於返回還可以從輸入流中讀取的字節數public void close() 該方法用於關閉輸入流,並釋放系統資源
public void mark(int readlimit) 該方法用於標記輸入流中的當前位置public boolean markSupported() 該方法用於測試輸入流是否支持mark和reset方法
public int read() 該方法用於從輸入流中讀取下一個數據字節
public int read(byte[] b,int off,int len) 讀取字節輸入流中的從偏移量off開始的len個字節並存入到指定的byte數組b中
public void reset() 將此流重新定位到最后一次調用mark方法時所處的位置
public long skip(long n) 跳過並且放棄輸入流中的n個字節數據字節緩沖區輸出流BufferedOutputStream
是OutputStream類的間接子類,其直接父類是FilterOutputStream。構造方法
BufferedOutputStream(OutputStream out) 以InputStream對象in為參數創建類
BufferedOutputStream(OutputStream out, int size) 以OutputStream對象out為參數創建類,並且通過size指定緩存區大小方法
public void flush() 該方法用於刷新輸出流
public void write(byte[] b,int off,int len) 將字節數組中從偏移量off開始的len個字節寫入到輸出流public void write(int b) 將指定的字節b寫入到輸出流
flush()方法用於強制將緩沖區的內容立即寫入輸出流。在使用緩存區機制的輸出流時,調用write()方法后數據並沒有立即寫入輸出流,而是先放到緩存區中。所以,在必要的地方可以調用flush()方法強制刷新緩沖區。
InputStream類的方法
public abstract int read() 從輸入流讀取下一個數據字節。如果因已到達流末尾而沒有可用的字節,則返回值-1public int available() 以不受阻塞地從輸入流中讀取字節。該方法返回讀取字節數
public void mark(int readlimit) 在此輸入流中標記當前的位置public boolean markSupported() 判斷輸入流是否支持mark()和reset()方法。如果支持則返回true。
public int read(byte[] b) 從輸入流中讀取一定數量的字節並將其存儲在緩沖區數組b中。該方法返回讀入緩沖區的總字節數
public int read(byte[] b,int off,int len) 從off處開始讀取流中len長度的字節並將其存儲在數組b中。返回讀取到的字節數public void reset() 將此流重新定位到輸入流最后調用mark方法時的位置
public long skip(long n) 跳過此輸入流中的n個字節。參數n表示要跳過的字節數。該方法返回實際跳過的字節數public void close() 關閉輸入流
OutputStream類的方法
public void writer (byte[] b) 將字節數組寫入輸出流
public void writer (byte[] b, int off, int len) 將指定字節數組b中以off開始的len個字節寫入輸出流public void flush() 刷新輸出流
public void close() 關閉輸出流裝飾設計模式
當想要對已有的獨享進行功能增強時,可以定義類,將已有的對象傳入,基於已經有的功能,並提供加強功能,那么自定義的該類稱為裝飾類
裝飾類通常會通過構造方法接收被裝飾的對象,並基於被裝飾的對象的功能,提供更強的功能。
已知類:
Person() {
public void chifan() {
}
}
增強類:
superPerson() {
private Person p;
superPerson(Person p) {
this.p=p;
}
public void superchifan() {
p.chifan();
.........
{
}
自定義裝飾類
package com.io;
import java.io.*;
public class MyBufferedReader {
private Reader r;
public MyBufferedReader(Reader r) {
super();
this.r = r;
}
//可以一次讀取一行的方法
public String myReadLine() throws IOException {
//定義一個臨時容器。StringBulider容器,應用於存儲字符數組
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;
}
//復寫reader中的抽象方法
//復寫close方法
public void close() throws IOException {
r.close();
}
//復寫read方法
public int read (char[] c,int off,int len) throws IOException {
return r.read(c, off, len);
}
}
裝飾設計模式就是通過包裝一個類,動態地為它增加功能的一種設計模式。
