🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇
File & IOStream
🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇🎇
今日推荐歌曲: death bed (coffee for your head ) -- Powfu / beabadoobee 🎵🎵
前言
本文会详细讲述 File 类的用法和 InputStream, OutputStream 的用法
一、File概述
我们先来看看 File 类中的常⻅属性、构造⽅法和⽅法
常见属性:
- Path Separator(路径分隔符): 用于分隔文件路径中的目录的字符串,例如在 Unix/Linux 系统中是 "/",在 Windows 系统中是 "\"。
- Separator(文件分隔符): 用于分隔文件路径中文件名和目录名的字符串,与路径分隔符有时是相同的,但不总是相同。
构造方法
- File(String pathname): 通过给定的路径名创建一个新的 File 实例。
- File(String parent, String child): 根据指定的父路径名字符串和子路径名字符串创建一个新的 File 实例。
- File(File parent, String child): 根据指定的父抽象路径名和子路径名字符串创建一个新的 File 实例。
方法
- boolean exists(): 判断文件或目录是否存在。
- boolean isFile(): 判断是否为文件。
- boolean isDirectory(): 判断是否为目录。
- String getName(): 返回文件或目录的名称。
- String getPath(): 返回文件或目录的路径。
- String getAbsolutePath(): 返回文件或目录的绝对路径。
- long length(): 返回文件的长度(字节数)。
- boolean createNewFile(): 创建一个新的空文件。
- boolean mkdir(): 创建此抽象路径名指定的目录。
- boolean mkdirs(): 创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。
- boolean delete(): 删除此抽象路径名表示的文件或目录。
- boolean renameTo(File dest): 重命名文件或目录为指定的路径名。
- String[] list(): 返回一个字符串数组,表示该目录中的文件和目录的名称。
- File[] listFiles(): 返回一个抽象路径名数组,表示该目录中的文件和目录。
- boolean canRead(): 测试应用程序是否可以读取文件。
- boolean canWrite(): 测试应用程序是否可以修改文件。
- boolean setReadOnly(): 设置文件为只读。
- long lastModified(): 返回文件的最后修改时间。
代码⽰例
⽰例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
普通⽂件的删除
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");
// 要求该⽂件不存在,才能看到相
}
}
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());
运⾏结果
false
true
true
true
false
⽰例4
观察deleteOnExit的现象
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");
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
程序运⾏结束后,⽂件还是被删除了
⽰例5
观察⽬录的创建
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");
}
}
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
true
true
false
⽰例6
观察⽬录创建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");
}
}
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
// some-parent 和 so 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");
}
}
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());
// some-parent 和 so
运⾏结果
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());
运⾏结果
true
false
true
false
true
二、⽂件内容的读写⸺数据流
InputStream 概述
⽅法
说明
InputStream 只是⼀个抽象类,要使⽤还需要具体的实现类。关于InputStream的实现类有很多,基 本可以认为不同的输⼊设备都可以对应⼀个InputStream类,我们现在只关⼼从⽂件中读取,所以使 ⽤FileInputStream
FileInputStream 概述
代码⽰例
⽰例1
将⽂件完全读完的两种⽅式。相⽐较⽽⾔,后⼀种的IO次数更少,性能更好。
import java.io.*;
// 需要先在项⽬⽬录下准备好⼀个 hello.txt 的⽂件,⾥⾯填充 "Hello" 的内容
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) {
//
代表⽂件已经全部读完
break;
}
System.out.printf("%c", b);
}
}
}
}
import java.io.*;
// 需要先在项⽬⽬录下准备好⼀个 hello.txt 的⽂件,⾥⾯填充 "Hello" 的内容
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;
}
for (int i = 0; i < len; i++) {
System.out.printf("%c", buf[i]);
}
}
}
}
}
⽰例2
这⾥我们把⽂件内容中填充中⽂看看,注意,写中⽂的时候使⽤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);
}
}
}
}
}
另一种
package io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
// 按照字节流来读取文件 一次读取若干个字节
public class IODemo9 {
public static void main(String[] args) throws IOException {
try(InputStream inputStream = new FileInputStream("./text.txt")){
while(true){
byte[] buffer = new byte[1024];
int n = inputStream.read(buffer);
if(n==-1){
break;
}
// 读取的时候, 将文件的 utf8 转为 unicode ,里边的汉字也转化了, 这里再次转化成字符串String 就是再转回 utf8
String s = new String(buffer,0,n);
System.out.println(s);
}
}
}
}
利⽤Scanner进⾏字符读取
上述例⼦中,我们看到了对字符类型直接使⽤InputStream进⾏读取是⾮常⿇烦且困难的,所以,我 们使⽤⼀种我们之前⽐较熟悉的类来完成该⼯作,就是Scanner类。
⽰例1
import java.io.*;
import java.util.*;
//使⽤charset字符集进⾏is的扫描读取
// 需要先在项⽬⽬录下准备好⼀个 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概述
说明 OutputStream同样只是⼀个抽象类,要使⽤还需要具体的实现类。我们现在还是只关⼼写⼊⽂件 中,所以使⽤FileOutputStream
利⽤OutputStreamWriter进⾏字符写⼊
⽰例1
package io;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class IODemo10 {
public static void main(String[] args) throws IOException {
//用 outputStream 来写文件 末尾追加 true
try(OutputStream outputStream = new FileOutputStream("./text.txt",true)){
byte[] buffer = new byte[]{97,98,99,100,101,102};
outputStream.write(buffer);
}
}
}
利⽤PrintWriter找到我们熟悉的⽅法
上述,我们其实已经完成输出⼯作,但总是有所不⽅便,我们接来下将OutputStream处理下,使⽤ PrintWriter 类来完成输出,因为 PrintWriter 类中提供了我们熟悉的print/println/printf⽅法
package io;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
public class IODemo12 {
public static void main(String[] args) throws IOException {
// 使用字符流来写入文件
try(Writer writer = new FileWriter("./text.txt")){
String s = "你好,java";
writer.write(s);
}
}
}
PrintReader
package io;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
public class IODemo11 {
// 使用 字符流 来读取文件
public static void main(String[] args) throws IOException {
try(Reader reader = new FileReader("./text.txt")){
while(true) {
char[] buffer = new char[1024];
int n = reader.read(buffer);
if(n == -1){
break;
}
String s = new String(buffer,0,n);
System.out.println(s);
//char 占两个字节 却能存 汉字(三个字节) 是因为 reader 读取的时候 将文件的 utf8码 转化成了 unicode码
//所以 buffer 实际上存的是 unicode码 的数据,后来转成String的时候转回了 utf8 的编码了
}
}
}
}
总结
- File 类用于表示文件或目录的路径名,并提供了一系列方法来操作文件系统。它可以用于创建、删除、重命名、检查文件或目录的存在性等操作。
- InputStream 和 OutputStream 是 Java I/O 中的两个基本抽象类,用于字节流的输入和输出操作。
- InputStream 用于读取字节流数据,而 OutputStream 用于写入字节流数据。这两个类的子类提供了各种方法来读写文件、网络连接等不同来源的数据。
- 通常,File 类用于操作文件路径和元数据,而 InputStream 和 OutputStream 用于实际的数据读写操作。
真嘟超级详细,都是手敲的 ,希望能帮助大伙,博客不易,
点赞 收藏 加关注,知识进脑不迷路!!!