1. 流的概念
流是一組有順序的绎秒,有起點和終點的字節(jié)集合确虱。
2. 流的分類
按處理數(shù)據(jù)的類型分為字節(jié)流和字符流
按數(shù)據(jù)流向分為輸入流和輸出流
字節(jié)流和字符流的區(qū)別
字節(jié)流一次只讀取一個字節(jié),字符流一次讀取一個字符(一個字符包含多個字節(jié))替裆。字節(jié)流可以所有類型的數(shù)據(jù)校辩,而字符流只能處理字符類型的數(shù)據(jù)(如文本文件)
字節(jié)流
InputStream,抽象了應用程序讀取數(shù)據(jù)的方式
OutputStream 辆童,抽象了應用程序?qū)懗鰯?shù)據(jù)的方式
輸入流的基本方法
InputStream in = new InputStream();
int b = in.read();
讀取一個字節(jié)無符號填充到int的最后8位宜咒,返回的是讀到的字節(jié)(轉換成int類型的值的)內(nèi)容,當讀到-1時把鉴,標識讀取到最后結束了故黑。
in.read(byte[] buf);
讀取的數(shù)據(jù)填充到字節(jié)數(shù)組buf中,返回的是讀到的字節(jié)的個數(shù)庭砍。
in.read(byte[] buf,int start ,int size);
讀取數(shù)據(jù)到字節(jié)數(shù)組buf,并且是從buf的start位置開始场晶,最多存放size長度的數(shù)據(jù),返回的是讀到的字節(jié)的個數(shù)怠缸。
輸出流的基本方法
OutputStream out = new OutputStream();
out.write(int b);
寫出一個字節(jié)到流诗轻,寫的是int的最后的8位
out.write(byte[] buf);
將buf字節(jié)數(shù)組都寫入到流
out.write(byte[] buf,int start,int size);
字節(jié)數(shù)組buf從start位置開始寫size長度的字節(jié)到流
字節(jié)流的實現(xiàn)類
文件輸入輸出流
FileInputStream FileOutputStream
數(shù)據(jù)輸入輸出流
DataInputStream DataOutputStream
加了一些方法如writeInt(),writeLong()等等,普通的流只有writre(),即只能寫入字節(jié)
字節(jié)緩沖流
BufferedInputStream BufferedOutputStream
為IO流加入緩沖揭北,提高了讀寫的性能
帶緩沖要在out.write()后加out.flush(); flush()表示強制將緩沖區(qū)中的數(shù)據(jù)發(fā)送出去,不必等到緩沖區(qū)滿.
實驗證明扳炬,批量讀寫速度最快(通過byte[]來作為緩沖區(qū)),比帶緩沖的快很多
字符流
Reader搔体,讀取字符的抽象基類
Writer恨樟,寫入字符的抽象基類
字符流和字節(jié)流的方法差不多,只不過讀取的單位不同疚俱,讀取單位指的是read和write方法中參數(shù)的類型
字符流的實現(xiàn)類
InputStreamReader劝术,完成byte流解析為char流,按照編碼解OutputStreamReader,提供char流到byte流养晋,按照編碼處理
注意:
假設文本文件的編碼格式為gbk衬吆,項目的工作空間編碼是utf-8
InputStreamReader isr=new InputStreamReader(in)
此時讀出的數(shù)據(jù)會亂碼,因為默認是按照項目的編碼進行解析的
InputStreamReader isr=new InputStreamReader(in匙握,“charset”)
將charset寫為gbk,則不會出現(xiàn)亂碼問題
讀取單位是char
文件的讀寫
FileReader/FileWriter
讀取單位char或者string
字符緩沖流
BufferedReader
BufferedWriter
3. File類和RandomAccessFile類
讀寫 rw 只讀r
File
將文件和文件夾抽象成類的形式
RandomAccessFile
可以從文件指定的位置讀取數(shù)據(jù)
4. 代碼體現(xiàn)IO流的各種操作
文件復制
private static void copyFile() {
String sPath = "/Users/sufan/Desktop/szsmk說明.txt";
String dPath = "/Users/sufan/Desktop/copyszsmk.txt";
File sFile = new File(sPath);
File dFile = new File(dPath);
if(!sFile.exists()){
System.out.println("源文件不存在");
return;
}
//這句代碼有無均可
if (!dFile.exists()) {
try {
dFile.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
FileInputStream fis = new FileInputStream(sFile);
FileOutputStream fos = new FileOutputStream(dFile);
byte[] bytes = new byte[512];
int rs = -1;
while ((rs = fis.read(bytes)) > 0) {
fos.write(bytes, 0, rs);
}
fis.close();
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
文件夾復制
private static void copyFileDir() {
String sPath = "/Users/sufan/Desktop/javaTest";
String dPath = "/Users/sufan/Desktop/copyJavaTest";
File sFile = new File(sPath);
File dFile = new File(dPath);
if(!sFile.exists()){
System.out.println("源文件夾不存在");
return;
}
//此處可有可無
if (!dFile.exists()) {
dFile.mkdir();
}
File[] files = sFile.listFiles();
copyFileChild(files, dFile);
}
// 循環(huán)遍歷復制文件夾中的內(nèi)容(文件夾和文件)
private static void copyFileChild(File[] sFiles, File dFile) {
for (int i = 0; i < sFiles.length; i++) {
if (sFiles[i].isFile()) {
try {
FileInputStream fis = new FileInputStream(sFiles[i]);
FileOutputStream fos = new FileOutputStream(
new File(dFile.getAbsolutePath() + "/"
+ sFiles[i].getName()));
byte[] bytes = new byte[512];
int rs = -1;
while ((rs = fis.read(bytes)) > 0) {
fos.write(bytes, 0, rs);
}
fis.close();
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else if (sFiles[i].isDirectory()) {
String dPath = dFile.getAbsolutePath() + "/"
+ sFiles[i].getName();
System.out.println(dPath);
File df = new File(dPath);
if (!df.exists()) {
df.mkdir();
}
File[] sf = sFiles[i].listFiles();
copyFileChild(sf, df);
}
}
}
同樣刪除操作也分為文件和文件夾
等等還有很多操作在這里我就不一一列出代碼了