Java基礎之IO
阿新 • • 發佈:2021-10-21
File類
File類構造方法
- public File(String pathname)
- public File(String parent, String child)
- public File(File parent, String child)
File類常用方法之get
- public String getAbsolutePath():獲取絕對路徑
- public String getPath() :獲取路徑
- public String getName() :獲取名稱
- public String getParent():獲取上層檔案目錄路徑。若無,返回null
- public long length() :獲取檔案長度(即:位元組數)。不能獲取目錄的長度。
- public long lastModified() :獲取最後一次的修改時間,毫秒值
- public String[] list() :獲取指定目錄下的所有檔案或者檔案目錄的名稱陣列
- public File[] listFiles() :獲取指定目錄下的所有檔案或者檔案目錄的File陣列
File常用方法之重新命名
- public boolean renameTo(File dest):把檔案重新命名為指定的檔案路徑
File常用方法之判斷
- public boolean isDirectory():判斷是否是檔案目錄
- public boolean isFile() :判斷是否是檔案
- public boolean exists() :判斷是否存在
- public boolean canRead() :判斷是否可讀
- public boolean canWrite() :判斷是否可寫
- public boolean isHidden() :判斷是否隱藏
File常用方法之建立
- public boolean createNewFile() :建立檔案。若檔案存在,則不建立,返回false
- public boolean mkdir() :建立檔案目錄。如果此檔案目錄存在,就不建立了。
如果此檔案目錄的上層目錄不存在,也不建立。 - public boolean mkdirs() :建立檔案目錄。如果上層檔案目錄不存在,一併建立
File常用方法之刪除
- public boolean delete():刪除檔案或者資料夾(要刪除一個檔案目錄,請注意該檔案目錄內不能包含檔案或者檔案目錄)
IO概述
流的分類
- 按照資料單位,分為:位元組流(8bit)、字元流(16bit)
- 按照流向,分為:輸入流、輸出流
- 按照角色,分為:節點流、處理流
IO流的體系
檔案流(節點流)
- FileReader, FileWriter 字元流用來讀取和吸入文字文件,如.txt, .java, .html
- FileInputStream, FileOutputStream 位元組流用來處理非文字文件,如.doc, .jpg, .mp3, .mp4
FileReader 文字字元輸入流
- public int read():讀取一個字元並返回,到了檔案末尾時返回-1
- public int read(char cbuf[]):讀取一定數量的字元至cbuf中,返回讀取的長度,到了檔案末尾時返回-1
@Test
public void testFileReader() {
// 1.建立檔案
File file = new File("test.txt");
FileReader fileReader = null;
try {
// 2.建立輸入流
fileReader = new FileReader(file);
// 3.讀取輸入
int c;
while ((c = fileReader.read()) != -1) {
System.out.print((char) c);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 4.關閉資源
if (fileReader != null) {
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Test
public void testFileReader1() {
// 1.建立檔案
File file = new File("test.txt");
FileReader fileReader = null;
try {
// 2.建立輸入流
fileReader = new FileReader(file);
// 3.讀取輸入
char[] buffer = new char[5];
int len;
while ((len = fileReader.read(buffer)) != -1) {
System.out.print(new String(buffer, 0, len));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 4.關閉資源
if (fileReader != null) {
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
FileWriter 文字字元輸出流
構造方法:
- public FileWriter(String fileName | File file, boolean append) : append為true時續寫檔案,append為false時重寫檔案
- public FileWriter(String fileName | File file), 相當於FileWriter(String fileName | File file, false)
注意事項:
- Writer和OutputStream操作的檔案如果不存在,不會報錯,並將自動建立該檔案
@Test
public void testFileWriter() {
FileWriter fileWriter = null;
try {
// 1.建立檔案
File file = new File("test1.txt");
// 2.建立輸出流
fileWriter = new FileWriter(file, false);
// 3.寫入
fileWriter.write("Hello World!\n");
fileWriter.write("我愛北京天安門\n");
} catch (IOException e) {
e.printStackTrace();
} finally {
// 4.關閉資源
if (fileWriter != null) {
try {
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
FileInputStream、FileOutputStream 文字位元組輸入輸出流
/**
* 使用FileInputStream和FileOutputStream實現通用的檔案拷貝
*/
public void fileCopy(String src, String dest) {
FileInputStream in = null;
FileOutputStream out = null;
try {
File srcFile = new File(src);
File destFile = new File(dest);
in = new FileInputStream(srcFile);
out = new FileOutputStream(destFile, false);
byte[] buffer = new byte[1024];
int len;
while((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
緩衝流
原理
為了提高資料讀寫的速度,Java API提供了帶緩衝功能的流類,在使用這些流類時,會建立一個內部緩衝區陣列,預設使用8192個位元組或字元的緩衝區
BufferedInputStream、BufferedOutputStream
public void fileCopy(String src, String dest) throws IOException {
BufferedInputStream in = new BufferedInputStream(new FileInputStream(src));
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(dest));
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
out.close();
in.close();
}
BufferReader、BufferedWriter
注意點:
- BufferedReader除了可以使用read()方法之外,還封裝了一個readLine()方法用於讀取一行,到檔案末尾時返回null
- readLine()方法返回的字串不好含換行符,如需輸出換行符,可手動拼接換行符或使用BufferedWriter.newLine()換行
public void testBufferedReaderWriter() throws IOException {
BufferedReader reader = new BufferedReader(new FileReader("test.txt"));
BufferedWriter writer = new BufferedWriter(new FileWriter("test(1).txt"));
// 方式1:
// char[] cbuf = new char[10];
// int len;
// while ((len = reader.read(cbuf)) != -1) {
// writer.write(cbuf, 0, len);
// }
// 方式2:
String line;
while ((line = reader.readLine()) != null) {
writer.write(line);
writer.newLine();
}
writer.close();
reader.close();
}
轉換流
轉換流提供了位元組流和字元流之間的轉換,常用來時間檔案編碼的轉換:
- InputStreamReader:將InputStream轉換為Reader
- OutputStreamWriter:將Writer轉換為OutputStream
public void utf8ToGbk() throws IOException {
InputStreamReader reader = new InputStreamReader(new FileInputStream("test.txt"), "UTF-8");
OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("test_gbk.txt"), "GBK");
char[] cbuf = new char[10];
int len;
while ((len = reader.read(cbuf)) != -1) {
writer.write(cbuf, 0, len);
}
reader.close();
writer.close();
}
標準輸入輸出流(瞭解)
- System.in 標準輸入流,型別是InputStream,預設輸入裝置是鍵盤,可通過System.setIn(InputStream in)設定輸入裝置
- System.out 標準輸出流,型別是PrintStream,預設輸出裝置是控制檯,可通過System.setOut(PrintStream out)設定輸出裝置
/**
* 從鍵盤輸入字串,要求將讀取到的整行字串轉成大寫輸出。
* 然後繼續進行輸入操作,直至當輸入“e”或者“exit”時,退出程式。
*/
public static void main(String[] args) throws IOException {
// 為了藉助BufferedReader的readLine()方法,這裡先把System.in(InputStream)轉為轉換流,又轉為了緩衝流
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String line;
while ((line = reader.readLine()) != null) {
if (!line.equals("e") && !line.equals("exit")) {
System.out.println(line);
} else {
break;
}
}
reader.close();
}
列印流(瞭解)
列印流:PrintStream和PrintWriter
- 提供了一系列過載的print()和println()方法,用於多種資料型別的輸出
- PrintStream和PrintWriter的輸出不會丟擲IOException異常
- PrintStream和PrintWriter有自動flush功能
- PrintStream 列印的所有字元都使用平臺的預設字元編碼轉換為位元組。
在需要寫入字元而不是寫入位元組的情況下,應該使用 PrintWriter 類。 - System.out返回的是PrintStream的例項
public void testPrintStream() throws FileNotFoundException {
PrintStream out = new PrintStream(new FileOutputStream("test11.txt"));
System.setOut(out);
for (int i = 0; i <= 255; i++) {
System.out.print((char) i);
if (i % 50 == 0) {
System.out.println();
}
}
out.close();
}
資料流(瞭解)
資料流有兩個類:(用於讀取和寫出基本資料型別、String類的資料)DataInputStream 和 DataOutputStream
/**
* 資料流:寫入
*/
@Test
public void testDataOutputStream() throws IOException {
DataOutputStream out = new DataOutputStream(new FileOutputStream("test.dat"));
out.writeUTF("張三");
out.writeInt(30);
out.writeBoolean(true);
out.close();
}
/**
* 資料流:讀取
*/
@Test
public void testDataInputStream() throws IOException {
DataInputStream in = new DataInputStream(new FileInputStream("test.dat"));
String name = in.readUTF();
int age = in.readInt();
boolean isAlive = in.readBoolean();
System.out.println("name:" + name);
System.out.println("age:" + age);
System.out.println("isAlive:" + isAlive);
in.close();
}
物件流
可序列化物件的要求:
- 需要實現介面:Serializable
- 當前類提供一個全域性常量:serialVersionUID
- 類內部所有屬性也必須是可序列化的(預設情況下,基本資料型別可序列化)
/**
* 物件序列化與反序列化
*/
public class IOTest7 {
/**
* 物件序列化
*/
@Test
public void testObjectOutputStream() throws IOException {
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("test.obj"));
out.writeObject("我愛你中國");
Person person = new Person("張三", 30, true);
out.writeObject(person);
out.close();
}
/**
* 物件反序列化
*/
@Test
public void testObjectInputStream() throws IOException, ClassNotFoundException {
ObjectInputStream in = new ObjectInputStream(new FileInputStream("test.obj"));
String str = (String) in.readObject();
System.out.println(str);
Person person = (Person) in.readObject();
System.out.println(person);
in.close();
}
}
class Person implements Serializable {
public static final long serialVersionUID = 20211021L;
private String name;
private int age;
private boolean isAlive;
public Person(String name, int age, boolean isAlive) {
this.name = name;
this.age = age;
this.isAlive = isAlive;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", isAlive=" + isAlive +
'}';
}
}