- 文件 VS 流
InputStream-字节输入流
- InputStream 抽象类是所有类字节输入流的超类
- InputStream 常用的子类
- FileInputStream:文件输入流
- BufferedInputStream:缓冲字节输入流
- ObjectInputStream:对象字节输入流
1. FileInputStream 介绍
- 要求:请使用
FileInputStream
读取hello.txt
文件,并将文件内容显示到控制台 - 如下 readFile01 方法不能读取中文文本,因为 FileInputStream 为字节输入流
/**
* 读取文件
* 单个字节的读取,效率比较低
*/
@Test
public void readFile01() {
String filePath = "e:\\hello.txt";
int readData = 0;
FileInputStream fileInputStream = null;
try {
// 创建 FileInputStream 对象,用于读取文件
fileInputStream = new FileInputStream(filePath);
// 从该输入流读取一个字节的数据,如果没有输入的可用,此方法将阻止
// 如果返回为 -1 时,说明读取完毕
while ((readData = fileInputStream.read()) != -1) {
//转成 char 显示
System.out.print((char) readData);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
// 关闭文件流,释放资源
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 使用读取字节数组的形式
/**
* 读取文件
* 使用 read(byte[] b) 提高效率
*/
@Test
public void readFile02() {
String filePath = "e:\\hello.txt";
// 字节数组,一次读取 8 个字节
byte[] bytes = new byte[8];
int readLength = 0;
FileInputStream fileInputStream = null;
try {
// 创建 FileInputStream 对象,用于读取文件
fileInputStream = new FileInputStream(filePath);
// 从该输入流读取一个字节的数据,如果没有输入的可用,此方法将阻止
// 如果返回为 -1 时,说明读取完毕
// 如果读取正常,返回实际读取的字节数
while ((readLength = fileInputStream.read(bytes)) != -1) {
System.out.print(new String(bytes, 0, readLength));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
// 关闭文件流,释放资源
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2. FileOutputStream 介绍
- 要求:请使用 FileOutputStream 在 hello.txt 文件,中写入 “hello,world”, 如果文件不存在,会创建文件
(注意:前提是目录已经存在)
- new FileOutputStream(filePath) 写入内容是会覆盖原来的内容
- new FileOutputStream(filePath, true) 写入内容追加到文件后面
/**
* 演示使用 FileOutputStream 将数据写入到文件中
* 如果该文件不存在,则创建该文件
*/
@Test
public void writeFile() {
// 创建 FileOutputStream 对象
String filePath = "e://hello.txt";
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(filePath);
// 写入一个字节
// fileOutputStream.write('a');
// 写入字符串
String str = "hello,world!";
// fileOutputStream.write(str.getBytes());
//write(byte[] b, int off, int len) 将 len 字节从位于偏移量 off 的指定字节数组写入此文件输出流
fileOutputStream.write(str.getBytes(), 0, 3);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3. 文件的拷贝
- 拷贝需要用到文件输入流和输出流,边读边写
- 如果文件足够大的时候,一次性读完就会把读取的文件全部放到内存中,不好判断文件和内存的大小是否匹配,所以还是需要边读边写
- 拷贝:将
e:\\music.jpg
拷贝d:\\music.jpg
//1. 创建文件的输入流,将文件读入到程序
//2. 创建文件的输出流,将读取到的文件数据,写入到指定的文件
String srcFilePath = "e:\\music.jpg";
String destFilePath = "d:\\music.jpg";
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try {
fileInputStream = new FileInputStream(srcFilePath);
fileOutputStream = new FileOutputStream(destFilePath);
// 定义一个字节数组,提高读取效果
byte[] buf = new byte[1024];
int readLen = 0;
while ((readLen = fileInputStream.read(buf)) != -1) {
// 读取到后,就写入到文件 通过 fileOutputStream
// 即一边读,一边写
fileOutputStream.write(buf, 0, readLen);
}
System.out.println("拷贝成功!");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
//关闭输入流和输出流,释放资源
if (fileInputStream != null) {
fileInputStream.close();
}
if (fileOutputStream != null) {
fileOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}