IO
IO的基本概念:
什么是输入?输入是一个从外界进入程序的方向,通常当我们需要使用读取“外界”的数据时候,使用输入。所以输入是用来读取数据。
什么是输出?输出是一个从程序发送到外界的方向,通常当我们需要输出到外界时候,使用输出,所以输出是用来写出数据的。
java将IO比作流,就像水流一样。但是流动的是二进制数据,所以在IO中有输入和输出之分。
InputStream和OutStream
java.io.InputStream:所有字节输入流的超类,其中定义了数据读取的方法,因此不管是什么设备我们都可以调用相同的方法来读取不同的设备。
int read()
读取一个字节,以int形式返回,该int值的低八位有效,若返回值为-1则表示EOF(读取完毕)。
int read(byte[] d)
尝试最多读取byte数组长度的字节数存入该数组,返回值为实际读取到的字节量。
java.io.OutStream:所有字节输出流的超类,其中定义了写出数据的方法。
void write(int d)
写出一个字节,写出的是int值得低8位
void write(byte[])
写出数组中的所有字节
文件流
文件流的作用
- 文件流实际是链接程序与硬盘中文件的"管道",用于读写文件的流
- 文件流以字节为单位读写数据
- 文件输出流:可将数据从内存写入到硬盘之中。以实现永久存储。
- 文件输入流:可以将硬盘中内容读到内存中使程序恢复到原有状态
常用构造器
构造器
- FileOutputStream(String FileName) 创建一个指向文件名称的文件中写出数据的文件输出流
- FileOutputStream(File file) 创建一个指向文件对象的文件输出流
- 如果创建时候文件不存在会自动创建文件
- 如果文件所在的目录不存在就会抛出异常FileNotFoundException
- 如果指定的文件已经存在且包含内容时候,创建流时候会将原有数据全部清除
写出字节数据
写出字节数据使用FileOutputStream,该类继承了java.io.OutputStream,该类提供了超类中要求写出的字节相关方法。
void write(int d)//只能写出低八位,如果超过八位也只写低八位
void write(byte[] data)//块写操作,一次性将byte数组内的所有内容写出
void write(byte[] data,int offset,int len)//块写操作,一次性将byte数组内从下标offset处开始连续n个字节写出。
关闭流 colse()
读取字节数据
读取字节数据使用FileInputStream,继承至java.io.InputStream,文件输入流提供了超类中要求的读取字节的相关方法。
int read()
读取一个字节,其返回值为读取的一个字节内容,其二进制的低八位有效,如果返回值为整数-1,则说明文件已经读到了末尾。
int read(byte[])
块读写操作,一次性读取byte[]长度的字节并存入到数组中,返回值为实际读取到的字节量。
复制文件
单字节复制
通过文件字节输入流和字节输出流实现单字节复制。
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyDemo {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("jsd/jsd2406/翡翠.webp");
FileOutputStream fos=new FileOutputStream("jsd/jsd2406/翡翠3.webp");
int n = 0;
while((n = fis.read()) != -1){
fos.write(n);
}
fis.close();
fos.close();
}
}
单字节复制的读写效率很差,原因是硬盘的机械特性决定着单字节的读写性能是极其低效的,这里涉及到磁盘很多机械特性,马达带动,电与磁的转换等等。越频繁的磁盘交互效率越低。
块读写
public int read(byte[] b)
从流中最多读取b.lengrh个字节并存入到数组b中,返回值为实际读取的字节数,若返回值为-1则读到了末尾。
块读写复制实例:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyDemo {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("jsd/jsd2406/翡翠.webp");
FileOutputStream fos=new FileOutputStream("jsd/jsd2406/翡翠3.webp");
int n = 0;
byte[] data=new byte[1024];
while((n = fis.read(data)) != -1){
fos.write(data);
}
fis.close();
fos.close();
}
}
但是运行之后发现一个问题,块读写复制之后的文件要比原来的文件大一点,原因是传入的byte[]数组长度较大,将多余内容也写入进去,因此我们应该使用write的重载方法,加入参数offset和len,这样当我们在读取最后的内容时候我们可以只写入读取的内容。
写入文本数据
使用字符串的getBytes()将字符串转换为一组字节
使用文件输出流的块写方法write(byte[] data)
追加模式
当我们在构造方法时候加入一个boolean的值true,那么写入的数据将会在原文件末尾添加。