天天看點

Java I/OJava I/O

Java I/O

作用:通過資料流,序列化,檔案系統,來提供輸入和輸出。

流:當程式需要讀取資料時,會開啟一個通向資料源的流。

資料源可以是檔案,記憶體或網絡連接配接。

寫入資料,開啟一個通向目的地的流。

處理資料類型:位元組型,字元型資料流向不同:輸入流(讀),輸出流(寫)。

1.File檔案操作類-既可以描述具體檔案也可以描述檔案夾

File類是唯一一個與檔案本身操作(建立,删除,取得資訊)有關的程式類

産生File對象:

public File(String pathname):根據檔案的絕對路徑來産生對象

public File(ERI uri):根據網絡産生File對象

1.1 常用·操作方法

建立新檔案:

public boolean createNewFile() throws IOException

判斷檔案是否存在

public boolean exists()

删除檔案

public boolean deleate()

檔案分隔符File.separator

1.2 目錄操作

取得父路徑的File對象

public File getParentFile()

取得父路徑的目錄

pblic String getParent()

建立多級父路徑(一次性建立多級不存在的父路徑)

public boolean mkdirs()

使用檔案目錄操作:

1.(取得File對象)

File file = new File(…);

2.(判斷父路徑是否存在,不存在建立多級父路徑

if(!file.getParentFile().exists){

file.getParentFile().mkdirs();}

3.(判斷檔案是否存在,不存在則建立檔案)

if(file.exists()){

System.out.println(“檔案已存在”);}

else{ try{

file.creatNewFile(); }

catch (IOException e){

e.printStackTrace(); }}

**取得檔案資訊

判斷File對象是否是檔案

public boolean isFile()

判斷File對象是否是檔案夾

public boolean isDirectory()

取得檔案大小-位元組為機關

public long length()

取得上次修改時間

public long lastModified()

列出一個目錄的全部組成 --檔案搜尋

public File[] listFiles()

1.取得File對象

File file = new File(…);

//表示檔案确實存在

if (file.exists() && file.isFile){

System.out.println(file.length()); //檔案大小 位元組

System.out.println(file.lastModified()); //時間}

//判斷file對象确實存在且是個檔案夾

if (file.exists() && file isDirectory ()){

File[] files = file.listFiles();

for(File file1 : files){

System.out.println(files);}}

列出目錄中的所有級的資訊***

由于File提供的isDirectory()方法隻能列出目錄中的一級資訊是以通過遞歸實作

import java.io.File;

/**
 * @Author: BaiMiao
 * @Date: 2019/10/28 15:52
 * @Description:
 * 列出目錄中所有級的資訊,遞歸實作
 * File提供的isDirectory()方法隻能列出目錄中的一級資訊。
 */
public class TestIO {
    public static void main(String[] args) {
        File file=new File(File.separator+"F:"+File.separator+
                "user"+File.separator+"bm");
        long start=System.currentTimeMillis();
        listAllFiles(file);
        long end=System.currentTimeMillis();
        System.out.println("所需時間為:"+(end-start)+"毫秒");
    }
    public static void listAllFiles(File file){
        if(file.isDirectory()){
            File[] result=file.listFiles();
            if(result!=null){
                for(File file2:result){
                    listAllFiles(file2);
                }
            }
        }else{
            System.out.println(file);
            //file.delete();則變成一個惡意程式
        }
    }
}
           

2.位元組與字元流

檔案内容作輸出java.io包流分為兩類:輸入流與輸出流

位元組(byte)流 是原生操作,無需轉換

可以處理文本檔案,圖像,音樂,視訊等資源InputStream,OutputStream

字元(char)流 是經過處理後的操作** 隻用于進行中文文本Reader,Writer

流模型的操作流程:

1.取得終端對象

2.根據終端對象取得輸入輸出流

3.根據輸入輸出流進行資料讀取與寫入

4..關閉流

IO操作屬于資源處理,是以的資源處理(IO操作,資料庫操作,網絡操作)在使用後一定要關閉

位元組輸出流OutputStream

1.public void write(byte b[]) throws IOException:将給定的位元組數組全部輸出

2.public void write(byte b[], int off, int len) throws IOException 将給定的字元數組以off位置開始輸出len長度後停止輸出

3.public abstract void write(int b) throws IOException 輸出單個位元組

使用OutputStream輸出資料時,若指定的檔案不存在,FileOutputStream會自動建立檔案(不包含建立目錄)

使用FileOutputStream輸出内容時,預設是檔案内容的覆寫操作

若要進行檔案内容的追加,

使用如下構造方法public FileOutputStream(File file, boolean append)

1.取得終端對象File file = new File(pathname:“c:\Users\38314\Desktop\TestIO.txt”);

2.根據指定檔案的輸出流OutputStream out = new FileOutputStream(file);

3.進行資料的輸出String str = “hello world”;Out.write(str.getBytes());

4.關閉流out.close();

AutoCloseable自動關閉接口,要使用此接口,必須使用try-catch塊推薦顯示關閉

2.2位元組輸入流

InputStreampublic abstract class InputStream implementsCloseable

public int read(byte b[]) throws IOException将讀取的内容放入位元組數組中

傳回值有如下三種情況:

1.傳回b.length 未讀取的資料>存放的緩存區大小,傳回位元組數組大小

2.傳回大于0的整數,此整數小于b.length 此時未讀取的資料<存放的緩存區大小,傳回剩餘資料大小

3.傳回-1 --終止标記 此時資料已經讀取完畢

1.取得終端對象File file = new file();

2.取得相應輸入流InputStream in = new FileInputStream(file);

3.進行資料的讀取byte[] data = new byte[1024];

int len = in.read(data);

System.out.println(new String(data,offset:0,len));

4.關閉流in.close();

import java.io.IOException;
import java.io.InputStream;

/**
 * @Author: BaiMiao
 * @Date: 2019/10/27 9:32
 * @Description:智能回複客服
 */
public class TestFile {
    public static void main(String[] args) throws IOException {
        InputStream in=System.in;
        System.out.print("請問有什麼需要幫助:");
        byte[] data=new byte[1024];
        int len=in.read(data);
        String str=new String(data,0,len);
        if(str.equals("你好\n"))
            System.out.println("客服小k:你好!");
        else if(str.equals("再見\n"))
            System.out.println("好的~親");
    }
}
           

2.3字元輸出流write --适用于進行中文文本

public void write(String str) throws IOException

字元流可以直接支援字元串的輸出

字元流若未關閉,資料在緩存區存放,不會輸出到目标終端。

要想将資料輸出,要麼将輸出流關閉 要麼使用flush()強制重新整理緩存區

1.取得File對象File file = new File(pathname:“c:\Users\38314\Desktop\TestIO.txt”);

2.取得字元輸出流Writer writer = new FileWriter(file);

3.資料輸出write.write("");

4.關閉流write.close();

2.4字元輸入流Reader

public int read(char cbuf[]) throws IOException

1.取得File對象File file = new File(pathname:“c:\Users\38314\Desktop\TestIO.txt”);

2.取得字元輸入流Reader reader = new FileReader(file);

3.資料輸出char[] data = new char[1024];

int len = reader.read(data);

System.out.println(“檔案内容為”+new String(data,offset:0,len));

4.關閉流reader.close();

3.轉換流(位元組流->字元流)

OutputStreamWriter(位元組輸出流->字元輸出流)

InputStreamReader(字元輸入流->位元組輸入流)

字元流的具體子類大都是通過轉換流将位元組流轉為字元流(FileWriter繼承轉換流)

通過程式進行檔案拷貝

public static void main(String[] args) throws Exception{

//源檔案路徑String sourceFilePath = “”;

//目标檔案路徑String destFilePath = “”;

copyFile(sourceFilePath, destFilePath); }

public static void copyFile(String sourceFilePath, String destFilePath) throws Exception{

//1.取得源檔案與目标檔案的File對象File sourceFile = new File(sourceFilePath);

File destFile = new File(destFilePath);

//2.取得輸入輸出流InputStream in = new FileInputStream(sourceFile);

OutputStream out = new FileOutputStream(destFile);

//3.資料輸入輸出int len = 0;byte[] data = new byte[1024];

long start = System.currentTimeMillis();

while( (len = in.read()) !=-1){

out.write(data,0,len); }

long end = System.currentTimeMillis();System.out.println(“共耗時:”+(end-start)+“毫秒”);}

4.字元編碼 -就使用UTF-8

1.GBK,GB2312:GBK包含簡體與繁體中文,GB2312隻包含簡體中文

2.UNICODE:java提供的16位進制編碼,可以描述世界上任意語言,但是編碼進制數太高,編碼體積較大

3.ISO-8859-1:國際通用編碼,不支援中文,浏覽器預設編碼

4.UTF編碼:結合UNICODE 和 ISO-8859-1,最常采用的是UTF-8

亂碼産生原因:

1.編解碼不一緻 (95%)

2.由于資料丢失造成的亂碼(5%)

5.記憶體流(以記憶體為終端的輸入輸出流)

位元組記憶體流ByteArrayInputStream,ByteArrayOutputStream

字元記憶體流CharArrayReader,CharArrayWriter

将指定的位元組數組内容存放到記憶體中

public ByteArrayInputStream(byte buf[])

public ByteArrayOutputStream()

6.列印流 -(輸出流的強化版本)

位元組列印流:PrintStream字元列印流:PrintWriter

列印流的設計屬于裝飾設計模式-基于抽象類特點:

核心依然是某個類(OutputStream提供的write())的功能,

但是為了得到更好的操作效果,讓其支援的功能更多一些,使用裝飾類(PrintStream)

優點:很容易更換裝飾類來達到不同的操作效果

缺點:造成類結構複雜

7.System類對于IO的支援

标準輸出(顯示屏):System.out

标準輸入(鍵盤):System.in

錯誤輸出 : System.err

7.1系統輸出系統提供的out(輸出到顯示器,顔色為黑色),err(輸出到顯示器,顔色為紅色)對象均是PrintStream的對象

以後輸出采用日志(Log)-格式化輸出

7.2系統輸入System.in是InputStream的直接對象

8.兩種輸入流

8.1 BufferedReader,BufferedInputStreamreadline()直接讀取一行輸入,預設以回車換行

8.2 java.util.Scanner支援正規表達式

hasNextXX(): 判斷是否有指定類型資料輸入

nextXX():擷取指定類型資料useDelimiter(“指定分隔符”)

Scanner scanner = new Scanner(System.in);

System.out.println(“請輸入内容”);scanner.useDelimiter("\n");

//自定義分隔符if(scanner.hasNext){

System.out.println(“輸入内容為”+scanner.next());}

File PrintStream Scanner

transient:部分屬性被序列化