国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Java基礎(chǔ)教程】(四十四)IO篇 · 上:File類、字節(jié)流與字符流,分析字節(jié)輸出流、字節(jié)輸入流、字符輸出流和字符輸入流的區(qū)別~

這篇具有很好參考價(jià)值的文章主要介紹了【Java基礎(chǔ)教程】(四十四)IO篇 · 上:File類、字節(jié)流與字符流,分析字節(jié)輸出流、字節(jié)輸入流、字符輸出流和字符輸入流的區(qū)別~。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

【Java基礎(chǔ)教程】(四十四)IO篇 · 上:File類、字節(jié)流與字符流,分析字節(jié)輸出流、字節(jié)輸入流、字符輸出流和字符輸入流的區(qū)別~,# Java基礎(chǔ)教程,java,開發(fā)語言,jvm,經(jīng)驗(yàn)分享,java-ee,后端

??本節(jié)學(xué)習(xí)目標(biāo)

  • 掌握 java.io包中類的繼承關(guān)系 ;
  • 掌握 File類的使用,并且可以通過File類進(jìn)行文件的創(chuàng)建、刪除以及文件夾的列表等操作;
  • 掌握字節(jié)流或字符流操作文件內(nèi)容,字節(jié)流與字符流的區(qū)別;

1?? 文件操作類:File

java.io 包中,如果要進(jìn)行文件自身的操作 (例如:創(chuàng)建、刪除等), 只能依靠 java.io.File 類完成。File 類常用操作方法如下表所示。

方法 類型 描述
public File(String pathname) 構(gòu)造方法 傳遞完整文件操作路徑
public File(File parent, String child) 構(gòu)造方法 設(shè)置父路徑與子文件路徑
boolean createNewFile() throws IOException 普通方法 創(chuàng)建新文件
boolean exists() 普通方法 判斷給定路徑是否存在
boolean delete() 普通方法 刪除指定路徑的文件
File getParentFile() 普通方法 取得當(dāng)前路徑的父路徑
boolean mkdirs() 普通方法 創(chuàng)建多級(jí)目錄
long length() 普通方法 取得文件大小,以字節(jié)為單位返回
boolean isFile() 普通方法 判斷給定路徑是否是文件
boolean isDirectory() 普通方法 判斷給定路徑是否是目錄
long lastModified() 普通方法 取得文件的最后一次修改日期時(shí)間
String[] list() 普通方法 列出指定目錄中的全部內(nèi)容
File[] listFiles() 普通方法 列出所有的路徑以File類對(duì)象包裝

通過上表可以發(fā)現(xiàn) File類中提供的方法并不涉及文件的具體內(nèi)容,只是針對(duì)文件本身的操作。在 File類中的 length()lastModified()方法返回的數(shù)據(jù)類型都是 long 型,這是因?yàn)?long數(shù)據(jù)類型可以描述內(nèi)存(或文件)大小、日期時(shí)間數(shù)字等等。

下面演示一個(gè)文件基本操作。任意給定一個(gè)文件路徑,如果文件不存在則創(chuàng)建一個(gè)新的文件,如果文件存在則將文件刪除。文件操作流程如下所示:

【Java基礎(chǔ)教程】(四十四)IO篇 · 上:File類、字節(jié)流與字符流,分析字節(jié)輸出流、字節(jié)輸入流、字符輸出流和字符輸入流的區(qū)別~,# Java基礎(chǔ)教程,java,開發(fā)語言,jvm,經(jīng)驗(yàn)分享,java-ee,后端
圖1 文件操作流程

//	范例1
package com.xiaoshan.demo;

import java.io.File;

public class TestDemo {
	public static void main(String[] args) throws Exception{	//此處直接拋出
		File file = new File("d:\\test.txt");	//設(shè)置文件的路徑
		if (file.exists()){		//判斷文件是否存在
			file.delete();		//刪除文件
		}else{			//文件不存在
			System.out.println(file.createNewFile());                      //創(chuàng)建新文件
		}
	}
}	

此程序首先定義了文件的操作路徑 “e:\\test.txt”(“\\”是“\”的轉(zhuǎn)義字符,也是路徑分隔符), 然后利用 exists()方法判斷該路徑的文件是否存在,如果存在則使用 delete()刪除,否則使用 createNewFile()創(chuàng)建新文件。

注意在操作系統(tǒng)中,如果要定義路徑則一定會(huì)存在路徑分隔符的問題,因?yàn)槌绦蜻\(yùn)行在 Windows系統(tǒng)下,所以范例1的程序中使用了“\\”(本質(zhì)為“\”)作為了分隔符。但是如果程序運(yùn)行在 Linux系統(tǒng)中,則路徑分隔符為"/"。而Java本身屬于跨平臺(tái)的操作系統(tǒng),總不能針對(duì)每一個(gè)不同的操作系統(tǒng)手工去修改路徑分隔符,這樣的操作實(shí)在是不智能。因此在 java.io.File 類里面提供有一個(gè)路徑分隔符常量:

public static final String separator;

利用此常量就可以在不同的操作系統(tǒng)中自動(dòng)轉(zhuǎn)化為適合于該操作系統(tǒng)的路徑分隔符。所以在實(shí)際開發(fā)中,如果要定義 File類對(duì)象往往會(huì)使用如下形式的操作代碼。

File file = new File("d:" + File.separator + "test.txt");	//設(shè)置文件的路徑

為了保證代碼開發(fā)的嚴(yán)格性,在使用文件操作中都會(huì)利用此常量定義路徑分隔符。 同時(shí)可能大家也發(fā)現(xiàn)了一個(gè)問題,雖然 separator 是一個(gè)常量,但是這個(gè)常量并沒有遵守字母全部大寫的原則,而造成這樣的問題是在JDK 1.0 時(shí)常量與變量的定義規(guī)則相同,而這一問題也屬于歷史遺留問題。

另外需要提醒大家的是,在進(jìn)行 java.io 操作文件的過程中,會(huì)出現(xiàn)延遲情況。因?yàn)?Java程序是通過JVM間接地調(diào)用操作系統(tǒng)的文件處理函數(shù)進(jìn)行的文件處理操作,所以中間可能會(huì)出現(xiàn)延遲情況。

如果給定的路徑為根路徑,則文件可以直接利用 createNewFile() 方法進(jìn)行創(chuàng)建;如果要?jiǎng)?chuàng)建的文件存在目錄,那么將無法直接進(jìn)行創(chuàng)建。所以合理的做法應(yīng)該是在創(chuàng)建文件前判斷父路徑 (getParent()取得父路徑) 是否存在,如果不存在則應(yīng)該先創(chuàng)建目錄 (mkdirs() 創(chuàng)建多級(jí)目錄),再創(chuàng)建文件。包含路徑的文件創(chuàng)建如下圖所示:

【Java基礎(chǔ)教程】(四十四)IO篇 · 上:File類、字節(jié)流與字符流,分析字節(jié)輸出流、字節(jié)輸入流、字符輸出流和字符輸入流的區(qū)別~,# Java基礎(chǔ)教程,java,開發(fā)語言,jvm,經(jīng)驗(yàn)分享,java-ee,后端
圖2 包含路徑的文件創(chuàng)建流程

//	范例 2: 創(chuàng)建帶路徑的文件
package com.xiaoshan.demo;

import java.io.File;

public class TestDemo {
	public static void main(String[] args) throws Exception {	//此處直接拋出
		File file = new File("d:" + File.separator + "demo" + File.separator + "hello" + File.separator + "xiaoshan" + File.separator + "test.txt");                      	//設(shè)置文件的路徑
		if (!file.getParentFile().exists()){       	//現(xiàn)在父路徑不存在
			file.getParentFile().mkdirs();			//創(chuàng)建父路徑
		}
		System.out.println(file.createNewFile());	//創(chuàng)建新文件
	}
}

