JAVA I/O基本操作

本文主要借鑑以下博客和網站:
how2j.cn
深入理解java中的I/O


JAVA文件操作

JAVA描述和管理文件的類是java.io.File類,通過File生成的對象file,可以通過以下指令對文件進行操作:

  1. file.exists() – 判斷文件是否存在
  2. file.isDirectory() – 判斷文件是否爲文件夾
  3. file.isFile() – 判斷是否是普通文件(不是文件夾)
  4. file.length() – 獲取文件的長度
  5. file.lastModified() – 獲取文件最後修改的時間
  6. file.getAbsolutePath() – 獲取文件的絕對路徑
  7. file.list() – 返回當前文件夾的所有子文件的文件名(深度爲1),返回類型爲字符串數組
  8. file.listFiles() – 返回當前文件夾的所有子文件(深度爲1),返回類型爲文件數組
  9. file.getParent() – 返回當前文件的父文件夾的名字
  10. file.getParentFile() – 返回當前文件的父文件夾
  11. file.mkdir() – 創建文件夾(如果父類文件夾不存在,則創建無效)
  12. file.mkdirs() – 創建文件夾(如果父類文件夾不存在,則連同父文件夾一同創建)
  13. file.getParentFile().mkdirs()常用,創建一個文件前,常把父類目錄都創好
  14. file.delete() – 刪除文件


以下將展示幾種流的使用方法(只展示讀,寫文件類似)

JAVA字節流

操作數據類型是字節,也就是JAVA數據類型中的byte,所有字節流的父類是InputStreamOutputStream(兩個都是的抽象類)在這裏插入代碼片
在這裏插入圖片描述
直接上代碼:

import java.io.*;
public class Main {
	public static void main(String[] args) {
		//文件中內容是 aAbB
		File file = new File("src/blog/test.txt");
		//對於文件操作,採用字節輸入流子類FileInputStream
		//建議採用在try括號內使用流的聲明,即使在異常時也能關閉流,減少資源損耗
		try(InputStream fi = new FileInputStream(file)){
			byte[] bytes = new byte[(int) file.length()];
			//將文件中的數據以字節流形式讀入到bytes中
			fi.read(bytes);
			for(byte b : bytes) {
				System.out.println(b);//打印ASCII碼的十進制形式
			}
		}catch (FileNotFoundException fe) {
			fe.printStackTrace();
		} catch (IOException e) {		
			e.printStackTrace();
		}
	}
}

結果爲(“aAbB”的ASCII碼的十進制):

97
65
98
66



JAVA字符流

與字節流不同,字符流操作的數據對象的最小單元是字符,比較符合我們的日常讀文本的習慣,所以在讀文本時用的很多,具體的字符輸入流和字符輸出流爲ReaderWriter,專門用於字符的形式讀取和寫入數據。
具體代碼如下:

import java.io.*;
public class Main {
	public static void main(String[] args) {
		//文件中內容是 aAbB
		//				cCdD
		File file = new File("src/blog/test.txt");
		//對於文件操作,採用字符輸入流FileReader
		//建議採用在try括號內使用流的聲明,即使在異常時也能關閉流,減少資源損耗
		try(Reader fr = new FileReader(file)){
			char[] chs = new char[(int) file.length()];
			fr.read(chs);
			for(char c : chs) {
				System.out.print(c);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

運行結果如下(輸出文本內容aAbBcCdD):

aAbB
cCdD

有時我們要對文本進行逐行處理,但以上的方法都是“一口將文件喫掉“,一次性讀完所有的內容,這時我們需要一個新的流來幫我們一步步做,這時緩存流就登上了舞臺。


JAVA緩存流

JAVA緩存流讀取數據用的是BufferedReader,寫入數據用的是BufferedWriter。這裏用到了設計模式中的裝飾者模式,在此不過多贅述,我們直接看緩存流是如何”裝飾“字符流來實現逐行讀取的。
代碼如下:

import java.io.*;
public class Main {
	public static void main(String[] args) {
		//文件中內容是 aAbB
		//				cCdD
		File file = new File("src/blog/test.txt");
		//逐行讀取,採用緩存流BufferedReader
		//建議採用在try括號內使用流的聲明,即使在異常時也能關閉流,減少資源損耗
		try(
				Reader fr = new FileReader(file);
				BufferedReader br = new BufferedReader(fr);
			)
		{
			String line = "";
			while((line = br.readLine()) != null) {//讀取一行
				System.out.println(line.toUpperCase());//全部轉化爲大寫
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

輸出處理後的結果:

AABB
CCDD



JAVA對象流

對象流指的是可以直接把一個對象以流的形式傳輸給其他的介質,但是,把一個對象序列化有一個前提是:這個對象的類,必須實現了Serializable接口。
注意,寫入到文本時,對象以序列化後的二進制形式存放,用文本查看時會亂碼
代碼如下:

import java.io.*;
class Student implements Serializable{
	//表示這個類當前的版本,如果有了變化,比如新設計了屬性,就應該修改這個版本號
    private static final long serialVersionUID = 1L;
	String name;
	int id;
	public Student(String name, int id) {
		this.name = name;
		this.id = id;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", id=" + id + "]";
	}
	
}


public class Main {
	public static void main(String[] args) {
		File file = new File("src/blog/test.txt");
		write(file);
		read(file);
	}
	
	//寫入對象
	static void write(File file) {
		try(
				OutputStream out = new FileOutputStream(file);
				ObjectOutputStream objout = new ObjectOutputStream(out);//對象輸出流
			)
		{
			Student[] students = new Student[2];
			students[0]= new Student("xsy", 123456);
			students[1] = new Student("theory", 654321);
			objout.writeObject(students);//只能寫一次
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	
	//讀取對象
	static void read(File file) {
		try(
				InputStream in = new FileInputStream(file);
				ObjectInputStream objin = new ObjectInputStream(in);//對象輸入流
			)
		{
			Student[] students = (Student[]) objin.readObject(); // 讀取文件中的所有對象
			for (Student s : students) {
				System.out.println(s);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}

對象讀取的運行結果爲:

Student [name=xsy, id=123456]
Student [name=theory, id=654321]



JAVA數據流

數據流的目的在於對文本數據進行格式化讀寫,以下代碼先寫入一個整型int和字符串String,然後按順序readInt和readUTF讀取。

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
      
public class Main {
      
    public static void main(String[] args) {
        write();
        read();
    }
 
    private static void read() {
        File f =new File("src\\blog\\test.txt");
        try (
                FileInputStream fis  = new FileInputStream(f);
                DataInputStream dis =new DataInputStream(fis);
        ){
            int i = dis.readInt();
            String str = dis.readUTF();

            System.out.println(i);
            System.out.println(str);
 
        } catch (IOException e) {
            e.printStackTrace();
        }
         
    }
 
    private static void write() {
        File f =new File("src\\blog\\test.txt");
        try (
                FileOutputStream fos  = new FileOutputStream(f);
                DataOutputStream dos =new DataOutputStream(fos);
        ){
            dos.writeInt(1);
            dos.writeUTF("xsy");
        } catch (IOException e) {
            e.printStackTrace();
        }
         
    }
}

運行結果如下:

1
xsy

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章