Java文件操作和IO示例詳解
Java中通過(guò)java.io.File類(lèi)來(lái)對(duì)一個(gè)文件(包括目錄)進(jìn)行抽象的描述.注意,有File對(duì)象,并不代表真實(shí)存在該文件.
一、File概述

File類(lèi)的構(gòu)造方法
有四種重載方式,通常使用如下:
File(String pathname) //指定文件(或目錄)名和路徑創(chuàng)建文件對(duì)象
File file =new File("hello.text"); //在當(dāng)前目錄創(chuàng)建文件對(duì)象
File file =new File("JAVA"); //在當(dāng)前目錄創(chuàng)建一個(gè)目錄對(duì)象
File file=new File("D:\\Java"); //指明詳細(xì)的路徑以及目錄名,請(qǐng)注意雙斜線方法

代碼示例
示例1:觀察get系列的觀點(diǎn)與差異:
import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
File file = new File("..\\hello-world.txt"); // 并不要求該文件真實(shí)存在
System.out.println(file.getParent());
System.out.println(file.getName());
System.out.println(file.getPath());
System.out.println(file.getAbsolutePath());
System.out.println(file.getCanonicalPath());
}
}
運(yùn)行結(jié)果
..
hello-world.txt
..\hello-world.txt
D:\代碼練習(xí)\文件示例1\..\hello-world.txt
D:\代碼練習(xí)\hello-world.txt
示例2 普通文件的創(chuàng)建、刪除
import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
File file = new File("hello-world.txt"); // 要求該文件不存在,才能看到相同
的現(xiàn)象
System.out.println(file.exists());
System.out.println(file.isDirectory());
System.out.println(file.isFile());
System.out.println(file.createNewFile());
System.out.println(file.exists());
System.out.println(file.isDirectory());
System.out.println(file.isFile());
System.out.println(file.createNewFile());
}
}運(yùn)行結(jié)果
false
false
false
true
true
false
true
false
示例3 普通文件的刪除
import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
File file = new File("some-file.txt"); // 要求該文件不存在,才能看到相同的現(xiàn)
象
System.out.println(file.exists());
System.out.println(file.createNewFile());
System.out.println(file.exists());
System.out.println(file.delete());
System.out.println(file.exists());
}
}運(yùn)行結(jié)果
false
true
true
true
false
示例4 觀察 deleteOnExit 的現(xiàn)象
import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
File file = new File("some-file.txt"); // 要求該文件不存在,才能看到相同的現(xiàn)
象
System.out.println(file.exists());
System.out.println(file.createNewFile());
System.out.println(file.exists());
file.deleteOnExit();
System.out.println(file.exists());
}
}示例5 觀察目錄的創(chuàng)建
import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
File dir = new File("some-dir"); // 要求該目錄不存在,才能看到相同的現(xiàn)象
System.out.println(dir.isDirectory());
System.out.println(dir.isFile());
System.out.println(dir.mkdir());
System.out.println(dir.isDirectory());
System.out.println(dir.isFile());
}
}運(yùn)行結(jié)果
false
false
true
true
false
示例6 觀察目錄創(chuàng)建2
import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
File dir = new File("some-parent\\some-dir"); // some-parent 和 somedir 都不存在
System.out.println(dir.isDirectory());
System.out.println(dir.isFile());
System.out.println(dir.mkdir());
System.out.println(dir.isDirectory());
System.out.println(dir.isFile());
}
}運(yùn)行結(jié)果
false
false
false
false
false
mkdir() 的時(shí)候,如果中間目錄不存在,則無(wú)法創(chuàng)建成功; mkdirs() 可以解決這個(gè)問(wèn)題
import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
File dir = new File("some-parent\\some-dir"); // some-parent 和 somedir 都不存在
System.out.println(dir.isDirectory());
System.out.println(dir.isFile());
System.out.println(dir.mkdirs());
System.out.println(dir.isDirectory());
System.out.println(dir.isFile());
}
}運(yùn)行結(jié)果
false
false
true
true
false
示例7 觀察文件重命名.
import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
File file = new File("some-file.txt"); // 要求 some-file.txt 得存在,可以
是普通文件,可以是目錄
File dest = new File("dest.txt"); // 要求 dest.txt 不存在
System.out.println(file.exists());
System.out.println(dest.exists());
System.out.println(file.renameTo(dest));
System.out.println(file.exists());
System.out.println(dest.exists());
}
}運(yùn)行結(jié)果
true
false
true
false
true
二、文件內(nèi)容的讀寫(xiě) —— 數(shù)據(jù)流


