1、IO(Input Output)流的概述
1、io的概念及其特點
流是一組有順序的,有起點和終點的字節集合,是對數據傳輸的總稱或抽象。即數據在兩設備間的傳輸稱爲流.
宏觀上io有以下特點。
· IO流用來處理設備之間的數據傳輸。
· Java對數據的操作是通過流(系統資源)的方式。
· Java用於操作流的對象都在java.io包中。
· 流按操作數據分爲兩種:字節流與字符流。
· 流按流向分爲:輸入流,輸出流。
2、io的體系結構
2、IO中常用的類
1. File(文件特徵與管理):用於文件或者目錄的描述信息,例如生成新目錄,修改文件名,刪除文件,判斷文件所在路徑等。
2. InputStream(二進制格式操作):抽象類,基於字節的輸入操作,是所有輸入流的父類。定義了所有輸入流都具有的共同特徵。
3.OutputStream(二進制格式操作):抽象類。基於字節的輸出操作。是所有輸出流的父類。定義了所有輸出流都具有的共同特徵。
4.Reader(文件格式操作):抽象類,基於字符的輸入操作。
5. Writer(文件格式操作):抽象類,基於字符的輸出操作。
6. RandomAccessFile(隨機文件操作):一個獨立的類,直接繼承至Object.它的功能豐富,可以從文件的任意位置進行存取(輸入輸出)操作。
3、File詳解
1、File(文件特徵與管理)
用來將文件或者文件夾封裝成對象。
方便對文件與文件夾的屬性信息進行操作。
File對象可以作爲參數傳遞給流的構造函數。
2、File API
package com.xyq.file;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
public class FileTest {
public static void main(String[] args) throws IOException {
// method_1();
// method_2();
// method_3();
// method_4();
// method_5();
// method_6();
// method_7();
File file = new File("E:\\test");
FilesFilter(file);
}
/*
* file類的四個靜態常量
* public static String separator 與系統有關的目錄分隔符 Windows中 :\
* public static char separatorChar Linux中: /
* public static String pathSeparator 與系統有關的路徑分隔符 Windows中 ; 分號
* public static char pathSeparatorChar Linux中 : 冒號
*/
public static void method_1(){
File file = new File("E:\\");
String s = file.separator;
System.out.println(s);
s = file.pathSeparator;
System.out.println(s);
}
/*
* file 類的構造方法
* 1. File(String pathName)
* 2. File(String parent, String child)
* 3. File(File parent, String child)
*/
public static void method_2(){
File file = new File("E:\\KeCheng");
File file2 = new File("E:\\","KeCheng");
File file3 = new File(file, "");
System.out.println(file);
System.out.println(file2);
System.out.println(file3);
}
/* File類的創建方法 ,目標文件或者路徑存在時,均會返回false
* 1. boolean createNewFile() 創建文件,成功返回true
* 2. boolean mkdir() 創建文件夾,成功返回true,只能創建一級目錄
* 3. boolean mkdirs() 創建多級文件夾
*/
public static void method_3()throws IOException{
File file = new File("E:\\text.txt");
System.out.println(file.createNewFile());
File file2 = new File("E:\\test\\test\\test");
System.out.println(file2.mkdirs());
}
/* File類的刪除方法
* 1. boolean delete() 刪除指定目錄或者文件,成功返回true,注意此刪除不走回收站,文件夾不爲空時沒有辦法刪除
* 2. void deleteOnExit() jvm退出前刪除,
*/
public static void method_4()throws IOException{
File file = new File("E:\\test.txt");
System.out.println(file.createNewFile());
System.out.println(file.delete());
}
/* File類的判斷方法
* boolean exists() 判斷構造方法中封裝的路徑或者文件是否存在
* boolean isAbsolute() 判斷構造方法中封裝的路徑是不是絕對路徑,是返回真
* boolean isDirectory() 判斷是不是路徑,是返回true
* boolean isFile() 判斷是不是文件,是返回true
* boolean isHidden() 判斷封裝的路徑(包括文件)是不是隱藏屬性是返回true
*/
public static void method_5(){
File file = new File("E:\\abcde");
System.out.println(file.exists());
System.out.println(file.isAbsolute());
}
/*
* File類的獲取方法
* 1.String getName() 獲取封裝路徑最後部分的名字,此方法不會判斷路徑是否存在,使用之前最好判斷
* 2.String getParent() 返回封裝路徑的父路徑
* 3.File getParentFile() 返回封裝路徑的父路徑的File對象
* 4.String getAbsolutePath() 返回封裝路徑的絕對路徑
* 5.File getAbsoluteFile() 返回封裝路徑的絕對路徑的File對象
*/
public static void method_6(){
File file = new File("scr");
System.out.println(file.getAbsoluteFile().getParent());
}
/*
* File的list方法
* 1. static File[] listRoots() 靜態的方法,列出系統所以的根,光驅和移動設備存儲也會算進去
* 2. String[] list()返回File構造方法封裝的路徑下的所有文件和文件夾
* 3. File[] listFiles()返回File構造方法封裝的路徑下的所有文件和文件夾,返回的Filed對象,帶全路徑
*/
public static void method_7(){
File []roots = File.listRoots();
for(File file:roots){
System.out.println(file);
}
}
//遞歸過濾方法的實現,選出目錄下的*.java文件
//直接使用匿名內部內實現了FileFilter接口
public static void FilesFilter(File file){
File []files = file.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
if (pathname.getName().endsWith(".java") || pathname.isDirectory()) {
return true;
} else {
return false;
}
}
});
if(files != null){
for(File file2:files){
if(file2.isFile()){
System.out.println(file2);
}else {
FilesFilter(file2);
}
}
}
}
}
4、IO流常用基類
- 字節流的抽象基類:
- InputStream 讀取一個文本文件中的數據
- OutputStream 向一個文本文件中寫入數據
- 用輸出流還是輸入流 參考標準是內存
字符流的抽象基類:
- Reader
- Writer
比較常用的字節流
- FileInputStream
- FileOutputStream
- BufferedInputStream
- BufferedOutputStream
4.1字節輸出流——FileOutputStream
注意 在創建字節輸出流對象用於操作文件,在對象初始化時必須明確數據存儲的目的地,輸出流所關聯的目的地,如果不存在,則會自動創建;如果存在,則會覆蓋。
具體用法 例 向一個文本文件中寫入數據
package com.xyq.outputstream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamTest {
/*
* 將數據寫入到文件中。
* 使用字節輸出流。FileOutputStream。
*/
public static void main(String[] args) throws IOException{
//1、創建文件夾
File dir = new File("tempFile");
if(!dir.exists()){
dir.mkdir();
}
//顯示創建文件的路徑
System.out.println(dir.getAbsoluteFile().getParent());
// 2、創建字節輸出流對象,用於操作文件,在對象初始化時必須明確數據存儲的目的地。
// 輸出流所關聯的目的地,如果不存在,會自動創建。如果存在,則覆蓋。
FileOutputStream fos = new FileOutputStream("tempFile\\test.txt");
// 3、調用輸出流的寫功能。
fos.write("abcd".getBytes());
//4、釋放資源
fos.close();
}
}
4.2字節輸入流——FileInputStream
具體用法 例 讀取一個文本文件中的數據
4.2.1 read():一個一個字節的讀
package com.xyq.outputstream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputStreamTest {
public static void main(String[] args) throws IOException{
//1、爲了確保文件一定在讀之前是存在的,將字符串路徑封裝成File對象。
File file = new File("tempFile\\test.txt");
//2、判斷文件是否存在
if(!file.exists()){
throw new RuntimeException("要讀取的文件不存在");
}
//3、創建文件字節讀取流對象時,必須明確與之關聯的數據源。
FileInputStream fis = new FileInputStream(file);
//4、調用讀方法
int by = 0;
while ((by = fis.read()) != -1) {
System.out.println(by);
}
//5、關閉資源
fis.close();
}
}
4.2.2read(byte[] buf):先把字節存入到緩衝區字節數組中,一下讀一個數組(常用)
package com.xyq.outputstream;
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputStreamTest2 {
//1、定義緩衝區的大小可以是1024的整數倍
private static final int SIZE = 1024;
public static void main(String[] args) {
//2、創建文件字節讀取流對象。
FileInputStream fis = null;
try {
fis = new FileInputStream("tempFile\\test.txt");
//3、創建一個字節數組。
byte [] buf = new byte[SIZE];
//4、調用讀方法
int len = 0;// len記錄的是往字節數組裏存儲的字節個數。
while((len = fis.read(buf)) != -1){
// 將字節數組轉成字符串,打印並看一下效果。
System.out.println(new String(buf, 0, len));
}
} catch (IOException e) {
// 將異常信息寫入到日誌文件中以進行記錄。
}finally {
//5、關閉資源
if(fis != null){
try {
fis.close();
} catch (IOException e) {
// 一般可以throw RuntimeException異常,或者將異常信息寫入到日誌文件中以進行記錄。
e.printStackTrace();
}
}
}
}
}
4.3緩衝流-BufferedInputStream、BufferedOutputStream
4.3.1有了InputStream和OutputStream爲什麼還要有BufferedInputStream和BufferedOutputStream?
因爲不帶緩衝的操作,每讀一個字節就要寫入一個字節,由於涉及磁盤的IO操作相比內存的操作要慢很多,所以不帶緩衝的流效率很低。帶緩衝的流,可以一次讀很多字節,但不向磁盤中寫入,只是先放到內存裏。等湊夠了緩衝區大小的時候一次性寫入磁盤,這種方式可以減少磁盤操作次數,速度就會提高很多!
同時正因爲它們實現了緩衝功能,所以要注意在使用BufferedOutputStream寫完數據後,要調用flush()方法或close()方法,強行將緩衝區中的數據寫出。否則可能無法寫出數據。
4.3.2 BufferedInputStream和BufferedOutputStream的具體用法
例 圖片的複製package com.xyq.outputstream;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyPicBufferTest {
//1、定義緩衝區的大小可以是1024的整數倍
private static final int SIZE = 1024;
public static void main(String[] args) {
File oldFile = new File("tempFile\\1.jpg");
File newFile = new File("tempFile\\abc.jpg");
copyFile(oldFile, newFile);
}
public static void copyFile(File oldFile, File newFile){
//2、創建流
FileInputStream fis = null;
BufferedInputStream bis = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
try {
fis = new FileInputStream(oldFile);
bis = new BufferedInputStream(fis);
fos = new FileOutputStream(newFile);
bos = new BufferedOutputStream(fos);
//3、進行讀寫操作
byte []byf = new byte[SIZE];
int len = 0;// len記錄的是往字節數組裏存儲的字節個數。
//先讀後寫
while((len = bis.read(byf)) != -1){
bos.write(byf, 0, len);
}
bos.flush();//沖刷沒有達到緩存限度的數據,確保數據全部寫完
System.out.println("複製完成。。。");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//4、關閉資源
if(fis != null){
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(bis != null){
try {
bis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(fos != null){
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(bos != null){
try {
bos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}