此程序所要?jiǎng)?chuàng)建的文件保存在目錄中,所以在創(chuàng)建文件前需要首先判斷父路徑是否存在,如果不存在則一定要先創(chuàng)建父目錄 (否則會(huì)出現(xiàn) “java.io.IOException: 系統(tǒng)找不到指定的路徑。”)。由于目錄會(huì)存在多級(jí)子目錄的問題,所以需要使用 mkdirs()方法進(jìn)行創(chuàng)建。

當(dāng)用戶在開發(fā)中使用 Struts、Spring MVC的 MVC開發(fā)框架時(shí),都會(huì)面臨接收文件上傳及保存的操作。在文件保存操作中,往往只會(huì)提供一個(gè)父目錄(例如:upload), 而具體的子目錄有可能需要根據(jù)實(shí)際的使用情況進(jìn)行動(dòng)態(tài)創(chuàng)建,這樣就需要使用上邊范例2的方式創(chuàng)建目錄。

//	范例 3: 取得文件或目錄的信息
package com.xiaoshan.demo;

import java.io.File;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;

public class TestDemo {
	public static void main(String[] args) throws Exception {	// 此處直接拋出
		File file = new File("d:" + File.separator + "mypicture.png");	// 設(shè)置文件的路徑
		if  (file.exists()){
			System.out.println("是否是文件:" + (file.isFile()));
			System.out.println("是否是目錄:" + (file.isDirectory()));
			//文件大小是按照字節(jié)單位返回的數(shù)字,所以需要將字節(jié)單元轉(zhuǎn)換為兆(M)  的單元
			//但是考慮到小數(shù)點(diǎn)問題,所以使用 BigDecimal處理
			System.out.println("文件大小:" + 
				( new BigDecimal((double)file.length()/1024 /1024)
					.divide(new BigDecimal(1),2,BigDecimal.ROUND_HALF_UP)) + "M");
			//返回的日期是以long 的形式返回,可以利用SimpleDateFormat 進(jìn)行格式化操作 
			System.out.println("上次修改時(shí)間:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(file.lastModified())));
		}
	}
}

程序執(zhí)行結(jié)果:

是否是文件:true
是否是目錄:false
文件大?。?.28M
上次修改時(shí)間:2023-07-19 06:24:28

此程序利用 File類中提供的方法進(jìn)行操作,其中最為重要的就是關(guān)于數(shù)字的四舍五入處理以及 longDate 類型間的轉(zhuǎn)換操作。

范例 3 的所有操作都是圍繞文件進(jìn)行的,但是在整個(gè)磁盤上除了文件之外,還會(huì)包含使用的目錄。對(duì)于目錄而言,最為常用的功能就是列出目錄組成,可 以使用 listFiles() 方法完成。

//	范例 4: 列出目錄信息
package com.xiaoshan.demo;

import java.io.File;

public class TestDemo {
	public static void main(String[] args) throws Exception {	// 此處直接拋出
		File file = new File("d:" + File.separator);
		if (file.isDirectory()){			//判斷當(dāng)前路徑是否為目錄
			File result[] = file.listFiles();
			for (int x=0; x<result.length; x++){
				System.out.println(result[x]);	//調(diào)用 toString()
			}
		}
	}
}

程序執(zhí)行結(jié)果:

d:\\demo
d:\\devtools
d:\\JSP
d:\\MailMasterData
d:\\MyApp
...

在進(jìn)行目錄列出之前首先要判斷給定的路徑是否是目錄,如果是目錄則利用 listFiles() 方法列出當(dāng)前目錄中所有內(nèi)容 (文件以及子目錄) 的文件對(duì)象,這樣就可以采用循環(huán)的方式直接輸出 File 類對(duì)象(默認(rèn)輸出的是完整路徑);如果有需要也可以繼續(xù)利用數(shù)組中的每一個(gè) File類對(duì)象進(jìn)行操作。

下面演示如何列出指定目錄下的所有文件及子目錄信息。在每一個(gè)目錄中有可能還會(huì)存在其他子目錄,并且還可能有更深層次的子目錄,所以為了可以列出所有的內(nèi)容,應(yīng)該判斷每一個(gè)給定的路徑是否是目錄。如果是目錄則應(yīng)該繼續(xù)列出,這樣的操作最好使用遞歸的方式完成。列出完整目錄結(jié)構(gòu)操作流程如下圖所示。

【Java基礎(chǔ)教程】(四十四)IO篇 · 上:File類、字節(jié)流與字符流,分析字節(jié)輸出流、字節(jié)輸入流、字符輸出流和字符輸入流的區(qū)別~,# Java基礎(chǔ)教程,java,開發(fā)語言,jvm,經(jīng)驗(yàn)分享,java-ee,后端
圖3 列出完整目錄結(jié)構(gòu)流程

//	范例 5: 列出完整目錄結(jié)構(gòu)
package com.xiaoshan.demo;

import java.io.File;

public class TestDemo {
	public static void main(String[] args) throws Exception{ 
		File file = new File("c:" + File.separator);	//定義操作路徑 
		print(file);	//列出目錄
	}
	
	/**
	*列出目錄結(jié)構(gòu),此方法采用遞歸調(diào)用形式
	*@param file 要列出目錄的路徑
	*/
	public static void print(File file){	
		if (file.isDirectory()){	//路徑為目錄
			File result[] = file.listFiles();	//列出子目錄
			if (result != null){
				for (int x=0; x<result.length; x++){
					print(result[x]);	//遞歸調(diào)用
				}
			}
		}
		System.out.println(file);	//直接輸出完整路徑
	}
}

此程序會(huì)列出指定目錄中的全部內(nèi)容 (包括子目錄中的內(nèi)容)。由于不確定要操作的目錄層級(jí)數(shù),所以使用遞歸的方式,將列出的每一個(gè)路徑繼續(xù)判斷;如果是目錄則繼續(xù)列出。

2?? 字節(jié)流與字符流

使用 java.io.File 類雖然可以操作文件,但是卻不能操作文件的內(nèi)容。如果要進(jìn)行文件內(nèi)容的操作,就必須依靠流的概念來完成。流在實(shí)際中分為輸入流與輸出流兩種。輸入流與輸出流是一種相對(duì)的概念,關(guān)鍵是要看參考點(diǎn),以下圖所示為例:數(shù)據(jù)從數(shù)據(jù)源流向目標(biāo)程序,以Java作為參考點(diǎn)來說,那么這就屬于輸入流;如果以數(shù)據(jù)源為參考點(diǎn),那么這就屬于輸出流;同樣以數(shù)據(jù)從Java程序流向目標(biāo)一樣,對(duì)目標(biāo)而言就屬于輸入流,對(duì)于Java程序來說就是輸出流。

【Java基礎(chǔ)教程】(四十四)IO篇 · 上:File類、字節(jié)流與字符流,分析字節(jié)輸出流、字節(jié)輸入流、字符輸出流和字符輸入流的區(qū)別~,# Java基礎(chǔ)教程,java,開發(fā)語言,jvm,經(jīng)驗(yàn)分享,java-ee,后端
圖4 流的概念

在Java 中針對(duì)數(shù)據(jù)流的操作分為輸入與輸出兩種方式,而且針對(duì)此操作提供了以下兩類支持。