輸入流(InputStream)概述.
方法
修飾符及 返回值類(lèi) 型 | 方法簽名 | 說(shuō)明 |
int | read() | 讀取一個(gè)字節(jié)的數(shù)據(jù),返回 -1 代表已經(jīng)完全讀完了 |
int | read(byte[] b) | 最多讀取 b.length 字節(jié)的數(shù)據(jù)到 b 中,返回實(shí)際讀到的數(shù)量;-1 代表以及讀完了 |
int | read(byte[] b, int off, int len) | 最多讀取 len - off 字節(jié)的數(shù)據(jù)到 b 中,放在從 off 開(kāi)始,返 回實(shí)際讀到的數(shù)量; -1 代表以及讀完了 |
| void | close() | 關(guān)閉字節(jié)流 |
InputStream 只是一個(gè)抽象類(lèi),要使用還需要具體的實(shí)現(xiàn)類(lèi)。關(guān)于 InputStream 的實(shí)現(xiàn)類(lèi)有很多,基本可以認(rèn)為不同的輸入設(shè)備都可以對(duì)應(yīng)一個(gè) InputStream 類(lèi),我們現(xiàn)在只關(guān)心從文件中讀取,所以使用 FileInputStream
利用FileInputStream 從文件中讀取
構(gòu)造方法
| 簽名 | 說(shuō)明 |
FileInputStream(File file) | 利用 File 構(gòu)造文件輸入流 |
FileInputStream(String name) | 利用文件路徑構(gòu)造文件輸入流 |
代碼示例
示例1
將文件完全讀完的兩種方式。相比較而言,后一種的 IO 次數(shù)更少,性能更好
import java.io.*;
// 需要先在項(xiàng)目目錄下準(zhǔn)備好一個(gè) hello.txt 的文件,里面填充 "Hello" 的內(nèi)容
public class Main {
public static void main(String[] args) throws IOException {
try (InputStream is = new FileInputStream("hello.txt")) {
while (true) {
int b = is.read();
if (b == -1) {
// 代表文件已經(jīng)全部讀完
break;
}
System.out.printf("%c", b);
}
}
}
}import java.io.*;
// 需要先在項(xiàng)目目錄下準(zhǔn)備好一個(gè) hello.txt 的文件,里面填充 "Hello" 的內(nèi)容
public class Main {
public static void main(String[] args) throws IOException {
try (InputStream is = new FileInputStream("hello.txt")) {
byte[] buf = new byte[1024];
int len;
while (true) {
len = is.read(buf);
if (len == -1) {
// 代表文件已經(jīng)全部讀完
break;
}
for (int i = 0; i < len; i++) {
System.out.printf("%c", buf[i]);
}
}
}
}
}示例2
這里我們把文件內(nèi)容中填充中文看看,注意,寫(xiě)中文的時(shí)候使用 UTF-8 編碼。 hello.txt 中填寫(xiě) " 你好中國(guó)"
注意:這里我利用了這幾個(gè)中文的 UTF-8 編碼后長(zhǎng)度剛好是 3 個(gè)字節(jié)和長(zhǎng)度不超過(guò) 1024 字節(jié)的現(xiàn)狀,但這種方式并不是通用的
import java.io.*;
// 需要先在項(xiàng)目目錄下準(zhǔn)備好一個(gè) hello.txt 的文件,里面填充 "你好中國(guó)" 的內(nèi)容
public class Main {
public static void main(String[] args) throws IOException {
try (InputStream is = new FileInputStream("hello.txt")) {
byte[] buf = new byte[1024];
int len;
while (true) {
len = is.read(buf);
if (len == -1) {
// 代表文件已經(jīng)全部讀完
break;
}
// 每次使用 3 字節(jié)進(jìn)行 utf-8 解碼,得到中文字符
// 利用 String 中的構(gòu)造方法完成
// 這個(gè)方法了解下即可,不是通用的解決辦法
for (int i = 0; i < len; i += 3) {
String s = new String(buf, i, 3, "UTF-8");
System.out.printf("%s", s);
}
}
}
}
}利用 Scanner 進(jìn)行字符讀取
上述例子中,我們看到了對(duì)字符類(lèi)型直接使用 InputStream 進(jìn)行讀取是非常麻煩且困難的,所以,我們使用一種我們之前比較熟悉的類(lèi)來(lái)完成該工作,就是 Scanner 類(lèi)。
| 構(gòu)造方法 | 說(shuō)明 |
Scanner(InputStream is, String charset) | 使用 charset 字符集進(jìn)行 is 的掃描讀取 |
import java.io.*;
import java.util.*;
// 需要先在項(xiàng)目目錄下準(zhǔn)備好一個(gè) hello.txt 的文件,里面填充 "你好中國(guó)" 的內(nèi)容
public class Main {
public static void main(String[] args) throws IOException {
try (InputStream is = new FileInputStream("hello.txt")) {
try (Scanner scanner = new Scanner(is, "UTF-8")) {
while (scanner.hasNext()) {
String s = scanner.next();
System.out.print(s);
}
}
}
}
}輸出流OutputStream 概述
方法
修飾 符及 返回 值類(lèi) 型 | 方法簽名 | 說(shuō)明 |
void | write(int b) | 寫(xiě)入要給字節(jié)的數(shù)據(jù) |
void | write(byte[] b) | 將 b 這個(gè)字符數(shù)組中的數(shù)據(jù)全部寫(xiě)入 os 中 |
| int | write(byte[] b, int off, int len) | 將 b 這個(gè)字符數(shù)組中從 off 開(kāi)始的數(shù)據(jù)寫(xiě)入 os 中,一共寫(xiě) len 個(gè) |
void | close() | 關(guān)閉字節(jié)流 |
void | flush() | 重要:我們知道 I/O 的速度是很慢的,所以,大多的 OutputStream 為 了減少設(shè)備操作的次數(shù),在寫(xiě)數(shù)據(jù)的時(shí)候都會(huì)將數(shù)據(jù)先暫時(shí)寫(xiě)入內(nèi)存的 一個(gè)指定區(qū)域里,直到該區(qū)域滿了或者其他指定條件時(shí)才真正將數(shù)據(jù)寫(xiě) 入設(shè)備中,這個(gè)區(qū)域一般稱為緩沖區(qū)。但造成一個(gè)結(jié)果,就是我們寫(xiě)的 數(shù)據(jù),很可能會(huì)遺留一部分在緩沖區(qū)中。需要在最后或者合適的位置, 調(diào)用 flush (刷新)操作,將數(shù)據(jù)刷到設(shè)備中。 |
OutputStream 同樣只是一個(gè)抽象類(lèi),要使用還需要具體的實(shí)現(xiàn)類(lèi)。我們現(xiàn)在還是只關(guān)心寫(xiě)入文件中,所以使用 FileOutputStream
利用 OutputStreamWriter 進(jìn)行字符寫(xiě)入
示例1
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
try (OutputStream os = new FileOutputStream("output.txt")) {
os.write('H');
os.write('e');
os.write('l');
os.write('l');
os.write('o');
// 不要忘記 flush
os.flush();
}
}
}示例2
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
try (OutputStream os = new FileOutputStream("output.txt")) {
byte[] b = new byte[] {
(byte)'G', (byte)'o', (byte)'o', (byte)'d'
};
os.write(b);
// 不要忘記 flush
os.flush();
}
}
}示例3
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
try (OutputStream os = new FileOutputStream("output.txt")) {
byte[] b = new byte[] {
(byte)'G', (byte)'o', (byte)'o', (byte)'d', (byte)'B',
(byte)'a', (byte)'d'
};
os.write(b, 0, 4);
// 不要忘記 flush
os.flush();
}
}
}示例4
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
try (OutputStream os = new FileOutputStream("output.txt")) {
String s = "Nothing";
byte[] b = s.getBytes();
os.write(b);
// 不要忘記 flush
os.flush();
}
}
}示例5
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
try (OutputStream os = new FileOutputStream("output.txt")) {
String s = "你好中國(guó)";
byte[] b = s.getBytes("utf-8");
os.write(b);
// 不要忘記 flush
os.flush();
}
}
}利用 PrintWriter 輸出
上述,我們其實(shí)已經(jīng)完成輸出工作,但總是有所不方便,我們接來(lái)下將 OutputStream 處理下,使用
PrintWriter 類(lèi)來(lái)完成輸出,因?yàn)?/p>
PrintWriter 類(lèi)中提供了我們熟悉的 print/println/printf 方法
OutputStream os = ...;
OutputStreamWriter osWriter = new OutputStreamWriter(os, "utf-8"); // 告訴它,我
們的字符集編碼是 utf-8 的
PrintWriter writer = new PrintWriter(osWriter);
// 接下來(lái)我們就可以方便的使用 writer 提供的各種方法了
writer.print("Hello");
writer.println("你好");
writer.printf("%d: %s\n", 1, "沒(méi)什么");
// 不要忘記 flush
writer.flush();示例1
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
try (OutputStream os = new FileOutputStream("output.txt")) {
try (OutputStreamWriter osWriter = new OutputStreamWriter(os, "UTF-
8")) {
try (PrintWriter writer = new PrintWriter(osWriter)) {
writer.println("我是第一行");
writer.print("我的第二行\(zhòng)r\n");
writer.printf("%d: 我的第三行\(zhòng)r\n", 1 + 1);
writer.flush();
}
}
}
}
}總結(jié)
到此這篇關(guān)于Java文件操作和IO的文章就介紹到這了,更多相關(guān)Java文件操作和IO內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot?Webflux創(chuàng)建TCP/UDP?server并使用handler解析數(shù)據(jù)
這篇文章主要介紹了SpringBoot?Webflux創(chuàng)建TCP/UDP?server并使用handler解析數(shù)據(jù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02
springboot yml中profiles的巧妙用法(小白必看多環(huán)境配置)
這篇文章主要介紹了springboot yml中profiles的巧妙用法,非常適合多環(huán)境配置場(chǎng)景,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04
Java調(diào)用明華RF讀寫(xiě)器DLL文件過(guò)程解析
這篇文章主要介紹了Java調(diào)用明華RF讀寫(xiě)器DLL文件過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12
在java中判斷兩個(gè)浮點(diǎn)型(float)數(shù)據(jù)是否相等的案例
這篇文章主要介紹了在java中判斷兩個(gè)浮點(diǎn)型(float)數(shù)據(jù)是否相等的案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-10-10
java List循環(huán)與Map循環(huán)的總結(jié)
這篇文章主要介紹了java List循環(huán)與Map循環(huán)的總結(jié)的相關(guān)資料,并附代碼實(shí)例,幫助大家學(xué)習(xí)理解,需要的朋友可以參考下2016-11-11
解決SpringBoot運(yùn)行報(bào)錯(cuò):找不到或無(wú)法加載主類(lèi)的問(wèn)題
這篇文章主要介紹了解決SpringBoot運(yùn)行報(bào)錯(cuò):找不到或無(wú)法加載主類(lèi)的問(wèn)題,具有很好的參考價(jià)值,對(duì)大家的學(xué)習(xí)或工作有一定的參考價(jià)值,需要的朋友可以參考下2023-09-09
JavaWeb購(gòu)物車(chē)項(xiàng)目開(kāi)發(fā)實(shí)戰(zhàn)指南
之前沒(méi)有接觸過(guò)購(gòu)物車(chē)的東東,也不知道購(gòu)物車(chē)應(yīng)該怎么做,所以在查詢了很多資料,總結(jié)一下購(gòu)物車(chē)的功能實(shí)現(xiàn),下面這篇文章主要給大家介紹了關(guān)于JavaWeb購(gòu)物車(chē)項(xiàng)目開(kāi)發(fā)的相關(guān)資料,需要的朋友可以參考下2022-06-06
SpringBoot簡(jiǎn)單的SpringBoot后端實(shí)例
這篇文章主要介紹了SpringBoot簡(jiǎn)單的SpringBoot后端實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03

