I/O流以及檔案的基本操作

xbhog發表於2021-05-20

檔案操作:

檔案操作其實就是一個FIle類;我們學習檔案操作就是學習File類中的方法;

檔案基操:

第一部分:學習檔案的基本操作(先扒原始碼以及文件)

Constructor Description
File(File parent, String child) 給定要操作的問價的父路徑和子檔名稱
File(String pathname) 給定一個要操作檔案的完整路徑
Modifier and Type Method Description
boolean public boolean createNewFile() throws IOException 建立檔案
boolean delete() 刪除檔案
boolean exists() 判斷給定路徑是否存在

來個例項:

import java.io.File;
import java.io.IOException;

public class FIleDelCre {
    public static void main(String[] args) throws IOException {
        File file = new File("e:\\IOFileSource\\xbhog.txt");
        if(file.exists()){
            file.delete();
        }else{
            System.out.println(file.createNewFile());
        }
    }
}

createNewFile:如果指定的檔案不存在且已成功建立,則為True;如果指定的檔案已經存在,則為False

知識點(敲黑板):

路徑分隔符:解決不同作業系統下的路徑符號問題(windows->“\”;Linux->“/”);

File file = new File("e:"+File.separator +"IOFileSource"+File.separator+"xbhog.txt");

注:

/**
     * The system-dependent default name-separator character, represented as a
     * string for convenience.  This string contains a single character, namely
     * {@link #separatorChar}.
*/
public static final String separator = "" + separatorChar;

對父路徑操作的方法:

import java.io.File;
import java.io.IOException;

public class FIleDelCre {
    public static void main(String[] args) throws IOException {
        File file = new File("e:"+File.separator +"IOFileSource"+File.separator+"test"+File.separator+"demo"+File.separator+"xbhog.txt");
        if(!file.getParentFile().exists()){ //如果該檔案的父目錄不存在
            /*
            file.getParentFile().mkdirs();   //進行建立多級父目錄
            mkdirs底層進行遞迴呼叫,實現多級目錄建立

            file.getParentFile().mkdir();   //進行建立一個父目錄
            */
        }
        if(file.exists()){
            file.delete();
        }else{
            System.out.println(file.createNewFile());
        }
    }
}

注:mkdirs與mkdir的區別,最好進入原始碼中檢視

檔案列表顯示:

流程圖:

image-20210426215631894

import java.io.File;
public class FilePwd {
    public static void main(String[] args) {
        File file = new File("D:" + File.separator);
		listDir(file);
    }
    public static void listDir(File file){
        if(file.isDirectory()){
            File[] Dirs = file.listFiles();
            while(Dirs != null){
                for (int i = 0; i < Dirs.length; i++) {
                    listDir(Dirs[i]);  //遞迴呼叫
                }
            }
        }
        System.out.println(file);
    }
}

檔案批量更名:

情景:

在資料採集的過程中由於操作失誤,使得xbhog-log資料夾下的所有檔案字尾採用了.java,為了修正這一錯誤,要求使得該目錄下的所有檔案字尾統一替換成.txt,同時也需要考慮多級目錄下的檔案更名操作。

image-20210426220807195

import java.io.File;
public class FIleChangeName {
    public static void main(String[] args) {
        File file = new File("D:" + File.separator + "xbhog-log");
        renameDir(file);

    }
    public static void renameDir(File file){
        if(file.isDirectory()){
            File[] dirs = file.listFiles(); 
            for (int i = 0; i < dirs.length; i++) {
                renameDir(dirs[i]);  //遞迴呼叫
            }
        }else {
            if (file.isFile()){ //判斷是否為檔案
                String fileName = null;  //檔名稱
                if(file.getName().endsWith(".java")){  //判斷是否以.java為結尾
                    fileName = file.getName().substring(0,file.getName().lastIndexOf("."))+".txt";
                    File newfile = new File(file.getParentFile(), fileName);  //新的檔名稱
                    file.renameTo(newfile);  //重新命名
                }
            }
        }
    }
}

位元組流與字元流:

位元組流:outputStream以及inputStream

字元流:Writer以及Reader

對資源操作的基本步驟:(檔案為例)--嚴格按照下面步驟

  1. 如果要操作的資源是檔案的話,首先需要通過File類物件找到一個要操作的檔案路徑
  2. 通過位元組流或者字元流的子類為位元組流或字元流的物件例項化(向上轉型)
  3. 執行讀寫操作
  4. 關閉資源

OutputStream位元組輸入流

常用的類普通方法:

Modifier and Type Method Description
void close() 關閉此輸出流並釋放與此流關聯的任何系統資源。
void flush() 重新整理此輸出流並強制寫入任何已緩衝的輸出位元組。
void write(byte[] b) 輸出單個位元組資料
void write(byte[] b, int off, int len) 輸出部分位元組資料
abstract void write(int b) 輸出一組位元組資料

對檔案的操作需要其OutputStream下的子類FileOutputStream來實現物件的例項化;

其常用的構造方法是:

Constructor Description
FileOutputStream(File file) 建立一個檔案輸出流,以寫入由指定file物件表示的檔案。
FileOutputStream(File file, boolean append) 建立一個檔案輸出流,以寫入由指定file物件表示的檔案。如果第二個引數為真,則位元組將被寫到檔案的末尾而不是開頭

例項:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;

public class FIleOutputStearm {
    public static void main(String[] args) throws IOException {
        File file = new File("xbhog.txt");
        if(!file.exists()){
            file.createNewFile();
        }
        OutputStream outputStearm = new FileOutputStream(file);
        String str = "歡迎來到xbhog的部落格";
        outputStearm.write(str.getBytes(StandardCharsets.UTF_8));
        outputStearm.close();
    }
}