  • 字節(jié)流 (JDK 1.0開始提供): InputStream (輸入字節(jié)流)、 OutputStream (輸出字節(jié)流);
  • 字符流 (JDK 1.1開始提供): Reader (輸入字符流)、 Writer (輸出字符流)。

java.io 包中提供的4個(gè)操作流的類是其核心的組成部分,但是這些類本質(zhì)上的操作流程區(qū)別不大。以文件讀、寫操作為例,其基本流程為以下四步。
(1)第一步:通過File類定義一個(gè)要操作文件的路徑;
(2)第二步:通過字節(jié)流或字符流的子類對(duì)象為父類對(duì)象實(shí)例化;
(3)第三步:進(jìn)行數(shù)據(jù)的讀(輸入)、寫(輸出)操作;
(4)第四步:數(shù)據(jù)流屬于資源操作,資源操作必須關(guān)閉。

其中第四步是很重要的,一定要記住,不管何種情況只要是資源操作(例如: 網(wǎng)絡(luò)、文件、數(shù)據(jù)庫的操作都屬于資源操作),必須要關(guān)閉連接(幾乎每種類都會(huì)提供 close()方法)。

java.io 包中,四個(gè)操作流的類 (OutputStreamInputStream、Writer、Reader) 全部都屬于抽象類,所以在使用這些類時(shí),一定要通過子類對(duì)象的向上轉(zhuǎn)型來進(jìn)行抽象類對(duì)象的實(shí)例化操作。在整個(gè) IO 流的操作中最麻煩的并不是這四個(gè)基礎(chǔ)的父類,而是一系列子類。每種子類代表著不同的輸入流、輸出流位置。

2.1 字節(jié)輸出流:OutputStream

字節(jié)流是在實(shí)際開發(fā)中使用較多的一種流操作,而 java.io.OutputStream 是一個(gè)專門實(shí)現(xiàn)字節(jié)輸出流的操作類。OutputStream 類的常用方法如下表所示。

方法 類型 描述
void close() throws IOException 普通方法 關(guān)閉字節(jié)輸出流
void flush() throws IOException 普通方法 強(qiáng)制刷新
abstract void write(int b) throws IOException 普通方法 輸出單個(gè)字節(jié)
void write(byte[] b) throws IOException 普通方法 輸出全部字節(jié)數(shù)組數(shù)據(jù)
void write(byte[] b, int off, int len) throws IOException 普通方法 輸出部分字節(jié)數(shù)組數(shù)據(jù)

可以發(fā)現(xiàn),在 OutputStream 類中提供了3個(gè)輸出( write()) 方法,這3個(gè) write()方法分別可以輸出單個(gè)字節(jié)(使用 int 接收)、全部字節(jié)數(shù)組和部分字節(jié)數(shù)組。

OutputStream是一個(gè)抽象類,而這個(gè)抽象類的定義如下。

public abstract class OutputStream extends Object  implements Closeable, Flushable

在類定義中可以發(fā)現(xiàn)OutputStream類同時(shí)實(shí)現(xiàn)了CloseableFlushable 兩個(gè)父接口,而這兩個(gè)父接口的定義組成如下。

//	Closeable接口:JDK 1.5之后才提供
public interface Closeable extends AutoCloseable {
	public void close() throws IOException;
}

//	Flushable接口:JDK 1.5之后才出現(xiàn)
public interface Flushable {
	public void flush() throws IOException;
}

通過兩個(gè)父接口提供的方法可以發(fā)現(xiàn),close()flush() 方法都已經(jīng)在 OutputStream 類中明確定義過了,這是因?yàn)樵贘DK 1.0時(shí)并沒有為OutputStream 類設(shè)計(jì)繼承的接口, 而從JDK 1.5之后考慮到標(biāo)準(zhǔn)的做法,才增加了兩個(gè)父接口,不過由于最初的使用習(xí)慣,這兩個(gè)接口很少被關(guān)注到。

到了JDK 1.7版本之后,對(duì)于接口的定義又發(fā)生了改變,在 Closeable 接口聲明時(shí)繼承了 AutoCloseable父接口,這個(gè)接口就是JDK 1.7中新增的接口,此接口定義如下。

public interface AutoCloseable {
	public void close() throws Exception;
}

通過定義可以發(fā)現(xiàn),在AutoCloseable 接口中也定義了一個(gè) close()方法,那么為什么在JDK 1.7中又需要提供這樣的 AutoCloseable() 自動(dòng)關(guān)閉)接口呢?

原因是JDK 1.7中針對(duì)異常處理產(chǎn)生了新的支持。在以往的開發(fā)中,如果是資源操作,用戶必須手工關(guān)閉資源(方法名稱幾乎都是 close() ),但是實(shí)際上會(huì)有許多開發(fā)者忘記關(guān)閉資源,就經(jīng)常導(dǎo)致其他線程無法打開資源進(jìn)行操作,所以Java提供了以下一種新的異常處理格式。

try (AutoCloseable接口子類 對(duì)象 = new AutoCloseable接口子類名稱()){
	//調(diào)用方法(有可能會(huì)出現(xiàn)異常);
catch(異常類型對(duì)象){
	//異常處理;
}..[finally  {
	//異常處理的統(tǒng)一出口;
}]

只要使用此種格式,在操作完成后用戶就沒有必要再去調(diào)用 close() 方法了,系統(tǒng)會(huì)自動(dòng)幫助用戶調(diào)用 close() 方法以釋放資源。

//	范例 6: 自動(dòng)執(zhí)行 close()操作
package com.xiaoshan.demo;

class Net implements AutoCloseable{
	@Override
	public void close() throws Exception{
		System.out.println("*** 網(wǎng)絡(luò)資源自動(dòng)關(guān)閉,釋放資源。");
	}
	public void info() throws Exception{	//假設(shè)有異常拋出
		System.out.println("*** 歡迎訪問: https://lst66.blog.csdn.net");
	}
}

public class TestDemo{
	public static void main(String[]  args){
		try (Net n = new Net()){
			n.info();
		}catch (Exception e){
			e.printStackTrace();
		}
	}
}

程序執(zhí)行結(jié)果:

*** 歡迎訪問: https://lst66.blog.csdn.net
*** 網(wǎng)絡(luò)資源自動(dòng)關(guān)閉,釋放資源。

此程序按照 AutoCloseable 的使用原則使用異常處理格式,可以發(fā)現(xiàn)程序中并沒有明確調(diào)用 close()方法的語句,但是在整個(gè)資源操作完成后會(huì)自動(dòng)調(diào)用 close() 釋放資源。

雖然 Java 本身提供了這種自動(dòng)關(guān)閉操作的支持,不過從開發(fā)習(xí)慣上講,仍有不少開發(fā)者還是愿意手工調(diào)用 close()方法,所以可以由讀者自己來決定是否使用此類操作。

OutputStream 本身是一個(gè)抽象類,這樣就需要一個(gè)子類。如果要進(jìn)行文件操作,則可以使用 FileOutputStream 子類完成操作,此類定義的常用方法如下表所示。

方法 類型 描述
public FileOutputStream(File file) throws FileNotFoundException 構(gòu)造方法 將內(nèi)容輸出到指定路徑,如果文件已存在,則使用新的內(nèi)容覆蓋舊的內(nèi)容
public FileOutputStream(File file,boolean append) throws FileNotFoundException 構(gòu)造方法 如果將布爾參數(shù)設(shè)置為true,表示追 加新的內(nèi)容到文件中

由于輸出操作主要以OutputStream 類為主,所以對(duì)于 FileOutputStream 只需要關(guān)注其常用的兩個(gè)構(gòu)造方法即可。大家可以通過下圖理解 FileOutputStream 類的繼承結(jié)構(gòu)。

【Java基礎(chǔ)教程】(四十四)IO篇 · 上:File類、字節(jié)流與字符流,分析字節(jié)輸出流、字節(jié)輸入流、字符輸出流和字符輸入流的區(qū)別~,# Java基礎(chǔ)教程,java,開發(fā)語言,jvm,經(jīng)驗(yàn)分享,java-ee,后端
圖5 FileOutputStream 類的繼承結(jié)構(gòu)

其實(shí)大家可以發(fā)現(xiàn),在OutputStream類中定義的方法都使用了 throws 拋出了異常,因?yàn)榱鲗儆谫Y源操作,所以任何操作都不一定確??梢哉M瓿?,不僅是流操作,而且在后面文章中我會(huì)講解的網(wǎng)絡(luò)操作、數(shù)據(jù)庫操作里面所使用的方法絕大部分也都會(huì)拋出異常。

