图片流写出 并带数据_第九章 IO流
1. 輸入流和輸出流聯(lián)系和區(qū)別,節(jié)點(diǎn)流和處理流聯(lián)系和區(qū)別
首先,你要明白什么是“流”。直觀地講,流就像管道一樣,在程序和文件之間,輸入輸出的方向是針對程序而言,向程序中讀入東西,就是輸入流,從程序中向外讀東西,就是輸出流。輸入流是得到數(shù)據(jù),輸出流是輸出數(shù)據(jù)。
而節(jié)點(diǎn)流,處理流是流的另一種劃分,按照功能不同進(jìn)行的劃分。節(jié)點(diǎn)流,可以從或向一個(gè)特定的地方(節(jié)點(diǎn))讀寫數(shù)據(jù)。處理流是對一個(gè)已存在的流的連接和封裝,通過所封裝的流的功能調(diào)用實(shí)現(xiàn)數(shù)據(jù)讀寫。如BufferedReader。處理流的構(gòu)造方法總是要帶一個(gè)其他的流對象做參數(shù)。一個(gè)流對象經(jīng)過其他流的多次包裝,稱為流的鏈接。
2. 字符流字節(jié)流聯(lián)系區(qū)別;什么時(shí)候使用字節(jié)流和字符流?
字符流和字節(jié)流是流的一種劃分,按處理照流的數(shù)據(jù)單位進(jìn)行的劃分。兩類都分為輸入和輸出操作。在字節(jié)流中輸出數(shù)據(jù)主要是使用OutputStream完成,輸入使的是InputStream,在字符流中輸出主要是使用Writer類完成,輸入流主要使用Reader類完成。這四個(gè)都是抽象類。字符流處理的單元為2個(gè)字節(jié)的Unicode字符,分別操作字符、字符數(shù)組或字符串,而字節(jié)流處理單元為1個(gè)字節(jié),操作字節(jié)和字節(jié)數(shù)組。字節(jié)流是最基本的,所有的InputStrem和OutputStream的子類都是,主要用在處理二進(jìn)制數(shù)據(jù),它是按字節(jié)來處理的 但實(shí)際中很多的數(shù)據(jù)是文本,又提出了字符流的概念,它是按虛擬機(jī)的編碼來處理,也就是要進(jìn)行字符集的轉(zhuǎn)化 這兩個(gè)之間通過 InputStreamReader,OutputStreamWriter來關(guān)聯(lián),實(shí)際上是通過byte[]和String來關(guān)聯(lián)的。
3. 列舉常用字節(jié)輸入流和輸出流并說明其特點(diǎn),至少5對。
FileInputStream 從文件系統(tǒng)中的某個(gè)文件中獲得輸入字節(jié)。
ByteArrayInputStream 包含一個(gè)內(nèi)部緩沖區(qū),該緩沖區(qū)包含從流中讀取的字節(jié)。內(nèi)部計(jì)數(shù)器跟蹤 read 方法要提供的下一個(gè)字節(jié)。
FilterInputStream 包含其他一些輸入流,它將這些流用作其基本數(shù)據(jù)源,它可以直接傳輸數(shù)據(jù)或提供一些額外的功能。FilterInputStream 類本身只是簡單地重寫那些將所有請求傳遞給所包含輸入流的 InputStream 的所有方法。FilterInputStream 的子類可進(jìn)一步重寫這些方法中的一些方法,并且還可以提供一些額外的方法和字段。
ObjectInputStream 對以前使用 ObjectOutputStream 寫入的基本數(shù)據(jù)和對象進(jìn)行反序列化。
ObjectOutputStream 和 ObjectInputStream 分別與 FileOutputStream 和 FileInputStream 一起使用時(shí),可以為應(yīng)用程序提供對對象圖形的持久存儲(chǔ)。ObjectInputStream 用于恢復(fù)那些以前序列化的對象。其他用途包括使用套接字流在主機(jī)之間傳遞對象,或者用于編組和解組遠(yuǎn)程通信系統(tǒng)中的實(shí)參和形參。
StringBufferInputStream此類允許應(yīng)用程序創(chuàng)建輸入流,在該流中讀取的字節(jié)由字符串內(nèi)容提供。應(yīng)用程序還可以使用ByteArrayInputStream 從 byte 數(shù)組中讀取字節(jié)。 只有字符串中每個(gè)字符的低八位可以由此類使用。
ByteArrayOutputStream此類實(shí)現(xiàn)了一個(gè)輸出流,其中的數(shù)據(jù)被寫入一個(gè) byte 數(shù)組。緩沖區(qū)會(huì)隨著數(shù)據(jù)的不斷寫入而自動(dòng)增長。可使用 toByteArray() 和 toString() 獲取數(shù)據(jù)。
FileOutputStream文件輸出流是用于將數(shù)據(jù)寫入 File 或 FileDescriptor 的輸出流。文件是否可用或能否可以被創(chuàng)建取決于基礎(chǔ)平臺(tái)。特別是某些平臺(tái)一次只允許一個(gè) FileOutputStream(或其他文件寫入對象)打開文件進(jìn)行寫入。在這種情況下,如果所涉及的文件已經(jīng)打開,則此類中的構(gòu)造方法將失敗。
FilterOutputStream類是過濾輸出流的所有類的超類。這些流位于已存在的輸出流(基礎(chǔ) 輸出流)之上,它們將已存在的輸出流作為其基本數(shù)據(jù)接收器,但可能直接傳輸數(shù)據(jù)或提供一些額外的功能。 FilterOutputStream 類本身只是簡單地重寫那些將所有請求傳遞給所包含輸出流的 OutputStream 的所有方法。FilterOutputStream 的子類可進(jìn)一步地重寫這些方法中的一些方法,并且還可以提供一些額外的方法和字段。
ObjectOutputStream 將 Java 對象的基本數(shù)據(jù)類型和圖形寫入 OutputStream。可以使用 ObjectInputStream 讀取(重構(gòu))對象。通過在流中使用文件可以實(shí)現(xiàn)對象的持久存儲(chǔ)。如果流是網(wǎng)絡(luò)套接字流,則可以在另一臺(tái)主機(jī)上或另一個(gè)進(jìn)程中重構(gòu)對象。
PipedOutputStream可以將管道輸出流連接到管道輸入流來創(chuàng)建通信管道。管道輸出流是管道的發(fā)送端。通常,數(shù)據(jù)由某個(gè)線程寫入 PipedOutputStream 對象,并由其他線程從連接的 PipedInputStream 讀取。不建議對這兩個(gè)對象嘗試使用單個(gè)線程,因?yàn)檫@樣可能會(huì)造成該線程死鎖。如果某個(gè)線程正從連接的管道輸入流中讀取數(shù)據(jù)字節(jié),但該線程不再處于活動(dòng)狀態(tài),則該管道被視為處于毀壞狀態(tài)。
4. 說明緩沖流的優(yōu)點(diǎn)和原理
不帶緩沖的流的工作原理:它讀取到一個(gè)字節(jié)/字符,就向用戶指定的路徑寫出去,讀一個(gè)寫一個(gè),所以就慢了。帶緩沖的流的工作原理:讀取到一個(gè)字節(jié)/字符,先不輸出,等湊足了緩沖的最大容量后一次性寫出去,從而提高了工作效率
優(yōu)點(diǎn):減少對硬盤的讀取次數(shù),降低對硬盤的損耗。
5. 序列化的定義、實(shí)現(xiàn)和注意事項(xiàng)
想把一個(gè)對象寫在硬盤上或者網(wǎng)絡(luò)上,對其進(jìn)行序列化,把他序列化成為一個(gè)字節(jié)流。
實(shí)現(xiàn)和注意事項(xiàng):
1) 實(shí)現(xiàn)接口Serializable Serializable接口中沒有任何的方法,實(shí)現(xiàn)該接口的類不需要實(shí)現(xiàn)額外的方法。
2) 如果對象中的某個(gè)屬性是對象類型,必須也實(shí)現(xiàn)Serializable接口才可以
3) 序列化對靜態(tài)變量無效
4) 如果不希望某個(gè)屬性參與序列化,不是將其static,而是transient
5) 串行化保存的只是變量的值,對于變量的任何修飾符,都不能保存
6) 序列化版本不兼容
6. 使用IO流完成文件夾復(fù)制(結(jié)合遞歸)
import java.io.*;
/**
* CopyDocJob定義了實(shí)際執(zhí)行的任務(wù),即
* 從源目錄拷貝文件到目標(biāo)目錄
*/
public class CopyDir2 {
public static void main(String[] args) {
try {
copyDirectiory("d:/301sxt","d:/301sxt2");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 復(fù)制單個(gè)文件
* @param sourceFile 源文件
* @param targetFile 目標(biāo)文件
* @throws IOException
*/
private static void copyFile(File sourceFile, File targetFile) throws IOException {
BufferedInputStream inBuff = null;
BufferedOutputStream outBuff = null;
try {
// 新建文件輸入流
inBuff = new BufferedInputStream(new FileInputStream(sourceFile));
// 新建文件輸出流
outBuff = new BufferedOutputStream(new FileOutputStream(targetFile));
// 緩沖數(shù)組
byte[] b = new byte[1024 * 5];
int len;
while ((len = inBuff.read(b)) != -1) {
outBuff.write(b, 0, len);
}
// 刷新此緩沖的輸出流
outBuff.flush();
} finally {
// 關(guān)閉流
if (inBuff != null)
inBuff.close();
if (outBuff != null)
outBuff.close();
}
}
/**
* 復(fù)制目錄
* @param sourceDir 源目錄
* @param targetDir 目標(biāo)目錄
* @throws IOException
*/
private static void copyDirectiory(String sourceDir, String targetDir) throws IOException {
// 檢查源目錄
File fSourceDir = new File(sourceDir);
if(!fSourceDir.exists() || !fSourceDir.isDirectory()){
return;
}
//檢查目標(biāo)目錄,如不存在則創(chuàng)建
File fTargetDir = new File(targetDir);
if(!fTargetDir.exists()){
fTargetDir.mkdirs();
}
// 遍歷源目錄下的文件或目錄
File[] file = fSourceDir.listFiles();
for (int i = 0; i < file.length; i++) {
if (file[i].isFile()) {
// 源文件
File sourceFile = file[i];
// 目標(biāo)文件
File targetFile = new File(fTargetDir, file[i].getName());
copyFile(sourceFile, targetFile);
}
//遞歸復(fù)制子目錄
if (file[i].isDirectory()) {
// 準(zhǔn)備復(fù)制的源文件夾
String subSourceDir = sourceDir + File.separator + file[i].getName();
// 準(zhǔn)備復(fù)制的目標(biāo)文件夾
String subTargetDir = targetDir + File.separator + file[i].getName();
// 復(fù)制子目錄
copyDirectiory(subSourceDir, subTargetDir);
}
}
}
}
總結(jié)
以上是生活随笔為你收集整理的图片流写出 并带数据_第九章 IO流的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python中的sys模块和os_pyt
- 下一篇: 日常小技巧之电脑之间传输文件电脑如何传输