第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

全部開(kāi)發(fā)者教程

Java 輸入輸出流

本小節(jié)將會(huì)介紹基本輸入輸出的 Java 標(biāo)準(zhǔn)類,通過(guò)本小節(jié)的學(xué)習(xí),你將了解到什么是輸入和輸出什么是流;輸入輸出流的應(yīng)用場(chǎng)景,File類的使用,什么是文件,Java 提供的輸入輸出流相關(guān) API 等內(nèi)容。

1. 什么是輸入和輸出(I / O)

1.1 基本概念

輸入/輸出這個(gè)概念,對(duì)于計(jì)算機(jī)相關(guān)專業(yè)的同學(xué)并不陌生,在計(jì)算中,輸入/輸出Input / Output,縮寫(xiě)為 I / O)是信息處理系統(tǒng)(例如計(jì)算機(jī)))與外界(可能是人類或其他信息處理系統(tǒng))之間的通信。輸入是系統(tǒng)接收的信號(hào)或數(shù)據(jù),輸出是從系統(tǒng)發(fā)送的信號(hào)或數(shù)據(jù)。

那么在 Java 中,什么是輸入和輸出呢?要理解這個(gè)概念,可將 Java 平臺(tái)視作一個(gè)系統(tǒng)。Java 平臺(tái)是一個(gè)孤立的系統(tǒng),系統(tǒng)之外的所有東西都是它的環(huán)境。系統(tǒng)與其環(huán)境之間的交互是一種雙向?qū)υ?。系統(tǒng)要么從其環(huán)境接收消息,要么將其消息傳遞給環(huán)境。當(dāng)系統(tǒng)接收到消息時(shí),將其稱為輸入,與之相反的是輸出。

本小節(jié)將介紹 Java 的基本輸入和輸出,包括從鍵盤(pán)讀取文本輸入,將文本輸出到屏幕以及從文件系統(tǒng)讀取/寫(xiě)入文件。

Java 提供了兩個(gè)用于 I / O 的包:較舊的java.io包(不支持符號(hào)鏈接)和較新的java.nio(“new io”)包,它對(duì)java.nio.file的異常處理進(jìn)行了改進(jìn)。

1.2 簡(jiǎn)單的 Java 輸出——打印內(nèi)容到屏幕

一直以來(lái),我們都在向屏幕輸出內(nèi)容以驗(yàn)證我們編寫(xiě)的代碼邏輯。向屏幕輸出內(nèi)容非常簡(jiǎn)單,可以由以下兩種方式來(lái)完成:

// 打印 Hello World,不換行
System.out.print("Hello World");
// 打印 Hello Java,并換行
System.out.println("Hello Java");

1.3 簡(jiǎn)單的 Java 輸入——從鍵盤(pán)輸入

java.util包下的Scanner類可用于獲取用戶從鍵盤(pán)輸入的內(nèi)容,我們?cè)?a href="http://idcbgp.cn/wiki/javalesson/scanner.html">Java Scanner 類這一小節(jié)已經(jīng)介紹過(guò)具體使用,實(shí)例如下:

import java.util.Scanner;

/**
 * @author colorful@TaleLin
 */
public class ScannerDemo {
    public static void main(String[] args) {
        // 創(chuàng)建掃描器對(duì)象
        Scanner scanner = new Scanner(System.in);
        System.out.println("請(qǐng)輸入您的姓名:");
        // 可以將用戶輸入的內(nèi)容掃描為字符串
        String name = scanner.nextLine();
        // 打印輸出
        System.out.println("你好 ".concat(name).concat(" ,歡迎來(lái)到慕課網(wǎng)!"));
        // 關(guān)閉掃描器
        scanner.close();
    }
}

運(yùn)行結(jié)果:

請(qǐng)輸入您的姓名:
Colorful
你好 Colorful ,歡迎來(lái)到慕課網(wǎng)!

2. 什么是流(Stream)

Java 中最基本的輸入/輸入是使用流來(lái)完成的。

流是代表數(shù)據(jù)源和數(shù)據(jù)目標(biāo)的對(duì)象,怎么理解這句話呢?簡(jiǎn)單來(lái)說(shuō),可以讀取作為數(shù)據(jù)源的流,也可以寫(xiě)入作為數(shù)據(jù)目標(biāo)的流。Java中的流是長(zhǎng)度不確定的有序字節(jié)序列,它是一連串流動(dòng)的字符,是以先進(jìn)先出的方式發(fā)送信息的通道。