需要注意的是,我寫的演示案例程序中會(huì)在主方法上直接使用 throws拋出異常,而在實(shí)際開發(fā)中,主方法一定要處理異常,不能拋出。

//	范例 7: 文件內(nèi)容的輸出
package com.xiaoshan.demo;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;

public class TestDemo  {
	public static void main(String[] args) throws Exception{	// 直接拋出
		//1.定義要輸出文件的路徑
		File file = new File("d:" + File.separator + "demo" + File.separator + "案例文本.txt");
		//此時(shí)由于目錄不存在,所以文件不能輸出,應(yīng)該首先創(chuàng)建目錄
		if (!file.getParentFile().exists()){       	//文件目錄不存在
			file.getParentFile().mkdirs();       	//創(chuàng)建目錄
		}
		//2.應(yīng)該使用 OutputStream和其子類進(jìn)行對(duì)象的實(shí)例化,此時(shí)目錄存在,文件還不存在 
		OutputStream output = new FileOutputStream(file);
		//字節(jié)輸出流需要使用byte類型,需要將String類對(duì)象變?yōu)樽止?jié)數(shù)組
		String str = "更多知識(shí)請(qǐng)?jiān)L問:https://lst66.blog.csdn.net"; 
		byte data[] = str.getBytes();		//將字符串變?yōu)樽止?jié)數(shù)組
		//3.輸出內(nèi)容
		output.write(data);
		//4.資源操作的最后一定要進(jìn)行關(guān)閉
		output.close();
	}
}

程序執(zhí)行結(jié)果:

【Java基礎(chǔ)教程】(四十四)IO篇 · 上:File類、字節(jié)流與字符流,分析字節(jié)輸出流、字節(jié)輸入流、字符輸出流和字符輸入流的區(qū)別~,# Java基礎(chǔ)教程,java,開發(fā)語言,jvm,經(jīng)驗(yàn)分享,java-ee,后端


此程序嚴(yán)格按照流的操作步驟進(jìn)行,并且在程序執(zhí)行前指定的文件路徑并不存在,為了保證程序可以正常執(zhí)行,需要先創(chuàng)建對(duì)應(yīng)的父路徑,再利用 FileOutputStream 類對(duì)象為 OutputStream 父類實(shí)例化,這樣 write() 方法輸出時(shí)就表示向文件中進(jìn)行輸出。由于 OutputStream 只適合輸出字節(jié)數(shù)據(jù),所以需要將定義的字符串利用 getBytes() 方法轉(zhuǎn)換為字節(jié)數(shù)組后才可以完成操作。

如果重復(fù)執(zhí)行上邊范例 7的代碼會(huì)發(fā)生文件內(nèi)容的覆蓋,而如果要實(shí)現(xiàn)文件的追加可以使用另外一個(gè) FileOutputStream() 類的構(gòu)造方法(public FileOutputStream(File file, boolean append))。

//	范例 8:文件追加
...
	//2.應(yīng)該使用OutputStream和其子類進(jìn)行對(duì)象的實(shí)例化,此時(shí)目錄存在,文件還不存在
	OutputStream output = new FileOutputStream(file, true);
...

此程序使用了追加模式,這樣每次執(zhí)行完程序都會(huì)向文件中不斷追加新的操作。

范例 7的程序是將整個(gè)字節(jié)數(shù)組的內(nèi)容進(jìn)行了輸出。同時(shí)可以發(fā)現(xiàn)一個(gè)問題:利用 OutputStream 向文件輸出信息時(shí)如果文件不存在,則會(huì)自動(dòng)創(chuàng)建(不需要用戶手工調(diào)用 createNewFile() 方法)。對(duì)于輸出操作在整個(gè) OutputStream 類里面一共定義了三個(gè)方法,下面來看一下其他兩種輸出方法(為方便操作,本處只列出代碼片斷)。

//	范例 9: 采用單個(gè)字節(jié)的方式輸出(此處可以利用循環(huán)操作輸出全部字節(jié)數(shù)組中的數(shù)據(jù))
...
	for (int x=0; x<data.length; x++){
		output.write(data[x]);         	//內(nèi)容輸出
	}
...
//	范例 10: 輸出部分字節(jié)數(shù)組內(nèi)容(設(shè)置數(shù)組的開始索引和長度)
...
	output.write(data, 6, 6);       	//內(nèi)容輸出
...

雖然在 OutputStream 類中定義了3種操作,但是從實(shí)際的開發(fā)來講,輸出部分字節(jié)數(shù)組操作 (public void write(byte[] b, int off, int len)) 是實(shí)際工作中使用較多的方法。

2.2 字節(jié)輸入流:InputStream

在程序中如果要進(jìn)行文件數(shù)據(jù)的讀取操作,可以使用 java.io.InputStream 類完成,此類可以完成字節(jié)數(shù)據(jù)的讀取操作。InputStream 類的常用方法如下表所示。

方法 類型 描述
void close() throws IOException 普通方法 關(guān)閉字節(jié)輸入流
abstract int read() throws IOException 普通方法 讀取單個(gè)字節(jié)
int read(byte[] b) throws IOException 普通方法 將數(shù)據(jù)讀取到字節(jié)數(shù)組中,同時(shí)返回讀取長度
int read(byte[] b, int off, int len) throws IOException 普通方法 將數(shù)據(jù)讀取到部分字節(jié)數(shù)組中,同時(shí)返回讀取的數(shù)據(jù)長度

通過 InputStream 類提供的3個(gè) read()方法可以發(fā)現(xiàn),其操作的數(shù)據(jù)類型與 OutputStream 類中的3個(gè) write()方法對(duì)應(yīng)。但是 OutputStream 類中的 write() 中的參數(shù)包含的是要輸出的數(shù)據(jù),而 InputStream 類中的 read() 方法中的參數(shù)是為了接收輸入數(shù)據(jù)準(zhǔn)備的。

InputStream 依然屬于一個(gè)抽象類,此類的定義如下。

public abstract class InputStream extends Object implements Closeable

通過定義可以發(fā)現(xiàn) InputStream類實(shí)現(xiàn)了 Closeable 接口(其繼承AutoCloseable接口),所以利用自動(dòng)關(guān)閉的異常處理結(jié)構(gòu)可以實(shí)現(xiàn)自動(dòng)的資源釋放。與 OutputStream類一樣,由于 Closeable 屬于后加入的接口,并且在 InputStream 類中存在 close()方法,所以用戶可以忽略此接口的存在。

InputStream 類中最為重要的就是3個(gè) read() 方法,這三個(gè)方法的詳細(xì)作用如下。

  • public abstract int read() throws IOException:讀取單個(gè)字節(jié),返回讀取的字節(jié)內(nèi)容,如果已經(jīng)沒有內(nèi)容,則讀取后返回 “-1”,如下圖所示;
  • public int read(byte[] b) throws IOException:將讀取的數(shù)據(jù)保存在字節(jié)數(shù)組里 (一次性讀取多個(gè)數(shù)據(jù)),返回讀取的數(shù)據(jù)長度,如果已經(jīng)讀取到結(jié)尾,則讀取后返回 “-1”;
  • public int read(byte[] b, int off, int len) throws IOException:將讀取的數(shù)據(jù)保存在部分字節(jié)數(shù)組里,讀取的部分?jǐn)?shù)據(jù)的長度,如果已經(jīng)讀取到結(jié)尾,則讀取后返回 “-1”,如下圖所示。
