IO流的綜述
**1.概念**
流:流動、流向,從一端移動到另一端,有源頭和目的地
程序 與 文件或數組或網絡連接或數據庫,以程序爲中心
**2.IO流分類**
a.流向:輸入流與輸出流
b.數據:字節流:二進制,可以處理一切文件,包括純文本、doc、音頻、視頻等等
字符流:文本文件,只能處理純文本
c.功能:節點流:包裹源頭(上圖中最後一個文件傳到程序中,靠近文件的)
處理流:增強功能,提供性能(靠近程序的)
**3.字節流與字符流(重點)與文件**
a.字節流
1)輸入流:InputStream 類FileInputStream
read(byte[] b)
從輸入流中讀取一定數量的字節,並將其存儲在緩衝區數組 b 中。
read(byte[] b, int off, int len)
將輸入流中最多 len 個數據字節讀入 byte 數組。
close()
關閉此輸入流並釋放與該流關聯的所有系統資源。
2)輸出流:OutputStream 類FileOutputStream
write(byte[] b)
將 b.length 個字節從指定的 byte 數組寫入此輸出流。
write(byte[] b, int off, int len)
將指定 byte 數組中從偏移量 off 開始的 len 個字節寫入此輸出流。
flush()
刷新此輸出流並強制寫出所有緩衝的輸出字節。
close()
關閉此輸出流並釋放與此流有關的所有系統資源。
b.字符流
1)輸入流:Reader 類FileReader
read(char[] cbuf)
將字符讀入數組。
read(char[] cbuf, int off, int len)
將字符讀入數組的某一部分。
close()
關閉該流並釋放與之關聯的所有資源
2)輸出流:Writer 類FileWriter
write(char[] cbuf)
寫入字符數組。
write(char[] cbuf, int off, int len)
寫入字符數組的某一部分。
flush()
刷新該流的緩衝。
close()
關閉此流,但要先刷新它。
write(String str, int off, int len)
寫入字符串的某一部分。
**4.操作**
a.舉例:搬家 -->>讀取文件
1)關聯房子 -->>建立與文件聯繫
2)選擇搬家公司 -->>選擇對應流
3)搬家 -->>讀取
a)卡車大小 -->>數組大小
b)運輸 -->>讀取
4)打發over -->>釋放資源
b.操作
1)建立聯繫
2)選擇流
3)操作 數組大小 + read
4)釋放資源
字節流
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
/**
* 文件的讀取
* 1.建立聯繫-> File對象(源頭)
* 2.選擇流-> 文件輸入流 InputStream FileInputStream
* 3.操作 : byte[] car =new byte[1024]; + read + 讀取大小
輸出
* 4.釋放資源 :關閉
* @author Administrator
*
*/
public class Demo01 {
public static void main(String[] args) {
//建立聯繫也就是創建File對象
File src = new File("D:/安裝包/aa/bb/a.txt");
//選擇流
InputStream io = null; //提升作用域
try {
io = new FileInputStream(src);
//操作,不斷讀取,緩衝數組
byte[] car = new byte[100];
int len = 0; //定義實際讀取的大小
//循環讀取,就是不斷的運輸貨物
while(-1!=(len=io.read(car))){
String str = new String(car, 0, len);
System.out.println(str);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("文件不存在");
} catch (IOException e) {
e.printStackTrace();
System.out.println("文件讀取失敗");
}finally{
try {
if (null != io) {
io.close();
}
} catch (Exception e2) {
System.out.println("關閉文件輸入流失敗");
}
}
}
}
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* 寫出文件
* 1.建立聯繫->File對象(目的地)
* 2.選擇流->文件輸出流 OutputStream FileOutputStream
* 3.操作 : write() +flush
* 4.釋放資源 :關閉
*
*/
public class Demo02 {
public static void main(String[] args) {
//1.建立聯繫->File對象(目的地)
File src = new File("D:/安裝包/aa/bb/a.txt");
OutputStream os = null;
//2.選擇流->文件輸出流 OutputStream FileOutputStream
try {
//下面false表示將字節寫入文件開始處,直接覆蓋原來的文件,
//true表示將字節寫入文件末尾處,在文件字節後面添加內容 ,默認爲false
os = new FileOutputStream(src,true);
int len = 0;
//3.操作 : write() +flush
String str = "上面說的都是對的!!\r\n";
byte b[] = str.getBytes();
os.write(b,0,b.length);
//這是強制刷出的意思,一般情況下,只有流慢了的時候纔會把內容刷出,
//或者最後close的時候也會自動刷出,但是最好自己實現刷出
os.flush();
} catch (FileNotFoundException e) {
System.out.println("其實就算沒有a.txt這個文件,還是會在文件夾中創建這樣一個文件");
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
//4.釋放資源 :關閉
if (null != os) {
os.close();
}
} catch (Exception e2) {
System.out.println("關閉輸出流文件失敗");
}
}
}
}
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* 3.文件和文件夾的拷貝,程序爲橋樑
a.建立聯繫:File對象 源頭和目的地
b.選擇流:文件輸入流 InputStream FileInputStream
文件輸出流 OutputStream FileOutputStream
c.操作:拷貝
byte[] flush = new byte[1024];
int len = 0;
while(-1 != (len = 輸入流.read(flush))){
輸出流.write(flush,0,len)
}
輸出流.flush
d.釋放資源:關閉兩個流
*/
public class FileUtils {
public static void main(String[] args) {
// String src = "D:/安裝包/aa/bb/a.txt";
// String dest = "D:/安裝包/aa/bb/cc/a3.txt";
// try {
// copyFile(src, dest);
// } catch (IOException e) {
// e.printStackTrace();
// }
System.out.println("===========測試拷貝文件夾===========");
String srcPath = "D:/安裝包/aa/bb/cc";
String destPath = "D:/安裝包/aa/bb/dd";
File src = new File(srcPath);
File dest = new File(destPath);
copyDir(srcPath, destPath);
}
//必須要有下面這個,如果沒有話,那麼拷貝的是文件夾裏面的內容,不會將文件夾拷貝出來
public static void copyDir(String srcPathName, String destDestName){
//1、建立聯繫,建立對象
File src = new File(srcPathName);
File dest = new File(destDestName);
if(src.isDirectory()){
dest = new File(destDestName,src.getName());
}
copyDirsonfile(src, dest);
}
public static void copyDirsonfile(File src, File dest){
if(src.isFile()){
try {
copyFile(src,dest);
} catch (IOException e) {
e.printStackTrace();
}
}else if(src.isDirectory()){
dest.mkdirs();
for(File temp:src.listFiles()){
copyDirsonfile(temp, new File(dest,temp.getName()));
}
}
}
public static void copyFile(File src, File dest) throws FileNotFoundException,IOException{
InputStream is = new FileInputStream(src);
OutputStream os = new FileOutputStream(dest);
int len = 0;
byte[] b = new byte[1024];
//3、處理,也就是讀取出來之後,寫入
while(-1!=(len=is.read(b))){
os.write(b, 0, len);
}
os.flush();
//4、關閉流,先打開的後關閉,後打開的先關閉
os.close();
is.close();
}
public static void copyFile(String srcPathName, String destDestName) throws FileNotFoundException,IOException{
//1、建立聯繫,建立對象
File src = new File(srcPathName);
File dest = new File(destDestName);
copyFile(src,dest);
}
}
但是上面的拷貝文件夾的程序還是有問題,正常情況下,文件夾不能拷貝到子文件夾中,但是現在程序的實現卻是可以的。所以需要對這裏出現的錯誤進行處理:解決:不能將父目錄拷貝到子目錄中(解決方法:程序中if(des.getAbsolutePath().contains(src.getAbsolutePath())))。
如下所示:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* 文件夾的拷貝
* 1.文件 賦值 copyFile()
* 2.文件夾 創建 mkdirs()
* 3.遞歸查找子孫級
*/
public class CopyFolder {
public static void main(String[] args) {
//源目錄
String srcPath = "G:/java/test/src";//如果寫錯爲文件,因不能建立與文件夾des同名的文件,所以會拋出異常
//目標目錄
String desPath = "G:/java/test/des";
if(srcPath.equals(desPath)){//拒絕自己拷貝給自己
System.out.println("拒絕自己拷貝給自己");
return;
}
File src = new File(srcPath);
File des = new File(desPath);
if(src.isDirectory()){//文件夾
des = new File(desPath,src.getName());
if(des.getAbsolutePath().contains(src.getAbsolutePath())){
System.out.println("父目錄不能拷貝到子目錄中");
return;
}
}
copyFolder(src,des);
}
/**
* 拷貝文件夾
* @param src
* @param des
*/
public static void copyFolder(File src,File des){
if(src.isFile()){//文件
try {
CopyFile.copyFile(src, des);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}else if(src.isDirectory()){//文件夾
//確保目標文件夾存在
des.mkdirs();
//獲取下一級目錄或文件
for(File sub : src.listFiles()){
copyFolder(sub,new File(des,sub.getName()));
}
}
}
}
字符流
字符流:只能處理純文本,全部爲可見字符 .txt .html
其中的節點流:Reader FileReader
Writer FileWriter
一、純文本讀取
1、建立聯繫
2、選擇流 Reader FileReader
3、讀取 char[] flush = new char[1024]
4、關閉
二、純文本寫出
1、建立聯繫
2、選擇流 Writer FileWriter
3、寫出 write(字符數組,0,長度) + flush
4、關閉
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
/**
* 一、純文本讀取
1、建立聯繫
2、選擇流 Reader FileReader
3、讀取 char[] flush = new char[1024]
4、關閉
*/
public class FileRead {
public static void main(String[] args) {
File src = new File("G:/JAVA/test/src/test.txt");
Reader charStreamR = null;
try {
charStreamR = new FileReader(src);
char[] flush = new char[10];
int len = 0;
while(-1 != (len=charStreamR.read(flush))){
System.out.print(new String(flush,0,len));
}
} catch (FileNotFoundException e){
e.printStackTrace();
System.out.println("文件不存在");
} catch (Exception e){
e.printStackTrace();
System.out.println("讀取文件失敗");
} finally {
try {
charStreamR.close();
} catch (IOException e) {
e.printStackTrace();
System.out.println("關閉文件輸入流失敗");
}
}
}
}
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
/**
* 二、純文本寫出
1、建立聯繫
2、選擇流 Writer FileWriter
3、寫出 write(字符數組,0,長度) + flush
4、關閉
*/
public class FileWrite {
public static void main(String[] args) {
File des = new File("G:/java/test/writed.txt");
String src = "牀前明月光,\r\n疑是地上霜,\r\n舉頭望明月,\r\n低頭思故鄉。\r\n";
Writer charStreamW = null;
try {
charStreamW = new FileWriter(des,true);
char[] flush = src.toCharArray();
charStreamW.write(flush,0,flush.length);
charStreamW.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("找不到指定路徑或拒絕訪問");//FileWriter:文件不存在會自動創建,但父路徑要存在;子路徑爲文件夾則拒絕訪問
} catch (IOException e) {
e.printStackTrace();
System.out.println("寫入文件失敗");
} finally {
try {
charStreamW.close();
} catch (IOException e) {
e.printStackTrace();
System.out.println("關閉流失敗");
}
}
}
}
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
/**
* 純文本文件的拷貝
*/
public class CopyFile {
public static void main(String[] args) {
File src = new File("G:/java/test/forcopy.txt");
File des = new File("G:/java/test/alreadycopy.txt");
Reader charStreamR = null;
Writer charStreamW = null;
try {
charStreamR = new FileReader(src);
charStreamW = new FileWriter(des,true);
char[] flush = new char[2];
int len = 0;
while(-1 != (len=charStreamR.read(flush))){
charStreamW.write(flush, 0, len);
charStreamW.flush();
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("文件夾或不可創建或不可打開");
} finally {
try {
charStreamW.close();
charStreamR.close();
} catch (IOException e) {
e.printStackTrace();
System.out.println("關閉流失敗");
}
}
}
}