3. 輸入輸出流的應(yīng)用場(chǎng)景

上面我們已經(jīng)了解了輸入輸出流的基本概念,那么它具體是做什么用的呢?

web產(chǎn)品的開(kāi)發(fā)中,最常開(kāi)發(fā)的功能就是上傳文件到服務(wù)器了,這個(gè)文件的讀寫(xiě)過(guò)程就要用到輸入輸出流。對(duì)于計(jì)算機(jī)中文件的讀寫(xiě)、復(fù)制和刪除等操作也都要用到輸入輸出流。輸入輸出流可以說(shuō)是無(wú)處不在,下面我們將會(huì)介紹 Java 中輸入輸出流相關(guān)的 API

4. File 類

在 Java 中,提供了java.io.File類對(duì)文件和目錄進(jìn)行操作。

File 意思為文件,文件在計(jì)算機(jī)中非常重要,我們編寫(xiě)的 word 文檔、PPT 演示文稿、運(yùn)行游戲的.exe可執(zhí)行文件以及我們編寫(xiě)的 Java 源代碼等等都是文件。

4.1 實(shí)例化

要實(shí)例化File對(duì)象,需要傳入一個(gè)文件或目錄的路徑。

File 類提供了如下 4 個(gè)構(gòu)造方法:

  1. File(File parent, String child):從父抽象路徑名和子路徑名字符串創(chuàng)建新的文件實(shí)例;
  2. File(String pathName):通過(guò)將給定的路徑名字符串轉(zhuǎn)換為抽象路徑名,創(chuàng)建一個(gè)新的文件實(shí)例(最常用);
  3. File(String parent, String child):從父路徑名字符串和子路徑名字符串創(chuàng)建新的文件實(shí)例;
  4. File(URI uri):通過(guò)將給定的文件: URI轉(zhuǎn)換為抽象路徑名,創(chuàng)建一個(gè)新的文件實(shí)例。

Windows系統(tǒng)為例,在桌面下有一個(gè)imooc目錄,該目錄下有一個(gè)Hello.java文件和一個(gè)空的images目錄,截圖如下:

我們可以單擊Windows的路徑欄,來(lái)獲取imooc目錄的絕對(duì)路徑:

有了目錄和文件以及路徑。我們分別實(shí)例化兩個(gè)File對(duì)象,實(shí)例如下:

import java.io.File;

public class FileDemo1 {
    public static void main(String[] args) {
        // 傳入目錄絕對(duì)路徑
        File dir = new File("C:\\Users\\Colorful\\Desktop\\imooc\\images");
        // 傳入文件絕對(duì)路徑
        File file = new File("C:\\Users\\Colorful\\Desktop\\imooc\\Hello.java");
        // 打印兩個(gè)File對(duì)象
        System.out.println(dir);
        System.out.println(file);
    }
}

我們可以直接打印File對(duì)象,File類重寫(xiě)了toString()方法,查看 Java 源碼,toString()方法直接返回了getPath()實(shí)例方法,此方法返回構(gòu)造方法傳入的路徑字符串:

運(yùn)行結(jié)果:

C:\Users\Colorful\Desktop\imooc\images
C:\Users\Colorful\Desktop\imooc\Hello.java

上面代碼中,使用\\表示Windows下的路徑分隔符\,LinuxMacOS下使用正斜杠/作為路徑分隔符。假設(shè)是同樣的目錄結(jié)構(gòu),在MacOSLinux下是這樣表示的:

File dir = new File("/Users/Colorful/Desktop/imooc/images");

因?yàn)?code>Windows平臺(tái)和其他平臺(tái)路徑分隔符不同,使用不同平臺(tái)的開(kāi)發(fā)者就難以保證路徑分隔符的統(tǒng)一。

為了保證代碼更好的兼容性,File類下提供了一個(gè)靜態(tài)變量separator,用于表示當(dāng)前平臺(tái)的系統(tǒng)分隔符:

// 根據(jù)當(dāng)前平臺(tái)輸出 / 獲取 \
System.out.println(File.separator);

4.2 絕對(duì)路徑和相對(duì)路徑

在實(shí)例化File對(duì)象時(shí),既可以傳入絕對(duì)路徑,也可以傳入相對(duì)路徑。