【Java基礎(chǔ)教程】(四十四)IO篇 · 上:File類、字節(jié)流與字符流,分析字節(jié)輸出流、字節(jié)輸入流、字符輸出流和字符輸入流的區(qū)別~,# Java基礎(chǔ)教程,java,開發(fā)語言,jvm,經(jīng)驗(yàn)分享,java-ee,后端
圖6 讀取單個(gè)字節(jié)與讀取一組字節(jié)

一些朋友在學(xué)習(xí)到此處時(shí)都會(huì)不太理解 read() 方法的作用,為了幫助大家更好地理解此操作,舉一個(gè)生活中的例子:辦公室有一個(gè)飲水機(jī),現(xiàn)在小李口渴了(身體需要輸入水分) 需要喝水,他的喝水操作就可能有以下3種情況。

  • 第一種情況(public int read()):小李沒有帶杯子,所以只能夠用手接著喝,每次喝掉 1mL的水,并且一直重復(fù)這個(gè)動(dòng)作, 一直到飲水機(jī)中的水被喝干,但是很明顯這樣喝水花費(fèi)時(shí)間較長,如果水全被喝完了,就相當(dāng)于數(shù)據(jù)沒有了,此時(shí)程序的處理做法是返回“-1”;
  • 第二種情況(public int read(byte[] b)):小李拿了一個(gè)水杯去接水 (假設(shè)水杯容量為300mL,這就相當(dāng)于每使用水杯接一次水,就可以喝掉300mL的水,接水的次數(shù)少了),此時(shí)存在兩種情況:
    • 飲水機(jī)里的水還剩余1L,很明顯即便杯子接滿了,也只能接出300mL,但這樣每次接300mL的水,相比每次接1mL的水操作次數(shù)有大幅減少。當(dāng)飲水機(jī)中沒有水的時(shí)候,水杯將無法接到水,最終就會(huì)返回一個(gè)“-1” 的長度標(biāo)記;
    • 飲水機(jī)里的水還剩余200mL,這樣無法接滿300mL的水杯,于是返回的總數(shù)量就是200mL,而再次要接水時(shí)將無法接到水,這樣就會(huì)返回一個(gè)“-1”的長度標(biāo)記;
  • 第三種情況(public int read(byte[] b, int off, int len)):小李拿了一個(gè)300mL 的杯子要去接飲水機(jī)里的水,但是他只要求杯子接150mL的水,這樣就會(huì)要求設(shè)置一個(gè)接水的量。

java.io.InputStream 是一個(gè)抽象類,所以如果要想進(jìn)行文件讀取,需要使用 FileInputStream 子類,而這個(gè)子類的構(gòu)造方法如下所示。

//	設(shè)置要讀取文件數(shù)據(jù)的路徑
public FilelnputStream(File file) throws FileNotFoundException

OutputStream 的使用規(guī)則相同,所有的子類要向父類對(duì)象轉(zhuǎn)型,所以 FileInputStream 類中只需要關(guān)注構(gòu)造方法即可,而 FileInputStream 類的繼承結(jié)構(gòu)如下圖所示。

【Java基礎(chǔ)教程】(四十四)IO篇 · 上:File類、字節(jié)流與字符流,分析字節(jié)輸出流、字節(jié)輸入流、字符輸出流和字符輸入流的區(qū)別~,# Java基礎(chǔ)教程,java,開發(fā)語言,jvm,經(jīng)驗(yàn)分享,java-ee,后端
圖7 FileInputStream 類的繼承結(jié)構(gòu)

//	范例 11: 數(shù)據(jù)讀取操作
package com.xiaoshan.demo;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

public class TestDemo{
	public static void main(String[] args) throws Exception { 	// 直接拋出
		File file = new File("d:" + File.separator + "demo" + File.separator + "案例文本.txt");     //1.定義要輸出文件的路徑 
		if (file.exists()){		// 需要判斷文件是否存在后才可以進(jìn)行讀取     
			InputStream input = new FileInputStream(file);		//2.使用InputStream 進(jìn)行讀取
			byte data []= new byte [1024];	//準(zhǔn)備出一個(gè)1024的數(shù)組
			int len = input.read(data);		//3.進(jìn)行數(shù)據(jù)讀取,將內(nèi)容保存到字節(jié)數(shù)組中 
			input.close();		//4.關(guān)閉輸入流
			//將讀取出來的字節(jié)數(shù)組數(shù)據(jù)變?yōu)樽址M(jìn)行輸出
			System.out.println("【" + new String(data, 0, len)+" 】");
		}
	}
}

程序執(zhí)行結(jié)果:

【更多知識(shí)請(qǐng)?jiān)L問:https://lst66.blog.csdn.net】                

此程序利用 InputStream 實(shí)現(xiàn)了文件的讀取操作,為了確??梢哉_讀取,首先要對(duì)文件是否存在進(jìn)行判斷。在進(jìn)行數(shù)據(jù)讀取時(shí),首先要開辟一個(gè)字節(jié)數(shù)組空間以保存讀取的數(shù)據(jù),但是考慮到要讀取的數(shù)據(jù)量有可能小于數(shù)組大小,所以在將字節(jié)數(shù)組轉(zhuǎn)換為字符串時(shí)設(shè)置了數(shù)組可用數(shù)據(jù)的長度 (該長度為 input.read(data)方法返回結(jié)果)。

范例11是將數(shù)據(jù)一次性讀取到字節(jié)數(shù)組中,但是在 InputStream 類中定義了3個(gè) read()方法,其中有一個(gè) read()方法可以每次讀取一個(gè)字節(jié)數(shù)據(jù),如果要使用此方法操作,就必須結(jié)合循環(huán)一起完成。

//	范例 12: 采用 while 循環(huán)實(shí)現(xiàn)輸入流操作
package com.xiaoshan.demo;

import java.io.File;
import java.io.FilelnputStream;
import java.io.InputStream;

public class TestDemo(
	public static void main(String[] args) throws Exception{	// 直接拋出
		File file =new File("d:"+ File.separator + "demo" + File.separator + "案例文本.txt");	//1.定義要輸出文件的路徑
			if (file.exists()){		//需要判斷文件是否存在后才可以進(jìn)行讀取
				InputStream input = new FilelnputStream(file);		//2.使用InputStream 進(jìn)行讀取
				byte data[] = new byte[1024];		//準(zhǔn)備出一個(gè)1024的數(shù)組
				int foot=0;		//表示字節(jié)數(shù)組的操作腳標(biāo)
				int temp=0;		//表示接收每次讀取的字節(jié)數(shù)據(jù)
				//第一部分:(temp= input.read()),表示將read()方法讀取的字節(jié)內(nèi)容給temp 變量 
				//第二部分:((temp = input.read()) != -1, 判斷讀取的 temp 內(nèi)容是否是-1
				while((temp = input.read()) != -1){		//3.讀取數(shù)據(jù)
					//有內(nèi)容進(jìn)行保存
					data[foot++] = (byte)temp;
				}
				input.close();                                                                   //4.關(guān)閉輸入流 
				System.out.println("【" + new String(data, 0, foot) + "】");
			}
		}
	}
}

程序執(zhí)行結(jié)果:

【更多知識(shí)請(qǐng)?jiān)L問:https://lst66.blog.csdn.net】