檔案內容的追加:

    OutputStream stream = new FileOutputStream(file, true);
    String addStr = "-----這是追加的內容------";
    stream.write(addStr.getBytes());
    stream.close();

InputStream位元組輸入流:

該類的常用方法:

Modifier and Type Method Description
void close() 關閉輸出流
abstract int read() 讀取單個位元組資料,如果現在已經讀取到底了,返回-1
int read(byte[] b) 讀取一組位元組資料,返回的是讀取的個數,如果沒有資料已經讀取到底則返回-1
int read(byte[] b, int off, int len) 讀取一組位元組資料(只佔陣列的部分)
byte[] readAllBytes() 讀取輸入流全部位元組資料,JDK 1.9後新增
long transferTo(OutputStream out) 輸入流轉存到輸出流,JDK 1.9之後新增

對檔案的操作需要其InputStream下的子類FileInputStream來實現物件的例項化;

讀取檔案的固定用法:

  1. 建立檔案輸入流---InputStream input = new FileInputStream(file)
  2. 設定資料的讀取快取區----new byte[1024]
  3. 讀取資料,將資料讀取到快取區中並放回讀取的位元組個數 ----int len = input.read(data)
  4. 位元組轉換為字元流----new String(data,0,len)
  5. 關閉資源

讀取檔案內容例項:

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class FileInputStreamTest {
    public static void main(String[] args) throws IOException {
        File file = new File("xbhog.txt"); // 輸出檔案路徑
        if (file.exists()) {    // 檔案存在
            InputStream input = new FileInputStream(file);// 檔案輸入流
            byte data[] = new byte[1024]; // 資料讀取緩衝區
            // 讀取資料,將資料讀取到緩衝區之中,同時返回讀取的位元組個數
            int len = input.read(data);
            System.out.println("【" + new String(data, 0, len) + "】");// 位元組轉為字串
            input.close();    // 關閉輸入流

        }
    }
}

讀取檔案中的全部內容:

byte[] bytes = input.readAllBytes();
System.out.println(new String(bytes));

Writer字元流:

為了簡化輸出的操作,提供了Writer與Reader字元流;

該類的常用方法:

Modifier and Type Method Description
Writer append(char c) 將指定的字元寫入。
Writer append(CharSequence csq) 將指定的字元序列附加到此編寫器。
Writer append(CharSequence csq, int start, int end) 將指定字元序列的子序列追加到此編寫器
abstract void close() 關閉資源
abstract void flush() 重新整理資源流
void write(char[] cbuf) 寫入一組字元陣列
abstract void write(char[] cbuf, int off, int len) 寫入一組字元陣列的一部分
void write(int c) 寫入一個字元
void write(String str) 寫入一個字串
void write(String str, int off, int len) 寫入一個字串的一部分

在進行檔案流的寫入時,需要引入Writer下的FileWriter子類;

類的專案結構:

FileWriter常用構造方法:

Constructor Description
FileWriter(File file) 給定File物件,構造一個FileWriter物件。
FileWriter(String fileName, boolean append) 構造一個給定檔名的FileWriter物件,該檔名帶有一個布林值,該布林值表示是否追加寫入的資料。

例項:

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

public class FileWriterDemo {
    public static void main(String[] args) throws IOException {
        File file = new File("FileWriter.txt"); // 輸出檔案路徑
        if(!file.exists()){
            file.createNewFile();
        }
        Writer out = new FileWriter(file) ; // 例項化Writer類物件
        out.write("歡迎來到xbhog");	// 輸出字串
        out.write("\n");
        out.append("Test\n");
        out.append("www.cblog.cn/xbhog") ;// 追加輸出內容
        out.close();// 關閉輸出流
    }
}

Reader字元輸入流:

該類常用的方法:

Modifier and Type Method Description
abstract void close() 關閉資源
int read() 讀取單個字元
int read(char[] cbuf) 將字元放入陣列
long skip(long n) 跳過字元(幾個)
boolean ready() 判斷這個流是否已準備好了讀取了

例項測試:

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

public class FileReaderDemo {
    public static void main(String[] args) throws IOException {
        File file = new File("FileWriter.txt");// 輸出檔案路徑
        if (file.exists()) {// 檔案存在
            Reader in = new FileReader(file);  // 例項化輸入流
            char data[] = new char[1024];  // 緩衝區
            //“歡迎沒有了”
            in.skip(2);// 跨過2個字元長度
            int len = in.read(data); // 讀取資料
            System.out.println(new String(data, 0, len));
            in.close();// 關閉輸入流
        }
    }
}

轉換流:

轉換流 OutputStreamWriter InputStreamReader
繼承結構 public class OutputStreamWriterextends Writer {} public class InputStreamReaderextends Reader
構造方法 public OutputStreamWriter(OutputStream out) public InputStreamReader(InputStream in)

實現兩者的轉換操作:

將位元組輸入流轉換成字元輸入流

import java.io.*;
public class ConversionOperations {
    public static void main(String[] args) throws IOException {
        File file = new File("FileWriter1.txt"); 	// 輸出檔案路徑
        OutputStream output = new FileOutputStream(file) ;// 位元組流
        Writer out = new OutputStreamWriter(output) ; 	// 位元組流轉字元流
        out.write("測試兩者之間的轉換"); // 字元流輸出
        out.close();	// 關閉輸出流
        output.close(); 	// 關閉輸出流
    }
}
---- ---- ----

相關文章