絕對(duì)路徑是以根目錄開(kāi)頭的完整的全路徑,上面代碼實(shí)例中傳入的是絕對(duì)路徑,我們?cè)賮?lái)看看什么是相對(duì)路徑,以及如何傳入相對(duì)路徑。

相對(duì)路徑指的是當(dāng)前文件所在的路徑引起的跟其它文件(或文件夾)的路徑關(guān)系。聽(tīng)起來(lái)有點(diǎn)繞,我們舉例來(lái)說(shuō)明一下,在imooc目錄下新建一個(gè)FileDemo2.java文件,此時(shí)imooc目錄的文件目錄樹(shù)結(jié)構(gòu)如下:

└── imoooc
    ├── FileDemo2.java
    ├── Hello.java
    └── images

內(nèi)容如下:

import java.io.File;
import java.io.IOException;

public class FileDemo2 {
    public static void main(String[] args) throws IOException {
        // 傳入目錄相對(duì)路徑
        File dir = new File(".\\images");
        File imoocDir = new File("..\\imooc");
        // 傳入文件相對(duì)路徑
        File file = new File(".\\Hello.java");
    }
}

上面代碼的File構(gòu)造方法中傳入的就是相對(duì)路徑,代碼中的.表示當(dāng)前目錄,..表示上級(jí)目錄。

Tips: 我們?cè)趯?shí)例化 File 對(duì)象時(shí),不會(huì)產(chǎn)生對(duì)磁盤(pán)的操作,因此即使傳入的文件或目錄不存在,代碼也不會(huì)拋出異常。只有當(dāng)調(diào)用 File 對(duì)象下的一些方法時(shí),才會(huì)對(duì)磁盤(pán)進(jìn)行操作。

File 對(duì)象下有 3 個(gè)表示路徑的實(shí)例方法:

  1. String getPath():將抽象路徑名轉(zhuǎn)換為路徑名字符串;
  2. String getAbsolute():返回此抽象路徑名的絕對(duì)路徑名字符串;
  3. String getCanonicalPath():返回此抽象路徑名的規(guī)范路徑名字符串。

我們可以調(diào)用這 3 個(gè)方法并打印結(jié)果,實(shí)例如下:

import java.io.File;
import java.io.IOException;

public class FileDemo2 {
    public static void main(String[] args) throws IOException {
        // 傳入目錄相對(duì)路徑
        File imagesDir = new File(".\\images");
        File imoocDir = new File("..\\imooc");
        // 傳入文件相對(duì)路徑
        File file = new File(".\\Hello.java");
        
        System.out.println("-- imagesDir ---");
        System.out.println(imagesDir.getPath());
        System.out.println(imagesDir.getAbsolutePath());
        System.out.println(imagesDir.getCanonicalPath());

        System.out.println("-- imoocDir ---");
        System.out.println(imoocDir.getPath());
        System.out.println(imoocDir.getAbsolutePath());
        System.out.println(imoocDir.getCanonicalPath());

        System.out.println("-- file ---");
        System.out.println(file.getPath());
        System.out.println(file.getAbsolutePath());
        System.out.println(file.getCanonicalPath());
    }
}

運(yùn)行結(jié)果:

-- imagesDir ---
.\images
C:\Users\Colorful\Desktop\imooc\.\images
C:\Users\Colorful\Desktop\imooc\images
-- imoocDir ---
..\imooc
C:\Users\Colorful\Desktop\imooc\..\imooc
C:\Users\Colorful\Desktop\imooc
-- file ---
.\Hello.java
C:\Users\Colorful\Desktop\imooc\.\Hello.java
C:\Users\Colorful\Desktop\imooc\Hello.java

通過(guò)運(yùn)行結(jié)果可以看出,規(guī)范路徑名就是把...轉(zhuǎn)換為標(biāo)準(zhǔn)的絕對(duì)路徑。

4.3 判斷對(duì)象是文件還是目錄

我們可以通過(guò)如下兩個(gè)方法判斷 File 對(duì)象是文件還是目錄:

  1. boolean isFile():測(cè)試此抽象路徑名表示的文件是否為普通文件;
  2. boolean isDirectory():測(cè)試此抽象路徑名表示的文件是否為目錄。

實(shí)例如下:

import java.io.File;

public class FileDemo3 {