此程序采用了循環(huán)的方式進(jìn)行數(shù)據(jù)讀取操作,每次循環(huán)時(shí)都會(huì)將讀取出來的字節(jié)數(shù)據(jù)保存給 temp 變量,如果讀取出來的數(shù)據(jù)不是“-1”就表示還有數(shù)據(jù)需要繼續(xù)進(jìn)行讀取。循環(huán)讀取字節(jié)數(shù)據(jù)的執(zhí)行流程如下圖所示。

【Java基礎(chǔ)教程】(四十四)IO篇 · 上:File類、字節(jié)流與字符流,分析字節(jié)輸出流、字節(jié)輸入流、字符輸出流和字符輸入流的區(qū)別~,# Java基礎(chǔ)教程,java,開發(fā)語言,jvm,經(jīng)驗(yàn)分享,java-ee,后端
圖8 循環(huán)讀取字節(jié)數(shù)據(jù)

關(guān)于“while((temp = input.read()) != -1)” 語句,一些朋友第一次接觸此類語法會(huì)有一些不習(xí)慣,而實(shí)際上這樣的語法在進(jìn)行 I0 操作時(shí)是最好用的。按照程序中的注解,此語法分為以下兩個(gè)執(zhí)行步驟:
(1)第一步(temp = input.read()):表示將read()方法讀取的字節(jié)內(nèi)容給temp變量,同時(shí)此代碼由于是在“()”中編寫的,所以運(yùn)算符的優(yōu)先級(jí)高于賦值運(yùn)算符;
(2)第二步((temp = input.read()) != -1):表示判斷 temp 接收數(shù)據(jù)返回的是否是"-1", 如果不是-1表示當(dāng)前已經(jīng)讀取到數(shù)據(jù),如果是“-1"表示數(shù)據(jù)已經(jīng)讀取完畢,不再需要讀了。

2.3 字符輸出流:Writer

java.io.Writer 類是從JDK 1.1 版本之后增加的,利用 Writer 類可以直接實(shí)現(xiàn)字符數(shù)組 (包含了字符串) 的輸出。 Writer類的常用方法如下表所示。

方法 類型 描述
void close() throws IOException 普通方法 關(guān)閉字節(jié)輸出流
void flush() throws IOException 普通方法 強(qiáng)制刷新
Writer append(CharSequence csq) throws IOException 普通方法 追加數(shù)據(jù)
void write(String str) throws IOException 普通方法 輸出字符串?dāng)?shù)據(jù)
void write(char[] cbuf) throws IOException 普通方法 輸出字符數(shù)組數(shù)據(jù)

通過 Writer 類定義的方法可以發(fā)現(xiàn),Writer 類中直接提供了輸出字符串?dāng)?shù)據(jù)的方法,這樣就沒有必要將字符串轉(zhuǎn)成字節(jié)數(shù)組后再輸出了。

OutputStream的定義類似,Writer類本身也屬于一個(gè)抽象類,此類的定義結(jié)構(gòu)如下。

public abstract class Writer extends Object implements Appendable, Closeable, Flushable

通過繼承結(jié)構(gòu)可以發(fā)現(xiàn),Writer類中除了實(shí)現(xiàn) CloseableFlushable接口之外,還實(shí)現(xiàn)了一個(gè) Appendable接口。Appendable接口定義如下。

public interface Appendable {
	public Appendable append(char c) throws IOException;
	public Appendable append(CharSequence csq) throws IOException;
	public Appendable append(CharSequence csq, int start, int end) throws I0Exception;
}

Appendable接口中定義了一系列數(shù)據(jù)追加操作,而追加的類型可以是 CharSequence(可以保存 String、StringBuffer、StringBuilder類對(duì)象)。Writer類的繼承結(jié)構(gòu)如圖所示。

【Java基礎(chǔ)教程】(四十四)IO篇 · 上:File類、字節(jié)流與字符流,分析字節(jié)輸出流、字節(jié)輸入流、字符輸出流和字符輸入流的區(qū)別~,# Java基礎(chǔ)教程,java,開發(fā)語言,jvm,經(jīng)驗(yàn)分享,java-ee,后端
圖9 Writer類的繼承結(jié)構(gòu)

Writer 是一個(gè)抽象類,要針對(duì)文件內(nèi)容進(jìn)行輸出,可以使用 java.io.FileWriter 類實(shí)現(xiàn) Writer 類對(duì)象的實(shí)例化操作。 FileWriter類的常用方法如表所示。

方法 類型 描述
public FileWriter(File file) throws I0Exception 構(gòu)造方法 設(shè)置輸出文件
public FileWriter(File file, boolean append) throws IOException 構(gòu)造方法 設(shè)置輸出文件以及是否進(jìn)行數(shù)據(jù)追加
//	范例 13: 使用 Writer 類實(shí)現(xiàn)內(nèi)容輸出
package com.xiaoshan.demo;

import java.io.File;
import java.io.FileWriter;
import java.io.Writer;

public class TestDemo {
	public static void main(String[] args) throws Exception{	// 此處直接拋出
		File file = new File("d:" + File.separator + "demo" + File.separator + "案例文本.txt");	//1.定義要輸出文件的路徑
		if (file.getParentFile().exists()){		//判斷目錄是否存在
			file.getParentFile().mkdirs();		//創(chuàng)建文件目錄
		}
		Writer out = new FileWriter(file);		//2.實(shí)例化了 Writer類的對(duì)象
		String str = "更多知識(shí)請(qǐng)?jiān)L問:https://lst66.blog.csdn.net"; 	//定義輸出內(nèi)容
		out.write(str);		//3.輸出字符串?dāng)?shù)據(jù)
		out.close();		//4.關(guān)閉輸出流
	}
}

本程序?qū)崿F(xiàn)了字符串?dāng)?shù)據(jù)的內(nèi)容輸出,基本的使用流程與 OutputStream 相同,而最方便的是 Writer 類可以直接進(jìn)行 String 數(shù)據(jù)的輸出。

2.4 字符輸入流:Reader

java.io.Reader 類是實(shí)現(xiàn)字符數(shù)據(jù)輸入的操作類,在進(jìn)行數(shù)據(jù)讀取時(shí)可以不使用字節(jié)數(shù)據(jù),而直接依靠字符數(shù)據(jù)(方便處理中文)進(jìn)行操作。 Reader 類的常用方法如下表所示。

方法 類型 描述
void close() throws IOException 普通方法 關(guān)閉字節(jié)輸入流
int read() throws IOException 普通方法 讀取單個(gè)數(shù)據(jù)
int read() throws IOException 普通方法 讀取單個(gè)字符
int read(char[] cbuf) throws IOException 普通方法 讀取數(shù)據(jù)到字符數(shù)組中,返回讀取長度
long skip(long n) throws IOException 普通方法 跳過字節(jié)長度

通過上表可以發(fā)現(xiàn),在Reader 類中也定義有 read() 方法,但是與 InputStream 最大的不同在于此處返回的數(shù)據(jù)是字符數(shù)據(jù)。為了更好地理解Reader類的操作,下面介紹 Reader類的定義結(jié)構(gòu)。

public abstract class Reader extends Object implements Readable, Closeable

通過定義結(jié)構(gòu)可以發(fā)現(xiàn),在Reader類中實(shí)現(xiàn)了兩個(gè)接口:ReadableCloseable,而 Readable接口定義如下。

public interface Readable{
	public int read(CharBuffer cb) throws IOException;
}

Readable接口中定義的 read()方法可以將數(shù)據(jù)保存在CharBuffer() 字符緩沖,類似于 StringBuffer()對(duì)象中,也就是說利用此類就可以替代字符數(shù)組的操作。Reader 類的繼承結(jié)構(gòu)如下圖所示。

