目录
Java 中操作文件
File 概述
属性
构造方法
方法
代码示例
文件内容的读写 —— 数据流
InputStream 概述
FileInputStream 概述
利用 Scanner 进行字符读取
OutputStream 概述
利用 OutputStreamWriter 进行字符写入
利用 PrintWriter 找到我们熟悉的方法
代码参考
如何按字节进行数据读
如何按字节进行数据写
如何按字符进行数据读
如何按字符进行数据写
Java 中操作文件
操作系统的一个重要功能就是对文件的管理,每个操作系统都有自己的一套系统API调用,Java作为一个跨平台的语言,JVM针对不同的操作系统做了一层封装,我们只需使用JDK提供的关于文件操作的API就可以完成不同的系统上的文件操作。
Java 中通过 java.io.File 类来对一个文件(包括目录)进行抽象的描述。注意,有 File 对象,并不代表真实存在该文件。
File 概述
属性
修饰符及类型 |
属性 |
说明 |
static String |
pathSeparator |
依赖于系统的路径分隔符,String 类型的表示 |
static char |
pathSeparator |
依赖于系统的路径分隔符,char 类型的表示 |
构造方法
方法
修饰符及返回 值类型 |
方法签名 |
说明 |
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() |
根据 File 对象,自动创建一个空文件。成功创建后返 回 true |
boolean |
delete() |
根据 File 对象,删除该文件。成功删除后返回 true |
void |
deleteOnExit() |
根据 File 对象,标注文件将被删除,删除动作会到 JVM 运行结束时才会进行 |
String[] |
list() |
返回 File 对象代表的目录下的所有文件名 |
File[] |
listFiles() |
返回 File 对象代表的目录下的所有文件,以 File 对象 表示 |
boolean |
mkdir() |
创建 File 对象代表的目录 |
boolean |
mkdirs() |
创建 File 对象代表的目录,如果必要,会创建中间目 录 |
boolean |
renameTo(File dest) |
进行文件改名,也可以视为我们平时的剪切、粘贴操 作 |
boolean |
canRead() |
判断用户是否对文件有可读权限 |
boolean |
canWrite() |
判断用户是否对文件有可写权限 |
代码示例
示例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());
}
}
运行结果
..
hello-world.txt
..\hello-world.txt
D:\代码练习\文件示例1\..\hello-world.txt
D:\代码练习\hello-world.txt
示例2
普通文件的创建、删除
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.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());
}
}
运行结果
false
false
false
true
true
false
true
false
示例3
观察 deleteOnExit 的现象
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
File file = new File("some-file.txt"); // 要求该文件不存在,才能看到相同的现象
System.out.println(file.exists());
System.out.println(file.createNewFile());
System.out.println(file.exists());
file.deleteOnExit();
System.out.println(file.exists());
}
}
运行结果
false
true
true
true
程序运行结束后,文件还是被删除了
示例4
观察目录创建
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());
}
}
运行结果
false
false
false
false
false
mkdir() 的时候,如果中间目录不存在,则无法创建成功; 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());
}
}
运行结果
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());
}
}
运行结果
true
false
true
false
true
文件内容的读写 —— 数据流
数据流分类
InputStream 概述
方法
修饰符及
返回值类
型
|
方法签名
|
说明
|
int
|
read()
|
读取一个字节的数据,返回
-1
代表已经完全读完了
|
int
|
read(byte[] b)
|
最多读取
b.length
字节的数据到
b
中,返回实际读到的数
量;
-1
代表以及读完了
|
int
|
read(byte[] b,
int off, int len)
|
最多读取
len - off
字节的数据到
b
中,放在从
off
开始,返
回实际读到的数量;
-1
代表以及读完了
|
void |
close()
|
关闭字节流
|
说明
InputStream 只是一个抽象类,要使用还需要具体的实现类。关于 InputStream 的实现类有很多,基本可以认为不同的输入设备都可以对应一个 InputStream 类,我们现在只关心从文件中读取,所以使用 FileInputStream
FileInputStream 概述
签名
|
说明
|
FileInputStream(File file)
|
利用
File
构造文件输入流
|
FileInputStream(String name)
|
利用文件路径构造文件输入流
|
示例
这里我们把文件内容中填充中文看看,注意,写中文的时候使用 UTF-8 编码。hello.txt 中填写 "你好中国"
注意:这里我利用了这几个中文的 UTF-8 编码后长度刚好是 3 个字节和长度不超过 1024 字节的现状,但这种方式并不是通用的
import java.io.*;
// 需要先在项目目录下准备好一个 hello.txt 的文件,里面填充 "你好中国" 的内容
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) {
// 代表文件已经全部读完
break;
}
// 每次使用 3 字节进行 utf-8 解码,得到中文字符
// 利用 String 中的构造方法完成
// 这个方法了解下即可,不是通用的解决办法
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 类。
构造方法
|
说明
|
Scanner(InputStream is, String charset)
|
使用
charset
字符集进行
is
的扫描读取
|
import java.io.*;
import java.util.*;
// 需要先在项目目录下准备好一个 hello.txt 的文件,里面填充 "你好中国" 的内容
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)
|
写入要给字节的数据
|
void
|
write(byte[]
b)
|
将
b
这个字符数组中的数据全部写入
os
中
|
int |
write(byte[]
b, int off,
int len)
|
将
b
这个字符数组中从
off
开始的数据写入
os
中,一共写
len
个
|
void
|
close()
|
关闭字节流
|
void
|
flush()
|
重要:我们知道
I/O
的速度是很慢的,所以,大多的
OutputStream
为
了减少设备操作的次数,在写数据的时候都会将数据先暂时写入内存的
一个指定区域里,直到该区域满了或者其他指定条件时才真正将数据写
入设备中,这个区域一般称为缓冲区。但造成一个结果,就是我们写的
数据,很可能会遗留一部分在缓冲区中。需要在最后或者合适的位置,
调用
flush
(刷新)操作,将数据刷到设备中。
|
说明
OutputStream 同样只是一个抽象类,要使用还需要具体的实现类。我们现在还是只关心写入文件中,所以使用 FileOutputStream文章来源:https://www.toymoban.com/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 找到我们熟悉的方法
上述,我们其实已经完成输出工作,但总是有所不方便,我们接来下将 OutputStream 处理下,使用PrintWriter 类来完成输出,因为文章来源地址https://www.toymoban.com/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("我的第二行\r\n");
writer.printf("%d: 我的第三行\r\n", 1 + 1);
writer.flush();
}
}
}
}
}
代码参考
如何按字节进行数据读
try (InputStream is = ...) {
byte[] buf = new byte[1024];
while (true) {
int n = is.read(buf);
if (n == -1) {
break;
}
// buf 的 [0, n) 表示读到的数据,按业务进行处理
}
}
如何按字节进行数据写
try (OutputStream os = ...) {
byte[] buf = new byte[1024];
while (/* 还有未完成的业务数据 */) {
// 将业务数据填入 buf 中,长度为 n
int n = ...;
os.write(buf, 0, n);
}
os.flush(); // 进行数据刷新操作
}
如何按字符进行数据读
try (InputStream is = ...) {
try (Scanner scanner = new Scanner(is, "UTF-8")) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
// 根据 line 做业务处理
}
}
}
如何按字符进行数据写
try (OutputStream os = ...) {
try (OutputStreamWriter osWriter = new OutputStreamWriter(os, "UTF-8")) {
try (PrintWriter writer = new PrintWriter(osWriter)) {
while (/* 还有未完成的业务数据 */) {
writer.println(...);
}
writer.flush(); // 进行数据刷新操作
}
}
}
到了这里,关于【文件操作与IO】Java中如何操作文件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!