IO流基礎
IO流概述
(1)用來處理裝置(硬碟,控制檯,記憶體)間的資料。
(2)java中對資料的操作都是通過流的方式。
(3)java用於操作流的類都在io包中。
(4)按照流操作的資料的型別不同:分為位元組流和字元流。字元流是為了方便中文的操作而來的。
(5)按照流的流向不同分為:輸入流,輸出流
IO流常用基類
(1)位元組流
輸出位元組流:OutputStream:位元組寫入流抽象類
|--->FileOutputStream:
位元組寫入流
|--->BufferedOutputStream:
位元組寫入流緩衝區
|--->PrintStream:
列印流
輸入位元組流:InputStream:位元組讀取流抽象類
|--->FileInputStream:
位元組讀取流
|--->BufferedInputStream:
位元組讀取流緩衝區
IO流常見需求
****字元流:
(1)需求1:在硬碟上建立一個檔案並寫入資訊
用字元寫入流:FileWriter
FileWriter fw = new FileWriter("g:\\filewriter.txt");
fw.write("輸入資訊");
fw.write("也可以寫入字元陣列".toCharArray());
fw.flush();
fw.close();
(2)需求2:在原有檔案上續寫資料
FileWriter fw = new FileWriter("g:\\filewriter.txt",true); fw.write("還可以續寫資訊"); fw.write("也可以寫入字元陣列".toCharArray()); fw.flush(); fw.close();
(3)需求3:讀取硬碟上的文字檔案,並將資料列印在控制檯
//**第一種讀取方法:只能讀取一個字元 try { FileReader fr = new FileReader("d:\\test.txt"); int ch = 0; ch = fr.read(); System.out.println((char)ch); fr.close(); } catch (IOException e) { e.printStackTrace(); } //**第二種讀取方法:利用陣列來提高效率 try { FileReader fr = new FileReader("d:\\test.txt"); char[] buf = new char[1024]; int len = 0; while((len = fr.read(buf))!=-1) { System.out.println(new String(buf,0,len)); } fr.close(); } catch (IOException e) { e.printStackTrace(); }
(4)需求4:拷貝文字檔案
利用緩衝區提高資料讀寫效率
(無緩衝區就相當於一滴一滴的喝水,有緩衝區就相當於一杯一杯的喝水)
try {
BufferedReader bufr = new BufferedReader(new FileReader("d:\\test.txt"));
BufferedWriter bufw = new BufferedWriter(new FileWriter("d:\\test2.txt"));
String line = null;
while((line = bufr.readLine())!=null)
{
bufw.write(line);
bufw.newLine();
bufw.flush(); //重新整理此輸出流並強制寫出所有緩衝的輸出字元。
}
bufr.close();
bufw.close();
} catch (IOException e) {
e.printStackTrace();
}
****位元組流:位元組流寫入時沒有重新整理
(1)需求1:在硬碟上建立一個檔案並寫入資訊(位元組流寫入時沒有重新整理)
FileOutputStream fos = new FileOutputStream("g:\\filestream.txt");
fos.write(97);//寫入一個位元組,int:97代表寫入char:a
fos.write("也可以寫入位元組陣列".getBytes());//通常使用此種方式寫入,直觀!
fos.close();
(2)需求2:在硬碟已有檔案上續寫資料(位元組流寫入時沒有重新整理)
FileOutputStream fos = new FileOutputStream("g:\\filestream.txt",true);
fos.write("建立位元組寫入流時,傳進去一個true引數就可以繼續寫入資訊".getBytes());
fos.close();
(3)需求3:讀取硬碟上的檔案
FileInputStream fis = new FileInputStream("g:\\filestream.txt");
//**第一種讀法:一個位元組一個位元組的讀(此種讀法慢)
int ch = 0;
while((ch = fis.read())!=-1)
{
System.out.println(char)ch);
}
**第一種讀法:利用位元組陣列讀(此種讀法效率有一定提高)
byte[] buf = new byte[1024];
int len = 0;
while((len = fis.read())!=-1)
{
System.out.println(new String(buf,0,len));
}
(4)需求4:拷貝位元組檔案,如圖片或者MP3或者電影
**第一種拷貝:不帶緩衝區(慢,還是效率問題)
FileInputStream fis = new FileInputStream("g:\\1.mp3");
FileOutputStream fos = new FileOutputStream("g:\\copy1.mp3");
byte[] buf = new byte[1024];
int len = 0;
while((len = fis.read(buf))!=-1)
{
System.out.priintln(buf,0,len);//位元組流寫入無需重新整理
}
fis.close();
fos.close();
**第二種拷貝:帶緩衝區,高效
BufferedInputStream bufi = new BufferedInputStream(new FileInputStream("g:\\1.mp3"));
BufferedOutputStream bufo = new BufferedOutputStream(new FileOutputStream("g:\\copy1.mp3"));
int ch = 0;
while((ch = bufi.read())!=-1)
{
bufo.write(ch);
}
bufi.close();
bufo.close();
****轉換流:
(1)需求1:讀取一個鍵盤錄入
InputStream in = System.in;//建立一個鍵盤錄入流,流不關則可以一直錄入
int by = in.read();//一次讀一個位元組
System.out.println((char)by);
in.close();
(2)需求2:鍵盤錄入一行資料列印一行資料,如果錄入的是over則結束錄入
InputStream in = System.in;
StringBuilder sb = new StringBuilder();
while(true)
{
int ch = in.read();
if(ch=='\r')
continue;
if(ch=='\n')
{
String line = sb.toString();
if("over".equals(line))
break;
sop(line.toUpperCase());//輸出大寫
sb.delete(0.sb.length());//清除上一行錄入的資料
}
else
sb.append((char)ch);
}
in.close();
(3)需求3:發現需求2中其實就是讀一行的原理,故引入位元組通向字元的橋樑:InputStreamReader
為提高效率加入緩衝區:
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while((line = bufr.readLine())!=null)
{
if("over".equals(line))
break;
System.out.println(line.toUpperCase());//輸出大寫
}
bufr.close();
(4)需求4:鍵盤錄入資料並列印到控制檯
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new OntputStreamWriter(System.out));
String line = null;
while((line = bufr.readLine())!=null)
{
if("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
bufr.close();
bufw.close();
(5)需求5:將鍵盤錄入的資料儲存到硬碟檔案
則只需將(4)中的
BufferedWriter bufw = new BufferedWriter(new OntputStreamWriter(System.out));
改為:
BufferedWriter bufw = new BufferedWriter(new OntputStreamWriter(new FileWriter("g:\\demo.txt")));
即:
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new OntputStreamWriter(new FileWriter("g:\\demo.txt")));
String line = null;
while((line = bufr.readLine())!=null)
{
if("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
bufr.close();
bufw.close();
(6)需求6:將硬碟檔案的資料列印到控制檯
則只需將(4)中的
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
改為:
BufferedReader bufr = new BufferedReader(new InputStreamReader(new FileReader("g:\\demo.txt")));
即:
BufferedReader bufr = new BufferedReader(new InputStreamReader(new FileReader("g:\\demo.txt")));
BufferedWriter bufw = new BufferedWriter(new OntputStreamWriter(System.out));
String line = null;
while((line = bufr.readLine())!=null)
{
if("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
bufr.close();
bufw.close();
File類常見需求
(1)檔名過濾:列出給定目錄的所有.java檔案
public void showFileName(File file)
{
String[] filenames = file.list(new FilenameFilter()//匿名內部類
{
public boolean accept(File dir,String name)//複寫唯一方法
{
return name.endsWith(".java");//列出所有.java檔案
}
});
}
(2)列出指定目錄下的所有檔案和資料夾(遞迴)
**示例1:不帶層次遞迴:
public static void showDir(File dir)
{
File[] files = dir.listFile();
for(int i = 0;i<files.length;i++)
{
if(files[i].isDirectory&&!files[i].isHidden())
showDir(files[i]);
else
sop(files[i]);
}
}
**示例2:帶層次遞迴:
public static void showDir(File dir,int level)
{
sop(getLevel(level)+C);//進來先列印層次和目錄
level++;
File[] files = dir.listFile();
for(int i = 0;i<files.length;i++)
{
if(files[i].isDirectory&&!files[i].isHidden())
showDir(files[i]);
else
sop(getLevel(level)+files[i]);//是檔案就列印層次和目錄
}
}
public static String getLevel(int level)
{
sop("|--");
StringBuilder sb = new StringBuilder();
for(int i=0;i<level;i++)
{
sb.inset(0."| ")
}
return sb.toString();
}
(3)需求:刪除帶內容的目錄:
public static void removeDir(File dir)
{
File[] files = file.listFile();
for(int i = 0;i<files.length;i++)
{
if(files[i].isDirectory&&!files[i].isHidden())
removeDir(files[i]);//如果是資料夾則繼續呼叫函式
else//如果是檔案則刪除。注意刪除的時候列印刪除的結果,防止誤刪或者重刪的情況
sop(files[i].toString()+"::"+files[i].delete());
}
sop(dir+"::"+dir.delete());
}
(4)需求:將制定目錄下的java檔案的絕對路徑儲存到文字檔案中。
思路:
**對指定目錄進行遞迴
**獲取遞迴過程中所有java檔案的路徑
**將這些路徑儲存到集合中
**將集合中的資料寫入檔案中
//對指定目錄進行遞歸併將所以Java檔案儲存到集合中
public static void getFileName(File file,ArrayList<File> arraylist){
File[] files = file.listFiles();
for (int i = 0; i < files.length; i++) {
if(files[i].isDirectory()&&!files[i].isHidden()){
getFileName(files[i],arraylist);
}else{
if(files[i].getName().endsWith(".java")){
arraylist.add(files[i]);
}
}
}
}
//將集合中所有資料儲存到新檔案中
public static void saveFileToNewDir(ArrayList<File> arraylist,File newDir){
BufferedWriter bufw = null;
try {
bufw = new BufferedWriter(new FileWriter(newDir));
for (File file : arraylist) {
String fileAbsolutePath = file.getAbsolutePath();
bufw.write(fileAbsolutePath);
bufw.newLine();
bufw.flush();
}
} catch (Exception e) {
System.out.println("檔案寫入失敗");
}finally{
try {
if(bufw!=null)
bufw.close();
} catch (Exception e2) {
System.out.println("檔案寫入流關閉失敗");
}
}
}