【Java基礎(chǔ)教程】(四十四)IO篇 · 上:File類、字節(jié)流與字符流,分析字節(jié)輸出流、字節(jié)輸入流、字符輸出流和字符輸入流的區(qū)別~,# Java基礎(chǔ)教程,java,開發(fā)語言,jvm,經(jīng)驗(yàn)分享,java-ee,后端
圖10 Reader 類的繼承結(jié)構(gòu)

另外大家可以發(fā)現(xiàn),在 Writer 類中存在直接輸出字符串的操作,而 Reader 類中并沒有直接返回字符串的操作,這是因?yàn)檩敵鰯?shù)據(jù)時(shí)可以采用追加的模式,所以隨著時(shí)間的推移,文件有可能變得非常龐大 (假設(shè)現(xiàn)在已經(jīng)達(dá)到了10G)。而如果在Reader類中提供了直接讀取全部數(shù)據(jù)的方式,則有可能造成內(nèi)存溢出問題。

Reader 類是一個(gè)抽象類,要實(shí)現(xiàn)文件數(shù)據(jù)的字符流讀取,可以利用 FileReader子類為 Reader 類對(duì)象實(shí)例化。FileReader 類的常用方法如下所示。

  • public FileReader(File file) throws FileNotFoundException:構(gòu)造方法,定義要讀取的文件路徑。
//	范例 14: 使用 Reader 讀取數(shù)據(jù)
package com.xiaoshan.demo;

import java.io.File;
import java.io.FileReader;
import java.io.Reader;

public class TestDemo  {
	public static void main(Stringll args) throws Exception   {    // 此處直接拋出 
		File file = new File("d:"+ File.separator + "demo" + File.separator + "案例文本.txt");	//1.定義要輸出文件的路徑
		if (file.exists()){
			Reader in = new FileReader(file);	//2. 為Reader 類對(duì)象實(shí)例化
			char data[] = new char[1024];		//開辟字符數(shù)組,接收讀取數(shù)據(jù)
			int len = in.read(data);			//3.進(jìn)行數(shù)據(jù)讀取
			in.close();			//4.關(guān)閉輸入流
			System.out.println(new String(data, 0, len));
		}
	}
}

程序執(zhí)行結(jié)果:

更多知識(shí)請(qǐng)?jiān)L問:https://lst66.blog.csdn.net

此程序首先使用了字符數(shù)組作為接收數(shù)據(jù),當(dāng)使用 read() 方法時(shí)會(huì)將數(shù)據(jù)保存到數(shù)組中,然后返回讀取的數(shù)據(jù)長度,由于數(shù)組開辟較大,內(nèi)容無法全部填充,這樣在輸出時(shí)就可以將部分字符數(shù)組轉(zhuǎn)換為字符串后輸出。

2.5 字節(jié)流與字符流的區(qū)別

以上講解已經(jīng)為讀者詳細(xì)地分析了字節(jié)流與字符流類的繼承結(jié)構(gòu)、基本操作流程。這兩類流都可以完成類似的功能,那么這兩種操作流有哪些區(qū)別呢?

以文件操作為例,字節(jié)流與字符流最大的區(qū)別是:字節(jié)流直接與終端文件進(jìn)行數(shù)據(jù)交互,字符流需要將數(shù)據(jù)經(jīng)過緩沖區(qū)處理才與終端文件數(shù)據(jù)交互。

在使用 OutputStream 輸出數(shù)據(jù)時(shí)即使最后沒有關(guān)閉輸出流,內(nèi)容也可以正常輸出,但是反過來如果使用的是字符輸出流 Writer, 在執(zhí)行到最后如果不關(guān)閉輸出流,就表示在緩沖區(qū)中處理的內(nèi)容不會(huì)被強(qiáng)制性清空,所以就不會(huì)輸出數(shù)據(jù)。如果有特殊情況不能關(guān)閉字符輸出流,可以使用 flush()方法強(qiáng)制清空緩沖區(qū)。

//	范例 15: 強(qiáng)制清空字符流緩沖區(qū)
package com.xiaoshan.demo;

import java.io.File;
import java.io.FileWriter;
import java.io.Writer;

public class TestDemo  {
	public static void main(String[] args) throws Exception{	//此處直接拋出
		File file = new File("d:"+ File.separator + "demo" + File.separator + "案例文本.txt");	//1.定義要輸出文件的路徑
		if (!file.getParentFile().exists()){	//判斷目錄是否存在
			file.getParentFile().mkdirs();		//創(chuàng)建文件目錄
		}
		Writer out = new FileWriter(file);		//2.實(shí)例化了Writer類的對(duì)象
		String str = "更多知識(shí)請(qǐng)?jiān)L問:https://lst66.blog.csdn.net";		// 定義輸出內(nèi)容
		out.write(str);                     	//3.輸出字符串?dāng)?shù)據(jù)
		out.flush();                          	//強(qiáng)制刷新緩沖區(qū)
	}
}

此程序執(zhí)行到最后并沒有執(zhí)行流的關(guān)閉操作,所以從本質(zhì)上講,內(nèi)容將無法完整輸出。在不關(guān)閉流又需要完整輸出時(shí)就只能利用 flush() 方法強(qiáng)制刷新緩沖區(qū)。

在開發(fā)中,對(duì)于字節(jié)數(shù)據(jù)處理是比較多的,例如:圖片、音樂、電影、文字。而字符流最大的好處是它可以進(jìn)行中文的有效處理。在開發(fā)中,如果要處理中文時(shí)應(yīng)優(yōu)先考慮字符流,如果沒有中文問題,建議使用字節(jié)流。

?? 總結(jié)

在本文中,我們深入探討了Java文件操作類:File、字節(jié)流和字符流。我們首先介紹了File類,它提供了處理文件和目錄的基本功能。接著,我們討論了字節(jié)流和字符流,分別涵蓋了InputStreamOutputStream、ReaderWriter。

字節(jié)流主要操作字節(jié)數(shù)據(jù),適用于處理二進(jìn)制文件和網(wǎng)絡(luò)數(shù)據(jù)傳輸。OutputStream用于寫入字節(jié)數(shù)據(jù)到輸出源,而InputStream則讀取字節(jié)數(shù)據(jù)從輸入源。這些流提供了豐富的方法,使我們能夠有效地讀寫字節(jié)數(shù)據(jù)。

字符流則重點(diǎn)處理字符數(shù)據(jù),適用于處理文本文件和字符集編碼等。Writer用于將字符數(shù)據(jù)寫入輸出源,而Reader則從輸入源讀取字符數(shù)據(jù)。字符流提供了更高級(jí)的字符處理功能,如自動(dòng)字符集編碼轉(zhuǎn)換和緩沖區(qū)管理。

此外,我們還探討了字節(jié)流和字符流的區(qū)別。字節(jié)流是以字節(jié)為單位進(jìn)行讀寫,而字符流則以字符為單位。字節(jié)流適合處理任意類型的數(shù)據(jù),而字符流則更適合處理文本數(shù)據(jù),并且對(duì)于國際化處理提供了更好的支持。在使用時(shí),我們應(yīng)根據(jù)實(shí)際需求選擇合適的流。

在日常開發(fā)中,熟練掌握文件操作類和IO流的知識(shí)非常重要。通過正確使用File類和不同類型的流,我們能夠高效地讀寫文件和處理數(shù)據(jù)。了解字節(jié)流和字符流的區(qū)別以及它們的適用場景,可以幫助我們更好地選擇合適的IO操作方式。


? 溫習(xí)回顧上一篇(點(diǎn)擊跳轉(zhuǎn))
《【Java基礎(chǔ)教程】(四十三)多線程篇 · 下:深入剖析Java多線程編程:同步、死鎖及經(jīng)典案例——生產(chǎn)者與消費(fèi)者,探究sleep()與wait()的差異》

