目錄
?Java 中操作文件
File 概述
屬性
構(gòu)造方法
方法
代碼示例
文件內(nèi)容的讀寫 —— 數(shù)據(jù)流
?InputStream 概述
FileInputStream 概述
利用 Scanner 進行字符讀取
OutputStream 概述
利用 OutputStreamWriter 進行字符寫入
利用 PrintWriter 找到我們熟悉的方法
代碼參考
如何按字節(jié)進行數(shù)據(jù)讀
如何按字節(jié)進行數(shù)據(jù)寫
如何按字符進行數(shù)據(jù)讀
如何按字符進行數(shù)據(jù)寫
?Java 中操作文件
操作系統(tǒng)的一個重要功能就是對文件的管理,每個操作系統(tǒng)都有自己的一套系統(tǒng)API調(diào)用,Java作為一個跨平臺的語言,JVM針對不同的操作系統(tǒng)做了一層封裝,我們只需使用JDK提供的關(guān)于文件操作的API就可以完成不同的系統(tǒng)上的文件操作。
Java 中通過 java.io.File 類來對一個文件(包括目錄)進行抽象的描述。注意,有 File 對象,并不代表真實存在該文件。
File 概述
屬性
修飾符及類型? |
屬性 |
說明 |
static String |
pathSeparator |
依賴于系統(tǒng)的路徑分隔符,String 類型的表示 |
static char |
pathSeparator |
依賴于系統(tǒng)的路徑分隔符,char 類型的表示 |
構(gòu)造方法
方法
修飾符及返回 值類型 |
方法簽名 |
說明 |
String |
getParent() |
返回 File 對象的父目錄文件路徑 |
String |
getName() |
返回 FIle 對象的純文件名稱 |
String |
getPath() |
返回 File 對象的文件路徑 |
String |
getAbsolutePath() |
返回 File 對象的絕對路徑 |
String |
getCanonicalPath() |
返回 File 對象的修飾過的絕對路徑 |
boolean |
exists() |
判斷 File 對象描述的文件是否真實存在 |
boolean |
isDirectory() |
判斷 File 對象代表的文件是否是一個目錄 |
boolean |
isFile() |
判斷 File 對象代表的文件是否是一個普通文件 |
boolean |
createNewFile() |
根據(jù) File 對象,自動創(chuàng)建一個空文件。成功創(chuàng)建后返 回 true |
boolean |
delete() |
根據(jù) File 對象,刪除該文件。成功刪除后返回 true |
void |
deleteOnExit() |
根據(jù) File 對象,標(biāo)注文件將被刪除,刪除動作會到 JVM 運行結(jié)束時才會進行 |
String[] |
list() |
返回 File 對象代表的目錄下的所有文件名 |
File[] |
listFiles() |
返回 File 對象代表的目錄下的所有文件,以 File 對象 表示 |
boolean |
mkdir() |
創(chuàng)建 File 對象代表的目錄 |
boolean |
mkdirs() |
創(chuàng)建 File 對象代表的目錄,如果必要,會創(chuàng)建中間目 錄 |
boolean |
renameTo(File dest) |
進行文件改名,也可以視為我們平時的剪切、粘貼操 作 |
boolean |
canRead() |
判斷用戶是否對文件有可讀權(quán)限 |
boolean |
canWrite() |
判斷用戶是否對文件有可寫權(quán)限 |
代碼示例
示例1
觀察 get 系列的特點和差異
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"); // 并不要求該文件真實存在
? ? ? ?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());
? }
}
運行結(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());
? }
}
運行結(jié)果
false
false
false
true
true
false
true
false
示例3
觀察 deleteOnExit 的現(xiàn)象
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());
? }
}
運行結(jié)果
false
true
true
true
程序運行結(jié)束后,文件還是被刪除了
示例4
觀察目錄創(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-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());
? }
}
運行結(jié)果
false
false
false
false
false
mkdir() 的時候,如果中間目錄不存在,則無法創(chuàng)建成功; mkdirs() 可以解決這個問題。
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());
? }
}
運行結(jié)果
false
false
true
true
false
示例5
觀察文件重命名
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());
? }
}
運行結(jié)果
true
false
true
false
true
文件內(nèi)容的讀寫 —— 數(shù)據(jù)流
數(shù)據(jù)流分類
?InputStream 概述
方法
修飾符及
返回值類
型
|
方法簽名
|
說明
|
int
|
read()
|
讀取一個字節(jié)的數(shù)據(jù),返回
-1
代表已經(jīng)完全讀完了
|
int
|
read(byte[] b)
|
最多讀取
b.length
字節(jié)的數(shù)據(jù)到
b
中,返回實際讀到的數(shù)
量;
-1
代表以及讀完了
|
int
|
read(byte[] b,
int off, int len)
|
最多讀取
len - off
字節(jié)的數(shù)據(jù)到
b
中,放在從
off
開始,返
回實際讀到的數(shù)量;
-1
代表以及讀完了
|
void |
close()
|
關(guān)閉字節(jié)流
|
說明
InputStream 只是一個抽象類,要使用還需要具體的實現(xiàn)類。關(guān)于 InputStream 的實現(xiàn)類有很多,基本可以認為不同的輸入設(shè)備都可以對應(yīng)一個 InputStream 類,我們現(xiàn)在只關(guān)心從文件中讀取,所以使用 FileInputStream
FileInputStream 概述
簽名
|
說明
|
FileInputStream(File file)
|
利用
File
構(gòu)造文件輸入流
|
FileInputStream(String name)
|
利用文件路徑構(gòu)造文件輸入流
|
示例
這里我們把文件內(nèi)容中填充中文看看,注意,寫中文的時候使用 UTF-8 編碼。hello.txt 中填寫 "你好中國"
注意:這里我利用了這幾個中文的 UTF-8 編碼后長度剛好是 3 個字節(jié)和長度不超過 1024 字節(jié)的現(xiàn)狀,但這種方式并不是通用的
import java.io.*;
// 需要先在項目目錄下準(zhǔn)備好一個 hello.txt 的文件,里面填充 "你好中國" 的內(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é)進行 utf-8 解碼,得到中文字符
? ? ? ? ? ? ? ?// 利用 String 中的構(gòu)造方法完成
? ? ? ? ? ? ? ?// 這個方法了解下即可,不是通用的解決辦法
? ? ? ? ? ? ? ?for (int i = 0; i < len; i += 3) {
? ? ? ? ? ? ? ? ? ?String s = new String(buf, i, 3, "UTF-8");
? ? ? ? ? ? ? ? ? ?System.out.printf("%s", s);
? ? ? ? ? ? ? }
? ? ? ? ? }
? ? ? }
? }
}
利用 Scanner 進行字符讀取
上述例子中,我們看到了對字符類型直接使用 InputStream 進行讀取是非常麻煩且困難的,所以,我們使用一種我們之前比較熟悉的類來完成該工作,就是 Scanner 類。
構(gòu)造方法
|
說明
|
Scanner(InputStream is, String charset)
|
使用
charset
字符集進行
is
的掃描讀取
|
import java.io.*;
import java.util.*;
// 需要先在項目目錄下準(zhǔn)備好一個 hello.txt 的文件,里面填充 "你好中國" 的內(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 概述
修飾
符及
返回
值類
型
|
方法簽名
|
說明
|
void
|
write(int b)
|
寫入要給字節(jié)的數(shù)據(jù)
|
void
|
write(byte[]
b)
|
將
b
這個字符數(shù)組中的數(shù)據(jù)全部寫入
os
中
|
int |
write(byte[]
b, int off,
int len)
|
將
b
這個字符數(shù)組中從
off
開始的數(shù)據(jù)寫入
os
中,一共寫
len
個
|
void
|
close()
|
關(guān)閉字節(jié)流
|
void
|
flush()
|
重要:我們知道
I/O
的速度是很慢的,所以,大多的
OutputStream
為
了減少設(shè)備操作的次數(shù),在寫數(shù)據(jù)的時候都會將數(shù)據(jù)先暫時寫入內(nèi)存的
一個指定區(qū)域里,直到該區(qū)域滿了或者其他指定條件時才真正將數(shù)據(jù)寫
入設(shè)備中,這個區(qū)域一般稱為緩沖區(qū)。但造成一個結(jié)果,就是我們寫的
數(shù)據(jù),很可能會遺留一部分在緩沖區(qū)中。需要在最后或者合適的位置,
調(diào)用
flush
(刷新)操作,將數(shù)據(jù)刷到設(shè)備中。
|
說明
OutputStream 同樣只是一個抽象類,要使用還需要具體的實現(xiàn)類。我們現(xiàn)在還是只關(guān)心寫入文件中,所以使用 FileOutputStream文章來源:http://www.zghlxwxcb.cn/news/detail-523805.html
利用 OutputStreamWriter 進行字符寫入
import java.io.*;
public class Main {
? ?public static void main(String[] args) throws IOException {
? ? ? ?try (OutputStream os = new FileOutputStream("output.txt")) {
? ? ? ? ? ?String s = "你好中國";
? ? ? ? ? ?byte[] b = s.getBytes("utf-8");
? ? ? ? os.write(b);
// 不要忘記 flush
? ? ? ? ? ?os.flush();
? ? ? }
? }
}
利用 PrintWriter 找到我們熟悉的方法
上述,我們其實已經(jīng)完成輸出工作,但總是有所不方便,我們接來下將 OutputStream 處理下,使用PrintWriter 類來完成輸出,因為文章來源地址http://www.zghlxwxcb.cn/news/detail-523805.html
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é)進行數(shù)據(jù)讀
try (InputStream is = ...) {
? ?byte[] buf = new byte[1024];
? ?while (true) {
? ? ? ?int n = is.read(buf);
? ? ? ?if (n == -1) {
? ? ? ? ? ?break;
? ? ? }
? ? ? ?// buf 的 [0, n) 表示讀到的數(shù)據(jù),按業(yè)務(wù)進行處理
? }
}
如何按字節(jié)進行數(shù)據(jù)寫
try (OutputStream os = ...) {
? ?byte[] buf = new byte[1024];
? ?while (/* 還有未完成的業(yè)務(wù)數(shù)據(jù) */) {
? ? ? ?// 將業(yè)務(wù)數(shù)據(jù)填入 buf 中,長度為 n
? ? ? ?int n = ...;
? ? ? ?os.write(buf, 0, n);
? }
? ?os.flush(); // 進行數(shù)據(jù)刷新操作
}
如何按字符進行數(shù)據(jù)讀
try (InputStream is = ...) {
? ?try (Scanner scanner = new Scanner(is, "UTF-8")) {
? ? ? ?while (scanner.hasNextLine()) {
? ? ? ? ? ?String line = scanner.nextLine();
? ? ? ? ? ?// 根據(jù) line 做業(yè)務(wù)處理
? ? ? }
? }
}
如何按字符進行數(shù)據(jù)寫
try (OutputStream os = ...) {
? ?try (OutputStreamWriter osWriter = new OutputStreamWriter(os, "UTF-8")) {
? ? ? ?try (PrintWriter writer = new PrintWriter(osWriter)) {
? ? ? ? ? ?while (/* 還有未完成的業(yè)務(wù)數(shù)據(jù) */) {
? ? ? ? ? ? ? ?writer.println(...);
? ? ? ? ? }
? ? ? ? ? ?writer.flush(); // 進行數(shù)據(jù)刷新操作
? ? ? }
? }
}
到了這里,關(guān)于【文件操作與IO】Java中如何操作文件的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!