Java 输入输出流
Java 标准库 java.io 提供了 File 对象用于操作文件和目录
- File(String pathName) 通过将给定路径名字符串转换为抽象路径名来创建新实例
- File(String parent, String child) 从父路径名字符串和子路径名字符串创建新实例
- File(File parent, String child) 从父抽象路径名和子路径名字符串创建新实例
java
import java.io.File;
public class FileObject {
public static void main(String[] args) {
File file1 = new File("D:/IOStream/data/1.txt");
System.out.println(file1);
File file2 = new File("D:/IOStream/data", "1.txt");
System.out.println(file2);
File file3 = new File("D:/IOStream/data");
File file4 = new File(file3, "1.txt");
System.out.println(file4);
}
}
public class FilePath {
public static void main(String[] args) throws IOException {
File file = new File("../data/1.txt");
System.out.println(file.getPath());
System.out.println(file.getAbsolutePath());
System.out.println(file.getCanonicalPath());
}
}文件和目录操作
java
import java.io.File;
import java.io.IOException;
public class CreateAndDelete {
public static void main(String[] args) throws IOException {
File file1 = new File("D:/IOStream/data/2.txt");
if (file1.createNewFile()) {
System.out.println("创建文件成功");
} else {
System.out.println("创建文件失败");
}
if (file1.delete()) {
System.out.println("删除文件成功");
} else {
System.out.println("删除文件失败");
}
File file2 = new File("D:/IOStream/data/demo");
if (file2.mkdir()) {
System.out.println("创建文件夹成功");
} else {
System.out.println("创建文件夹失败");
}
File file3 = new File("D:/IOStream/data/JavaSE/demo");
if (file3.mkdirs()) {
System.out.println("创建多级目录成功");
} else {
System.out.println("创建多级目录失败");
}
}
}| 返回值 | 方法 | 描述 |
|---|---|---|
| boolean | isFile() | 测试此抽象路径名表示的文件是否为普通文件 |
| boolean | isDirectory() | 测试此抽象路径名表示的文件是否为目录 |
| boolean | exists() | 测试此抽象路径名表示的文件或目录是否存在 |
| String | getPath() | 将抽象路径转换为路径字符串 |
| String | getAbsolutePath() | 返回此抽象路径名的绝对路径名字符串 |
| String | getName() | 返回由此抽象路径名表示的文件或目录的名称 |
| String[] | list() | 返回字符串数组,表示该抽象路径名表示目录下的文件和目录 |
| File[] | listFiles() | 返回抽象路径名数组,表示该抽象路径名表示目录下的文件 |
流
| 字节流 | 字符流 | |
|---|---|---|
| 输入流 | InputStream | Reader |
| 输出流 | OutputStream | Writer |
所谓 FileInputStream,就是从文件流中读取数据,然后将数据从文件中读取到内存,常用方法如下:
| 返回值 | 方法 | 描述 |
|---|---|---|
| int | available() | 返回该输入流中可以读取的字节数的估计值 |
| void | close() | 关闭输入流并释放相关资源 |
| int | read(bytep[] b) | 从输入流读取一些字节数,并将其存储到缓冲区 b |
下面是一个从文件中读取数据到内存中的实例,文件内容如下:
java
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class TestInputStream {
public static void main(String[] args) {
String result = null;
File file = new File("D:/IOStream/data/1.txt");
try (InputStream inputStream = new FileInputStream(file)) {
// 读取输入流中可以被读的 bytes 估计值
int size = inputStream.available();
// 根据 bytes 数创建数组
byte[] array = new byte[size];
// 数据读取到数组
inputStream.read(array);
// 数组转化为字符串
result = new String(array);
} catch (IOException e) {
e.printStackTrace();
}
// 打印字符串
System.out.println(result);
}
}OutputStream 并非是并不是一个接口,而是所有输出字节流的所有类的父类。下面我们主要以 FileOutputStream 来举例,所谓 FileOutputStream,就是从内存中读取数据,然后将数据从内存存放到文件中,常用方法如下:
| 返回值 | 方法 | 描述 |
|---|---|---|
void | write(byte[] b) | 将 b.length 个字节从指定字节数组写入此文件输出流 |
void | close() | 关闭文件输出流并释放相关资源 |
java
import java.io.*;
public class TestOutputStream {
public static void main(String[] args) {
File file = new File("D:/IOStream/data/2.txt");
String content = "这是一个 OutputStream 实例!";
try (OutputStream outputStream = new FileOutputStream(file)) {
// 字符串转换为 byte 数组
byte[] array = content.getBytes();
// 写入数据
outputStream.write(array);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("写入成功");
}
}需要注意的点:
- 字节流写入数据时如何实现换行?
写入换行的转义字符的字节数组即可,但是需要注意,不同系统下换行的转义字符不同,Windows 下为 \r\n,macOS 下为 \r,而 Linux 下为 \m。
- 字节流写入数据时如何实现追加?
调用 public FileOutputStream(String name, boolean append) 这个构造方法即可,当 append 为 true 时,表示追加,默认情况下是 false,表示不追加。
字符串中的编解码问题
编码
byte[] getBytes():使用平台默认字符集将该字符串编码成一系列字节,然后将结果存储到新的字节数组中;byte[] getBytes(String charsetName):使用指定字符集将该字符串编码为一系列字节,然后将结果存储到新的字节数组中;
解码
String(byte[] bytes):使用平台默认字符集解码指定的字节数来构造新的字符串;String(byte[] bytes, String charsetName):通过指定的字符集解码指定的字节数组来构造新的字符串;
java
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class EncodeAndDecode {
public static void main(String[] args) throws UnsupportedEncodingException {
// 编码
String str = "tomiaa";
byte[] bytes1 = str.getBytes();
byte[] bytes2 = str.getBytes("UTF-8");
byte[] bytes3 = str.getBytes("GBK");
System.out.println(Arrays.toString(bytes1));
System.out.println(Arrays.toString(bytes2));
System.out.println(Arrays.toString(bytes3));
// 解码
String res1 = new String(bytes1);
String res2 = new String(bytes1, "UTF-8");
String res3 = new String(bytes1, "GBK");
System.out.println(res1);
System.out.println(res2);
System.out.println(res3);
}
}Writer
当我们要写入基于字符的数据到数据源中时,需要使用写入器 Writer. 以其中的 FileWriter 具体展开,其常用方法如下:
| 返回值 | 方法 | 描述 |
|---|---|---|
void | close() | 先刷新再关闭流,不能再写数据 |
void | flush() | 刷新流,可以继续写数据 |
void | newLine() | 写入行分隔符 |
void | write() | 写入字符或字符串 |
java
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class TestWriter {
public static void main(String[] args) {
File file = new File("D:/TheWay2Java/IOStream/data/2.txt");
try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file))) {
bufferedWriter.write("123123");
bufferedWriter.newLine();
bufferedWriter.write("asdasd");
bufferedWriter.newLine();
bufferedWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("写入成功");
}
}Reader
当我们要从数据源读取基于字符的数据时,需要使用读取器 Reader. 我们以 FileReader 实践,其常用的方法有:
| 返回值 | 方法 | 描述 |
|---|---|---|
void | close() | 关闭流并释放相关资源 |
int | read() | 读取一个字符 |
String | readLine() | 读一行文字 |
boolean | ready() | 获取该流是否准备好被读取 |
我们以从文件中读取内容为例:
java
import java.io.*;
public class TestReader {
public static void main(String[] args) {
String content = null;
File file = new File("D:/IOStream/data/2.txt");
System.out.println("内容如下:");
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) {
while ((content = bufferedReader.readLine()) != null) {
System.out.println(content);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}