? 繼續(xù)閱讀下一篇(點(diǎn)擊跳轉(zhuǎn))
《【Java基礎(chǔ)教程】(四十五)IO篇 · 中:轉(zhuǎn)換流、內(nèi)存流和打印流(探索裝飾設(shè)計(jì)模式與PrintStream類的進(jìn)階),文件操作案例實(shí)踐、字符編碼問題~》
文章來源地址http://www.zghlxwxcb.cn/news/detail-608465.html

【Java基礎(chǔ)教程】(四十四)IO篇 · 上:File類、字節(jié)流與字符流,分析字節(jié)輸出流、字節(jié)輸入流、字符輸出流和字符輸入流的區(qū)別~,# Java基礎(chǔ)教程,java,開發(fā)語言,jvm,經(jīng)驗(yàn)分享,java-ee,后端

到了這里,關(guān)于【Java基礎(chǔ)教程】(四十四)IO篇 · 上:File類、字節(jié)流與字符流,分析字節(jié)輸出流、字節(jié)輸入流、字符輸出流和字符輸入流的區(qū)別~的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【Java|基礎(chǔ)篇】File類和IO流

    【Java|基礎(chǔ)篇】File類和IO流

    File類是Java中用于表示文件或目錄的類。它提供了一些方法來操作文件和目錄的屬性和內(nèi)容,可以進(jìn)行文件的創(chuàng)建、刪除、重命名等操作。 File類可以用于表示磁盤上的實(shí)際文件或目錄,也可以表示一個(gè)虛擬的文件或目錄。File對(duì)象可以通過路徑來創(chuàng)建,路徑可以是絕對(duì)路徑或

    2024年02月15日
    瀏覽(24)
  • Java基礎(chǔ)(十七)File類與IO流

    Java基礎(chǔ)(十七)File類與IO流

    1.1 概述 File類及本章下的各種流,都定義在java.io包下。 一個(gè)File對(duì)象代表硬盤或網(wǎng)絡(luò)中可能存在的一個(gè)文件或者文件目錄(俗稱文件夾),與平臺(tái)無關(guān)。(體會(huì)萬事萬物皆對(duì)象) File 能新建、刪除、重命名文件和目錄,但 File 不能訪問文件內(nèi)容本身。如果需要訪問文件內(nèi)容本

    2024年02月02日
    瀏覽(21)
  • 張小飛的Java之路——第四十二章——字節(jié)流

    張小飛的Java之路——第四十二章——字節(jié)流

    寫在前面: 視頻是什么東西,有看文檔精彩嗎? 視頻是什么東西,有看文檔速度快嗎? 視頻是什么東西,有看文檔效率高嗎? 諸小亮:下面我們學(xué)習(xí)——字節(jié)流 張小飛:什么是字節(jié)流? 諸小亮:就是 以字節(jié)的形式操作文件中的數(shù)據(jù) ,分為:InputStream、OutputStream Stream:流

    2024年02月06日
    瀏覽(18)
  • java基礎(chǔ)入門-18-【IO(異常&File&綜合案例)】

    java基礎(chǔ)入門-18-【IO(異常&File&綜合案例)】

    異常 :指的是程序在執(zhí)行過程中,出現(xiàn)的非正常的情況,最終會(huì)導(dǎo)致JVM的非正常停止。 在Java等面向?qū)ο蟮木幊陶Z言中,異常本身是一個(gè)類,產(chǎn)生異常就是創(chuàng)建異常對(duì)象并拋出了一個(gè)異常對(duì)象。Java處理異常的方式是中斷處理。 異常指的并不是語法錯(cuò)誤,語法錯(cuò)了,編譯不通過

    2024年02月07日
    瀏覽(34)
  • 【JavaSE】Java基礎(chǔ)語法(三十六):File & IO流

    【JavaSE】Java基礎(chǔ)語法(三十六):File & IO流

    java.io.File類是文件和目錄路徑名的抽象表示形式,主要用于文件和目錄的創(chuàng)建、查找和刪除等操作。 File:它是文件和目錄路徑名的抽象表示 文件和目錄可以通過File封裝成對(duì)象 File封裝的對(duì)象僅僅是一個(gè)路徑名。它可以是存在的,也可以是不存在的。 | 方法名 | 說明 | | —

    2024年02月07日
    瀏覽(29)
  • JAVA基礎(chǔ)學(xué)習(xí)筆記-day15-File類與IO流

    JAVA基礎(chǔ)學(xué)習(xí)筆記-day15-File類與IO流

    博文主要是自己學(xué)習(xí)JAVA基礎(chǔ)中的筆記,供自己以后復(fù)習(xí)使用,參考的主要教程是B站的 尚硅谷宋紅康2023大數(shù)據(jù)教程 老驥伏櫪,志在千里 --曹操《龜雖壽》 1.1 概述 File類及本章下的各種流,都定義在 java.io 包下。 一個(gè)File對(duì)象代表硬盤或網(wǎng)絡(luò)中可能存在的一個(gè)文件或者文件目

    2024年01月21日
    瀏覽(22)
  • Java基礎(chǔ)——IO流之字符集

    (1)IO前置內(nèi)容:字符集 1.字符集基礎(chǔ)知識(shí): 計(jì)算機(jī)底層不可以直接存儲(chǔ)字符,只能存儲(chǔ)二進(jìn)制(0,1)。 二進(jìn)制可以轉(zhuǎn)換成十進(jìn)制。 計(jì)算機(jī)底層可以表示十進(jìn)制編號(hào)。計(jì)算機(jī)可給人類字符進(jìn)行編號(hào)存儲(chǔ),這套編號(hào)規(guī)則就是字符集。 2.ASCII字符集:(1字節(jié)) ASCII(American S

    2023年04月17日
    瀏覽(24)
  • leetcode解題思路分析(一百四十四)1247 - 1253 題

    交換字符使得字符串相同 有兩個(gè)長度相同的字符串 s1 和 s2,且它們其中 只含有 字符 “x” 和 “y”,你需要通過「交換字符」的方式使這兩個(gè)字符串相同。每次「交換字符」的時(shí)候,你都可以在兩個(gè)字符串中各選一個(gè)字符進(jìn)行交換。交換只能發(fā)生在兩個(gè)不同的字符串之間,

    2024年02月16日
    瀏覽(23)
  • SpringBoot系列(四十四):Tomcat與Undertow容器性能對(duì)比分析|超級(jí)詳細(xì),建議收藏

    SpringBoot系列(四十四):Tomcat與Undertow容器性能對(duì)比分析|超級(jí)詳細(xì),建議收藏

    ????????Tomcat和Undertow都是非常流行的Java Web容器,它們都有自己的優(yōu)缺點(diǎn)。但在實(shí)際項(xiàng)目中,我們?nèi)绾芜x擇最合適的容器呢?是選擇老牌的Tomcat,還是選擇后起之秀的Undertow?本篇文章將深入分析Tomcat和Undertow的性能表現(xiàn),為大家揭秘最佳選擇!無論你是Java開發(fā)者還是想深

    2023年04月21日
    瀏覽(44)
  • Java面試題字節(jié)流字符流

    String 編碼 UTF-8 和 GBK 的區(qū)別 GBK 編碼:是指中國的中文字符,其實(shí)它包含了簡體中文與繁體中文字符,另外還有一種字符 “gb2312” ,這種字符僅能存儲(chǔ)簡體中文字符。 UTF-8 編碼:它是一種全國家通過的一種編碼,如果你的網(wǎng)站涉及到多個(gè)國家的語言,那么建議你 選擇 UTF-

    2024年02月02日
    瀏覽(14)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包