    public static void printResult(File file) {
        // 調(diào)用isFile()方法并接收布爾類型結(jié)果
        boolean isFile = file.isFile();
        String result1 = isFile ? "是已存在文件" : "不是已存在文件";
        // 掉用isDirectory()方法并接收布爾類型而己過(guò)
        boolean directory = file.isDirectory();
        String result2 = directory ? "是已存在目錄" : "不是已存在目錄";
        // 打印該file對(duì)象是否是已存在文件/目錄的字符串結(jié)果
        System.out.print(file);
        System.out.print('\t' + result1 + '\t');
        System.out.println(result2);
    }

    public static void main(String[] args) {
        // 傳入目錄絕對(duì)路徑
        File dir = new File("C:\\Users\\Colorful\\Desktop\\imooc\\images");
        // 傳入文件絕對(duì)路徑
        File file = new File("C:\\Users\\Colorful\\Desktop\\imooc\\test.java");
        FileDemo3.printResult(dir);
        FileDemo3.printResult(file);
    }
}

運(yùn)行結(jié)果:

C:\Users\Colorful\Desktop\imooc\images	不是已存在文件	是已存在目錄
C:\Users\Colorful\Desktop\imooc\test.java	不是已存在文件	不是已存在目錄

代碼中我們封裝了一個(gè)靜態(tài)方法printResult(),此方法打印 File 對(duì)象是否是文件/目錄。值得注意的是,我們的磁盤(pán)中不存在C:\Users\Colorful\Desktop\imooc\test.java,因此無(wú)論調(diào)用isFile()方法還是isDirectory()方法,其返回結(jié)果都為false

4.4 創(chuàng)建和刪除目錄

4.4.1 創(chuàng)建目錄

對(duì)于一個(gè)不存在的目錄,我們可以使用boolean mkdir()方法創(chuàng)建一個(gè)目錄。例如,我們想在imooc目錄下創(chuàng)建一個(gè)codes目錄,就可以使用該方法編寫(xiě)一段創(chuàng)建目錄的代碼。

實(shí)例如下:

import java.io.File;

public class FileDemo4 {

    public static void main(String[] args) {
        // 傳入目錄絕對(duì)路徑
        File dir = new File("C:\\Users\\Colorful\\Desktop\\imooc\\codes");
        if (!dir.exists()) {
            // 調(diào)用 mkdir() 方法
            boolean result = dir.mkdir();
            if (result) {
                System.out.println("目錄創(chuàng)建成功");
            }
        }
    }
}

代碼中我們調(diào)用了File對(duì)象的boolean exists()方法,此方法用于測(cè)試由此抽象路徑名表示的文件或目錄是否存在。當(dāng)不存在時(shí),我們才去創(chuàng)建目錄。

運(yùn)行代碼前,imooc文件目錄樹(shù)結(jié)構(gòu)如下:

└── imoooc
    ├── FileDemo2.java
    ├── Hello.java
    └── images

運(yùn)行結(jié)果:

目錄創(chuàng)建成功

運(yùn)行代碼后,imooc目錄下多了一個(gè)codes目錄,樹(shù)結(jié)構(gòu)如下:

└── imoooc
    ├── FileDemo2.java
    ├── Hello.java
    ├── images
    └── codes

另外,F(xiàn)ile 類也提供了一個(gè)boolean mkdirs()方法,用來(lái)創(chuàng)建由這個(gè)抽象路徑名命名的目錄,包括任何必要但不存在的父目錄。實(shí)際上是在遞歸執(zhí)行mkdir()方法。

4.4.2 刪除目錄

如果我們想要?jiǎng)h除剛剛創(chuàng)建的codes目錄,可以調(diào)用boolean delete()方法,實(shí)例如下:

import java.io.File;

public class FileDemo5 {
    public static void main(String[] args) {
        // 傳入目錄絕對(duì)路徑
        File dir = new File("C:\\Users\\Colorful\\Desktop\\imooc\\codes");
        if (dir.exists()) {
            // 調(diào)用 delete() 方法
            boolean deleted = dir.delete();
            if (deleted) {
                System.out.println("刪除目錄成功");
            }
        }
    }
}

運(yùn)行代碼前,imooc文件目錄樹(shù)結(jié)構(gòu)如下:

└── imoooc
    ├── FileDemo2.java
    ├── Hello.java
    ├── images
    └── codes

運(yùn)行結(jié)果:

刪除目錄成功

運(yùn)行代碼后,樹(shù)結(jié)構(gòu)如下:

└── imoooc
    ├── FileDemo2.java
    ├── Hello.java
    └── images

4.5 創(chuàng)建和刪除文件

對(duì)于文件類型的File對(duì)象,可以通過(guò)boolean createNewFile()方法創(chuàng)建一個(gè)新文件,使用boolean delete()方法刪除文件。其調(diào)用方法和創(chuàng)建/刪除目錄相同,此處不再贅述。

關(guān)于更多File對(duì)象的操作,可翻閱官方文檔。

5. InputStream 抽象類

5.1 概述

java.io.InputStream抽象類是 Java 提供的最基本的輸入流,它是所有輸入流的父類。其最常用的抽象方法int read()簽名如下:

public abstract int read() throws IOException;

這個(gè)方法用于讀取輸入流的下一個(gè)字節(jié),返回的int如果為-1,則表示已經(jīng)讀取到文件末尾。

InputStream與其子類的 UML 圖如下所示:

5.2 FileInputStream 實(shí)現(xiàn)類

我們將以最常用的FileInputStream實(shí)現(xiàn)類為例進(jìn)行學(xué)習(xí)。其他實(shí)現(xiàn)類大同小異,如有需要可翻閱官方文檔。

FileInputStream就是從文件流中讀取數(shù)據(jù),我們?cè)?code>imooc目錄下新建一個(gè)文本文檔Hello.txt,并輸入如下內(nèi)容:

讀取Hello.txt文件中數(shù)據(jù)的實(shí)例代碼如下:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileInputStreamDemo1 {

    public static void main(String[] args) throws IOException {
        // 實(shí)例化文件流
        FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Colorful\\Desktop\\imooc\\Hello.txt");
        for (;;) {
            int n = fileInputStream.read();
            if (n == -1) {
                // read() 方法返回-1 則跳出循環(huán)
                break;
            }
            // 將n強(qiáng)制轉(zhuǎn)換為 char 類型
            System.out.print((char) n);
        }
        // 關(guān)閉文件流
        fileInputStream.close();
    }
}

運(yùn)行結(jié)果:

Hello imooc!

如果我們打開(kāi)了一個(gè)文件并進(jìn)行操作,不要忘記使用close()方法來(lái)及時(shí)關(guān)閉。這樣可以讓系統(tǒng)釋放資源。

6. OutputStream 抽象類

6.1 概述

OutPutStream抽象類是與InputStream對(duì)應(yīng)的最基本的輸出流,它是所有輸出流的父類。其最常用的抽象方法void write(int b)簽名如下:

public abstract void write(int b) throws IOException;

這個(gè)方法用于寫(xiě)入一個(gè)字節(jié)到輸出流。

OutputStream與其子類的 UML 圖如下所示:

6.2 FileOutputStream 實(shí)現(xiàn)類

我們同樣以最常用的FileOutputStream實(shí)現(xiàn)類為例進(jìn)行學(xué)習(xí)。其他實(shí)現(xiàn)類大同小異,如有需要可翻閱官方文檔。

FileOutputStream就是向文件流中寫(xiě)入數(shù)據(jù),下面我們向imooc目錄下的文本文檔Hello.txt輸入一段字符串HHH。完整實(shí)例如下:

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileOutputStreamDemo1 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Colorful\\Desktop\\imooc\\Hello.txt");
        // 寫(xiě)入 3 個(gè)H字符
        fileOutputStream.write(72);
        fileOutputStream.write(72);
        fileOutputStream.write(72);
        fileOutputStream.close();
    }
}

運(yùn)行代碼后,Hello.txt后面成功寫(xiě)入了 3 個(gè)字符H。

7. 小結(jié)

通過(guò)本小節(jié)的學(xué)習(xí),我們知道了什么是輸入輸出流的概念,輸入輸出流經(jīng)常用于上傳文件到服務(wù)器的場(chǎng)景。想要通過(guò) Java 操作文件和目錄,要學(xué)會(huì)使用java.io.File類,InputStreamOutputStream分別是所有輸入流和所有輸出流的父類,FileInputStream實(shí)現(xiàn)了文件流的輸入,FileOutputStream實(shí)現(xiàn)了文件流的輸出。還有很多其它實(shí)現(xiàn)類我們沒(méi)有介紹到,但使用方法大同小異,希望同學(xué)可以在用到時(shí)自行查閱文檔來(lái)學(xué)習(xí)。