IO流
File
File類概述
File:它是檔案和目錄路徑名的抽象表示
- 檔案和目錄是可以通過File封裝成物件的
- 對于File而言,其封裝性并不是一個真正存在的檔案,僅僅是一個路徑名而已,它可以是存在的,也可以是不存在的,將來要是用過具體的操作把這個路徑的內容轉換為具體存在的
構造方法
- File(String pathname) 通過將給定的路徑名字串轉換為抽象路徑名來創建新的File實體
- File(String parent,String child) 從路徑名字字串和子路徑名字字串創建新的File實體
- File(File parent,String child)從父抽象路徑名和子路徑名字字串創建新的File實體
import java.io.File;
public class Demo {
public static void main(String[] args) {
//File(String pathname) 通過將給定的路徑名字串轉換為抽象路徑名來創建新的File實體
File f1 = new File("D:\\JAVA\\java.txt");
System.out.println(f1);
//File(String parent,String child) 從路徑名字字串和子路徑名字字串創建新的File實體
File f2 = new File("D:\\JAVA","java.txt");
System.out.println(f2);
//File(File parent,String child)從父抽象路徑名和子路徑名字字串創建新的File實體
File f3 = new File("D:\\JAVA");
File f4 = new File(f3,"java.txt");
System.out.println(f4);
}
}
File類創建功能
-
public boolean createNewFile() 當具有該名稱的檔案不存在時,創建一個由該抽象路徑命名的新空檔案
- 檔案名存在,就不創建,回傳false
- 檔案名不存在,就創建,回傳ture
-
public boolean mkdir() 創建由此路徑名命名的目錄
- 目錄名存在,就不創建,回傳false
- 目錄名不存在,就創建,回傳ture
-
punlic boolean mkdirs() 創建由此抽象路徑名命名的目錄,包括任何必須但不存在的父目錄
- 目錄名存在,就不創建,回傳false
- 目錄名不存在,就創建,回傳ture
import java.io.File;
import java.io.IOException;
public class Demo {
public static void main(String[] args) throws IOException {
//在D:\\JAVA目錄下創建一個檔案java.txt
File f1 = new File("D:\\JAVA\\java.txt");
System.out.println(f1.createNewFile());
//在E:\\JAVA目錄下創建一個目錄JavaEE
System.out.println("----------------");
File f2 = new File("D:\\JAVA\\JAVAEE");
System.out.println(f2.mkdir());
//在E:\\JAVA目錄下創建一個多級目錄javaWEB\\HTML
System.out.println("----------------");
File f3 = new File("D:\\JAVA\\javaWEB\\HTML");
System.out.println(f3.mkdirs());
}
}
File判斷和獲取功能
- public boolean isDiectory() 測驗此抽象路徑名表示的File是否為目錄
- public boolean isFiel() 測驗此抽象路徑名表示的Fiel是否為檔案
- public boolean exists() 測驗此抽象路徑名表示的File是否存在
- public String getAbsolutePath() 回傳此抽象路徑名轉換為路徑名字字串
- public String getPath() 將此抽象路徑名轉換為路徑名字串
- public String getName() 回傳由此抽象路徑名表示的檔案或目錄的名稱
- public String[] list() 回傳此抽象路徑名表示的目錄中的檔案和目錄的名稱字串陣列
- public File[] listFiles() 回傳此抽象路徑名表示的目錄中的檔案和目錄的File物件陣列
import java.io.File;
public class Demo {
public static void main(String[] args) {
// 1. public boolean isDiectory() 測驗此抽象路徑名表示的File是否為目錄
// 1. public boolean isFiel() 測驗此抽象路徑名表示的Fiel是否為檔案
// 3. public boolean exists() 測驗此抽象路徑名表示的File是否存在
File f1 = new File("D:\\JAVA\\java.txt");
System.out.println(f1.isDirectory());
System.out.println(f1.isFile());
System.out.println(f1.exists());
System.out.println("---------------------------");
// 4. public String getAbsolutePath() 回傳此抽象路徑名轉換為路徑名字字串
// 5. public String getPath() 將此抽象路徑名轉換為路徑名字串
// 6. public String getName() 回傳由此抽象路徑名表示的檔案或目錄的名稱
System.out.println(f1.getAbsolutePath());
System.out.println(f1.getPath());
System.out.println(f1.getName());
// 7. public String[] list() 回傳此抽象路徑名表示的目錄中的檔案和目錄的名稱字串陣列
// 8. public File[] listFiles() 回傳此抽象路徑名表示的目錄中的檔案和目錄的File物件陣列
File f2 = new File("D:\\JAVA");
String[] list = f2.list();
System.out.println(list);
for (String li : list) {
System.out.println(li);
}
System.out.println("---------------------");
File[] files = f2.listFiles();
for (File filelist : files) {
// System.out.println(filelist);
if (filelist.isFile()) {
System.out.println(filelist.getName());
}
}
}
}
File類洗掉功能
- public boolean delete() 洗掉由此抽象路徑名表示的檔案或目錄
遍歷目錄
/*
給定一個路徑(E:\\JAVA),請通過遞回完成遍歷該目錄下的所有內容,并把所有檔案的絕對路徑輸出到控制臺
思路:
根據給定路徑創建一個File物件
定義一個方法用于獲取給定目錄下的所有內容,引數為第一步創建的File物件
獲取給定的File目錄下所有的檔案或者目錄的File陣列
遍歷該File陣列,得到每一個File物件
判斷該File物件是否是目錄
是:遞回呼叫
不是:獲取絕對路徑輸出在控制臺
呼叫方法
*/
import java.io.File;
public class Demo {
public static void main(String[] args) {
File fiel = new File("D:\\JAVA");
getAllFilePath(fiel);
}
public static void getAllFilePath(File file){
File[] files = file.listFiles();
if (files != null){
for (File i : files){
if (i.isDirectory()){
getAllFilePath(i);
}else{
System.out.println(i.getAbsolutePath());
}
}
}
}
}
IO流概述和分類
IO流概述:
- IO:輸入/輸出(input/Output)
- 流 : 是一種抽象概念,是對資料傳輸的總稱,也就是說資料在設備間的傳輸稱為流,流的本質是資料傳輸
- IO流就是用來處理設備間資料傳輸問題的
- 常見的應用:檔案復制;檔案上傳;檔案下載
分類
- 按資料流向:
- 輸入流:讀資料
- 輸出流:寫資料
- 按照資料型別分
- 位元組流
- 位元組輸入流;位元組輸出流
- 字符流
- 字符輸入流;字符輸出流
- 位元組流
- 一般IO流按照資料型別來分
使用場景:
- 如果資料通過Windows自帶的記事本,我們還可以讀懂里面的內容,用字符流;否則用位元組流,若不知道使用哪種型別,用位元組流(萬能流),
位元組流
位元組流抽象基類
- InputStream:這個抽象類是表示位元組輸入流的所有類的超類
- OutputStream:這個抽象類表示位元組輸出流的所有類的超類
- 子類名特點:子類名稱都是以其父類名作為子類名的后綴
FileOutputStream:檔案輸出流用于將資料寫入File
- FileOutputStream(String name):創建檔案輸出流以指定的名稱寫入檔案
使用位元組輸出流寫資料的步驟
- 創建位元組輸出流物件(呼叫系統功能創建了檔案,創建位元組輸出流物件,讓位元組輸出流物件指向檔案)
- 呼叫位元組輸出流物件的寫資料方法
- 釋放資源(關閉此檔案輸出流并釋放與此相關聯的任何系統資源)
/*
FileOutputStream(String name):創建檔案輸出流以指定的名稱寫入檔案
做了三件事:
呼叫系統功能創建了檔案
創建了位元組輸出流物件
讓位元組輸出流物件指向創建好的檔案
void write(int b):將指定的位元組寫入此檔案輸出流
最后都要釋放資源
void colse():關閉此檔案輸出流并釋放與此相關聯的任何系統資源
*/
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("fos.txt");
fos.write(97);
fos.close();
}
}
位元組流寫資料的三種方式
- void write(int b) 將指定的位元組寫入此檔案輸出流
- void write(byte[] b)將b.length位元組從指定的位元組陣列寫入此檔案輸出流一次寫一個位元組陣列資料
- void write(byte[] b, int off, int len)將len位元組從指定的位元組陣列開始,從偏移量off(索引位置)開始寫入此檔案輸出流一次寫一個位元組陣列的部分資料
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("fos.txt");
//void write(int b) 將指定的位元組寫入此檔案輸出流
// fos.write(97);
// fos.write(98);
// fos.write(99);
// fos.write(100);
// fos.write(101);
//void write(byte[] b)將b.length位元組從指定的位元組陣列寫入此檔案輸出流一次寫一個位元組陣列資料
byte[] bytes = "abcde".getBytes();
// fos.write(bytes);
//void write(byte[] b, int off, int len)將len位元組從指定的位元組陣列開始,從偏移量off(索引位置)開始寫入此文
fos.write(bytes,1,3);
}
}
fos.colse();
寫入資料的兩個問題
- 如何換行
- Windows: \r\n
- Linux: \n
- mac: \r
- 如何追加寫入
- public FileOutputStream?(String name,boolean append)
創建檔案輸出流以指定的名稱寫入檔案,
如果第二個引數為true ,則位元組將寫入檔案的末尾而不是開頭,
- public FileOutputStream?(String name,boolean append)
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("IO流\\fos.txt",true);
//如何換行
for (int i = 0; i < 10; i++){
fos.write("hello".getBytes());
//如何換行
fos.write("\r\n".getBytes());
}
//釋放資源
fos.close();
}
}
位元組流寫資料+例外處理
- finally:在例外處理時提供finally塊來執行所有請出操作,比如說IO流中的釋放資源
- 特點:被finally控制的陳述句一定會執行,除非JVM退出
- 格式:
try{
可能出現例外的代碼
}catch(例外類名 變數名){
例外的處理代碼;
}finally{
執行所有清除操作;
}
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo {
public static void main(String[] args) {
FileOutputStream fos = null;
try{
fos = new FileOutputStream("IO流\\fos.txt");
fos.write("hello".getBytes());
}catch (IOException e){
e.printStackTrace();
}finally {
if (fos != null){
try{
fos.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}
}
位元組流讀資料
FileInputStream:檔案系統中的獲取輸入位元組
- int read(),從該輸入流讀取一個位元組的資料
- int read?(byte[] b) 從該輸入流讀取最多 b.length個位元組的資料到一個位元組陣列,
- int read?(byte[] b, int off, int len) 從該輸入流讀取最多 len個位元組的資料到位元組陣列,
- 使用位元組輸入流讀資料的步驟:
- 創建位元組輸入流物件
- 呼叫位元組輸入流物件的讀資料方法
- 釋放資源
位元組緩沖流
- BufferedOutputStream:該類實作緩沖輸出流,通過設定這樣的輸出流,應用程式可以向底層輸出流寫入位元組,而不必為寫入的每個位元組導致底層系統的呼叫
- BufferedInputStream:創建BufferedInputStream將創建一個內部緩沖區陣列,當從流中讀取或者跳過位元組時,內部緩沖區將根據需要從所包含的輸入流中重新填充,一次很多位元組,
構造方法
- 位元組緩沖輸出流:BufferedOutputStream(OutputStream out)
- 位元組緩沖輸入流:BufferedInputStream(InputStream in)
為什么構造方法需要的是位元組流,而不是具體的檔案或者路徑呢?
- 位元組緩沖流僅僅提供緩沖區,而真正的讀寫資料還得依靠基本的位元組流物件進行操作,
package 位元組流.位元組緩沖流;
import java.io.*;
/*
* BufferedOutputStream
* * BufferedInputStream
* 構造方法:
* 位元組緩沖輸出流:BufferedOutputStream(OutputStream out)
* 位元組緩沖輸入流:BufferedInputStream(InputStream in)
*/
public class Demo {
public static void main(String[] args) {
//BufferedOutputStream
/* BufferedOutputStream bos = null;
try {
bos = new BufferedOutputStream(new FileOutputStream("bos.txt"));
bos.write("hello\r\n".getBytes());
bos.write("world\r\n".getBytes());
}catch (IOException e){
e.printStackTrace();
}finally {
if (bos != null){
try {
bos.close();
}catch (IOException e){
e.printStackTrace();
}
}
}*/
//BufferedInputStream
//讀一
/* BufferedInputStream bis = null;
try {
bis = new BufferedInputStream(new FileInputStream("bos.txt"));
int len;
while((len = bis.read()) != -1){
System.out.print((char)len);
}
}catch (IOException e){
e.printStackTrace();
}finally {
if (bis != null){
try {
bis.close();
}catch (IOException e){
e.printStackTrace();
}
}
}*/
//讀二
BufferedInputStream bis = null;
try {
bis = new BufferedInputStream(new FileInputStream("bos.txt"));
byte [] b = new byte[1024];
int len;
while ((len = bis.read(b)) != -1){
System.out.print(new String(b,0,len));
}
}catch (IOException e){
e.printStackTrace();
}finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
復制視頻效率對比:
import java.io.*;
public class Demo {
public static void main(String[] args) {
long start = System.currentTimeMillis();
//緩沖位元組流一次讀取一個位元組
// method(); // 50 ms
//緩沖位元組流一次讀取一個位元組陣列
method2(); // 2 ms
//基本位元組流一次讀取一個位元組陣列
// method3(); // 20 ms
//基本位元組流一次讀取一個位元組
// method4(); // 6000 ms
long end = System.currentTimeMillis();
System.out.println(end - start + "ms");
}
//緩沖位元組流一次讀取一個位元組
public static void method() {
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream("D:\\JAVA\\NBA.qlv"));
bos = new BufferedOutputStream(new FileOutputStream("D:\\JAVA\\JAVAEE\\NBA.qlv"));
int len;
while ((len = bis.read()) != -1) {
bos.write(len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bis == null || bos == null) {
try {
bis.close();
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//緩沖位元組流一次讀取一個位元組陣列
public static void method2() {
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream("D:\\JAVA\\NBA.qlv"));
bos = new BufferedOutputStream(new FileOutputStream("D:\\JAVA\\JAVAEE\\NBA.qlv"));
byte[] b = new byte[1024];
int len;
while ((len = bis.read(b)) != -1) {
bos.write(b,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bis == null || bos == null) {
try {
bis.close();
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//基本位元組流一次讀取一個位元組陣列
public static void method3() {
FileOutputStream fos = null;
FileInputStream fis = null;
try {
fis = new FileInputStream("D:\\JAVA\\NBA.qlv");
fos = new FileOutputStream("D:\\JAVA\\JAVAEE\\NBA.qlv");
byte[] b = new byte[1024];
int len;
while ((len = fis.read(b)) != -1) {
fos.write(b,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos == null || fis == null) {
try {
fos.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//基本位元組流一次讀取一個位元組
public static void method4() {
FileOutputStream fos = null;
FileInputStream fis = null;
try {
fis = new FileInputStream("D:\\JAVA\\NBA.qlv");
fos = new FileOutputStream("D:\\JAVA\\JAVAEE\\NBA.qlv");
int len;
while ((len = fis.read()) != -1) {
fos.write(len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos == null || fis == null) {
try {
fos.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
位元組緩沖流效率明顯高于基本位元組流
字符流
為什么會出現字符流
由于位元組流操作中文不是特別方便,所以Java就提供了字符流
- 字符流 = 位元組流 + 編碼表
用位元組流復制文本檔案式,文本檔案也會有中文,但是沒問題,是因為最終底層操作會自動進行位元組拼接成中文,如何識別是中文呢? - 漢字在存盤的時候,無論選擇哪種編碼存盤,第一個位元組都是負數,
編碼:
- byte[] getBytes():使用平臺默認字符集將該 String 編碼為一系列位元組,將結果存盤到新的位元組陣列中
- byte[] getBytes(String charsetName):使用指定的字符集將該 String編碼為一些列位元組,將結果存盤到新的位元組陣列中
解碼:
- String(byte[] bytes):通過使用平臺的默認字符集解碼指定的位元組陣列來構造新的 String
- String(byte[] bytes, String charsetName):通過指定的字符集解碼指定的位元組陣列來構造新的String
字符流編碼解碼問題
- 字符流抽象基類
- Reader:字符輸入流的抽象類
- Writer:字符輸出流的抽象類
- 字符流中和編碼解碼問題相關的兩個類
- InputStreamReader:是從位元組流到字符流的橋梁:它讀取位元組,并使用指定的charset將其解碼為字符, 它使用的字符集可以由名稱指定,也可以被明確指定,或者可以接受平臺的默認字符集,
- OutputStreamWriter:是從字符流到位元組流的橋梁:使用指定的charset將寫入的字符編碼為位元組, 它使用的字符集可以由名稱指定,也可以被明確指定,或者可以接受平臺的默認字符集,
import java.io.*;
public class Demo {
public static void main(String[] args) throws IOException {
//編碼
// OutputStreamWriter?(OutputStream out) 創建一個使用默認字符編碼的OutputStreamWriter,
// OutputStreamWriter?(OutputStream out, String charsetName) 創建一個使用命名字符集的OutputStreamWriter,
//默認編碼
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"));
osw.write("中國");
osw.close();
//自定義編碼
OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream("osw2.txt"), "GBK");
osw2.write("中華人民共和國");
osw2.close();
//解碼
// InputStreamReader?(InputStream in) 創建一個使用默認字符集的InputStreamReader,
// InputStreamReader?(InputStream in, String charsetName) 創建一個使用命名字符集的InputStreamReader,
//默認編碼
InputStreamReader isr = new InputStreamReader(new FileInputStream("osw.txt"));
int ch;
while ((ch = isr.read()) != -1){
System.out.print((char) ch);
}
isr.close();
System.out.println();
//自定義編碼
InputStreamReader isr2 = new InputStreamReader(new FileInputStream("osw2.txt"),"GBK");
int len;
char [] c = new char[1024];
while((len = isr2.read(c)) != -1){
System.out.println(new String(c,0,len));
}
isr2.close();
}
}
字符流寫資料的5種方式
- void write(int c) 寫一個字符
- void write(char[] cbuf)寫入一個字符陣列
- void write(char[] cbuf, int off, int len)寫入字符陣列的一部分
- void write(String str)寫一個字串
- void write(String str, int off, int len)寫入字串的一部分
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class Demo {
public static void main(String[] args) throws IOException {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"));
//void write(int c) 寫一個字符
osw.write(97);
osw.write(98);
//void write(char[] cbuf)寫入一個字符陣列
// char [] c = {'a','b','c','d'};
// osw.write(c);
//void write(char[] cbuf, int off, int len)寫入字符陣列的一部分
// char [] c = {'a','b','c','d'};
// osw.write(c,1,2);
//void write(String str)寫一個字串
// osw.write("hello");
//void write(String str, int off, int len)寫入字串的一部分
// osw.write("hello",1,2);
//void flush()重繪流
osw.flush();
osw.close();//關閉流 釋放資源 先重繪 后釋放
}
}
字符流讀資料的兩種方式
- int read()一次讀一個字符資料
- int read(char[] cbuf)一次讀一個字符陣列資料
```import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class Demo {
public static void main(String[] args) throws IOException {
//int read()一次讀一個字符資料
InputStreamReader isr = new InputStreamReader(new FileInputStream("osw.txt"));
int ch;
while ((ch = isr.read()) != -1){
System.out.print((char)ch);
}
isr.close();
System.out.println("--------------");
//int read(char[] cbuf)一次讀一個字符陣列資料
InputStreamReader isr2 = new InputStreamReader(new FileInputStream("osw.txt"));
int ch2;
char [] c = new char[1024];
while((ch2 = isr2.read(c)) != -1){
System.out.print(new String(c,0,ch2));
}
isr2.close();
}
}
轉換流的名字較長,而我們常見的操作都是按照本地默認編碼實作的,為了簡便書寫,轉換流提供了對應的子類
- FileReader:用于讀取取字符的便捷類
- FileReader(String fileName)
- FileWriter:用于寫入字符檔案的便捷類
- FileWriter(String fileName)
字符緩沖流
- BufferedReader:從字符輸入流讀取文本,緩沖字符,以提供字符,陣列和行的高效讀取, 可以指定緩沖區大小,或者可以使用默認大小, 默認值足夠大,可用于大多數用途,
- BufferedWriter:將文本寫入字符輸出流,緩沖字符,以提供單個字符,陣列和字串的高效寫入, 可以指定緩沖區大小,或者可以接受默認大小, 默認值足夠大,可用于大多數用途,
構造方法:
- BufferedReader(Reader in)
- BufferedWriter(Writer out)
import java.io.*;
public class Demo {
public static void main(String[] args) throws IOException {
// BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt"));
// bw.write("hello\r\n");
// bw.write("world");
// bw.close();
BufferedReader br = new BufferedReader(new FileReader("bw.txt"));
//一次讀取一個字符資料
// int len;
// while((len = br.read()) != -1){
// System.out.print((char)len);
// }
//一次讀取一個字符陣列
int len;
char [] c = new char[1024];
while((len = br.read(c)) != -1){
System.out.print(new String(c,0,len));
}
br.close();
}
}
字符緩沖流特有功能
- BufferedWriter
- void newLine():寫一行行分隔符,行分隔符字串由系統屬性定義
- BufferedReader:
- public String readLine():讀一行文字,結果包含行的內容的字串,不包括任何行終止符,如果流的結尾已經到達,則為null
import java.io.*;
public class Demo {
public static void main(String[] args) throws IOException {
/* BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt"));
for (int i = 0; i < 10; i++){
bw.write("hello"+i);
bw.newLine();
}
bw.close();*/
BufferedReader br = new BufferedReader(new FileReader("bw.txt"));
String line;
while((line = br.readLine()) != null){
System.out.println(line);
}
br.close();
}
}
JDK7之后的例外處理
格式:
try(定義流物件){
可能出現例外的代碼;
}catch(例外類 名變數名){
例外的處理代碼;
}
自動釋放資源
JDK9之后的例外處理
定義輸入流物件;
定義輸出流物件;
try(輸入流物件;輸出流物件){
可能出現例外的代碼;
}catch(例外類 名變數名){
例外的處理代碼;
}
自動釋放資源
例如:
package 復制檔案例外加入例外處理;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Demo {
public static void main(String[] args) {
}
//JDK9的改進
private static void method3() throws IOException{
FileReader fr = new FileReader("fr.txt");
FileWriter fw = new FileWriter("fw.txt");
try(fr;fw){
int len;
char [] chars = new char[1024];
while ((len = fr.read(chars)) != -1){
fw.write(chars,0,len);
}
}catch (IOException e){
e.printStackTrace();
}
}
//JDK7的改進
private static void method2(){
try(FileReader fr = new FileReader("fr.txt");
FileWriter fw = new FileWriter("fw.txt")){
int len;
char [] chars = new char[1024];
while ((len = fr.read(chars)) != -1){
fw.write(chars,0,len);
}
}catch (IOException e){
e.printStackTrace();
}
}
//try...catch...finally
private static void method01(){
FileReader fr = null;
FileWriter fw = null;
try{
fr = new FileReader("fr.txt");
fw = new FileWriter("fw.txt");
int len;
char [] chars = new char[1024];
while ((len = fr.read(chars)) != -1){
fw.write(chars,0,len);
}
}catch (IOException e){
e.printStackTrace();
}finally {
if (fr != null){
try{
fr.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
if (fw != null){
try{
fw.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}
物件序列化流
物件序列化:就是將物件保存到磁盤中,或網路傳輸物件
這種機制就是使用一個位元組序串列示一個物件,該位元組序列包含:物件的型別、物件的資料和物件的存盤的屬性等資訊位元組序列寫到檔案之后,相當于檔案中保存了一個物件的資訊,反之,該位元組序列還可以從檔案中讀取回來,重構物件,對它進行反序列化
- 物件序列化流:ObjectOutputStream
- 物件反序列化流:ObjectInputStream
物件序列化流
ObjectOutputStream將Java物件的原始資料型別和圖形寫入OutputStream, 可以使用ObjectInputStream讀取(重構)物件, 可以通過使用流的檔案來實作物件的持久存盤, 如果流是網路套接字流,則可以在另一個主機上或另一個行程中重構物件,
構造方法:
- ObjectOutputStream(OutputStream out):創建一個寫入指定的OutputStream的ObjiectOutputStream
序列化物件的方法:
- void writeObject(Object obj):將指定的物件寫入ObjectOutputStream
注意:物件所屬的類需要實作Serializable介面.不實作此介面將不會使任何狀態序列化或反序列化(僅是一個標識介面,無需要重新的方法)
物件反序列化流
ObjectInputStream反序列化先前使用ObjectOutputStream撰寫的原始資料和物件,
構造方法:
- ObjectInputStream(InputStream in) 創建從指定的InputStream讀取的ObjectInputStream,
反序列化物件的方法:
- Object readObject():從ObjectInputStream讀取一個物件
- 用 transient 關鍵字修飾的成員變數不會被序列化
- 用物件序列流序列化了一個物件后,假如我們修改了物件所屬的類檔案,讀取資料會拋出:InvalidClassException例外.我們可以給物件所屬的類加一個serialVersionUID來解決這個問題,
private static final long serialVersionUID = 42L;
import java.io.Serializable;
public class Student implements Serializable {
private static final long serialVersionUID = 42L;
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class Demo {
public static void main(String[] args) {
try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("oos.txt"))
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("oos.txt"))){
Student student = new Student("張三",20);
oos.writeObject(student);
Object obj = ois.readObject();
Student s = (Student)obj;
System.out.println(s.getName() + "," + s.getAge());
}catch (IOException | ClassNotFoundException e){
e.printStackTrace();
}
}
}
Properties
- 是一個Map體系的集合類
- Properties可以保存到流中或從流中加載
mport java.util.Properties;
import java.util.Set;
public class Demo {
public static void main(String[] args) {
Properties p = new Properties();
p.put("張三",20);
p.put("李四",18);
p.put("王五",19);
Set<Object> keys = p.keySet();
for (Object key : keys){
System.out.println(p.get(key));
}
}
}
特有方法:
- Objiec setProperty(String key,String value) 設值集合的鍵和值,都是String型別,底層呼叫Hashtable方法put
- String getProperty(String key) 使用此屬性串列中指定的鍵搜索屬性
- Set
stringPropertyNames() 從該屬性串列回傳一個不可修改的鍵集,其中鍵及其對應的值是字串
import java.util.Properties;
import java.util.Set;
public class Demo2 {
public static void main(String[] args) {
//Objiec setProperty(String key,String value)
Properties p = new Properties();
p.setProperty("張三", "19");
p.setProperty("李四", "20");
p.setProperty("王五", "18");
System.out.println(p);
System.out.println("--------------");
//String getProperty(String key)
String zs = p.getProperty("張三");
System.out.println(zs);
System.out.println("--------------");
//Set<String> stringPropertyNames()
Set<String> keys = p.stringPropertyNames();
for (String key : keys) {
System.out.println(key);
}
System.out.println("------------------");
Set<String> names = p.stringPropertyNames();
for (String key : names) {
String values = p.getProperty(key);
System.out.println(key + "," + values);
}
}
}
Properties與IO流
- void load(InputStream inStream) 從輸入位元組流讀取屬性串列(鍵和元素對)
- void load(Reader reader)從輸入字符流讀取屬性串列(鍵和元素對)
- void store(OutputStream out,String comments)將此屬性串列(鍵和元素對)寫入此Properties表中,以適合于使用load(InputStream)方法的格式寫入輸出位元組流
- void store(Writer writer, String comments)將此屬性串列(鍵和元素對)寫入此Properties表中,以適合使用load(Reader)方法的格式寫入輸出字符流
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
public class Demo {
public static void main(String[] args) throws IOException{
// mystore();
myload();
}
private static void mystore() throws IOException {
Properties p = new Properties();
p.setProperty("張三","20");
p.setProperty("李四","19");
p.setProperty("王五","18");
//void store(OutputStream out,String comments) comments描述
FileWriter fw = new FileWriter("IO流\\fw.txt");
p.store(fw,null);
fw.close();
}
private static void myload() throws IOException{
Properties p = new Properties();
FileReader fr = new FileReader("IO流\\fw.txt");
p.load(fr);
System.out.println(p);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/198230.html
標籤:Java
上一篇:年末得到美團/京東/螞蟻金服Java崗內推,分享我的6點面試經驗
下一篇:追蹤將服務器CPU耗光的兇手
