1. 基本IO操作
1.1. InputStream与OutputStream
1.1.1. 输入与输出
我们编写的程序除了自身会定义一些数据信息外,经常还会引用外界的数据,或是将自身的数据发送到外界。比如,我们编写的程序想读取一个文本文件,又或者我们想将程序中的某些数据写入到一个文件中。这时我们就要使用输入与输出。
什么是输入:输入是一个从外界进入到程序的方向,通常我们需要“读取”外界的数据时,使用输入。所以输入是用来读取数据的。
什么是输出:输出是一个从程序发送到外界的方向,通常我们需要”写出”数据到外界时,使用输出。所以输出是用来写出数据的。1.1.2. 节点流与处理流
按照流是否直接与特定的地方 (如磁盘、内存、设备等) 相连,分为节点流和处理流两类。
节点流:可以从或向一个特定的地方(节点)读写数据。
处理流:是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。
处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接。1.1.3. InputStream与OutputStream常用方法
InputStream是所有字节输入流的父类,其定义了基础的读取方法,常用的方法如下:
int read()
读取一个字节,以int形式返回,该int值的”低八位”有效,若返回值为-1则表示EOF。
- int read(byte[] d)
尝试最多读取给定数组的length个字节并存入该数组,返回值为实际读取到的字节量。
OutputStream是所有字节输出流的父类,其定义了基础的写出方法,常用的方法如下:
void write(int d)
写出一个字节,写的是给定的int的”低八位”
- void write(byte[] d)
将给定的字节数组中的所有字节全部写出
1.2. 文件流
1.2.1. 创建FOS对象(重写模式)
FileOutputStream是文件的字节输出流,我们使用该流可以以字节为单位将数据写入文件。
构造方法:
FileOutputStream(File file)
创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
例如:
- FIle file = new File("demo.dat");
- FileOutputStream fos = new FileOutputStream(file);
构造方法:
FileOutputStream(String filename):
创建一个向具有指定名称的文件中写入数据的输出文 件流。
例如:
- FileOutputStream fos = new FileOutputStream("demo.dat");
这里需要注意,若指定的文件已经包含内容,那么当使用FOS对其写入数据时,会将该文件中原有数据全部清除。
1.2.2. 创建FOS对象(追加模式)
通过上一节的构造方法创建的FOS对文件进行写操作时会覆盖文件中原有数据。若想在文件的原有数据之后追加新数据则需要以下构造方法创建FOS
构造方法:
FileOutputStream(File file,boolean append)
创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
例如:
- File file = new File("demo.dat");
- FileOutputStream fos = new FileOutputStream(file,true);
构造方法:
FileOutputStream(String filename,boolean append):
创建一个向具有指定名称的文件中写入数据的输出文 件流。
例如:
- FileOutputStream fos = new FileOutputStream("demo.dat",true);
以上两个构造方法中,第二个参数若为true,那么通过该FOS写出的数据都是在文件末尾追加的。
1.2.3. 创建FIS对象
FileInputStream是文件的字节输入流,我们使用该流可以以字节为单位读取文件内容。
FileInputStream有两个常用的构造方法:
FileInputStream(File file):
创建用于读取给定的File对象所表示的文件FIS
例如:
- File file = new File("demo.dat");
- FileInputStream fis
- = new FileInputStream(file);//创建一个用于读取demo.dat文件的输入流
另一个构造方法:
FileInputStream(String name):
创建用于读取给定的文件系统中的路径名name所指定的文件的FIS
例如
- FileInputStream fis
- //创建一个用于读取demo.dat文件的输入流
- = new FileInputStream("demo");
1.2.4. read()和write(int d)方法
FileInputStream继承自InputStream,其提供了以字节为单位读取文件数据的方法read。
int read()
从此输入流中读取一个数据字节,若返回-1则表示EOF(End Of File)
FileOutputStream继承自OutputStream,其提供了以字节为单位向文件写数据的方法write。
- void write(int d)
将指定字节写入此文件输出流。,这里只写给定的int值的”低八位”
例如
FileOutputStream fos = new FileOutputStream("demo.dat");
fos.write('A');//这里要注意,char占用2个字节,但这里只写入了1个字节。
1.2.5. read(byte[] d)和write(byte[] d)方法
FileInputStream也支持批量读取字节数据的方法:
- int read(byte[] b)
从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中 。
FileOutputStream也支持批量写出字节数据的方法:
void write(byte[] d)
将 b.length 个字节从指定 byte 数组写入此文件输出流中。
例如:
- FileOutputStream fos = new FileOutputStream("demo.txt");
- byte[] data = "HelloWorld".getBytes();
- fos.write(data);//会将HelloWorld的所有字节写入文件。
将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流的方法:
void write(byte[] d,int offset,int len)
例如:
- FileOutputStream fos = new FileOutputStream("demo.txt");
- byte[] data = "HelloWorld".getBytes();
- fos.write(data,5,5);//只会将world这5个字节写入文件。
1.3. 缓冲流
1.3.1. BOS基本工作原理
与缓冲输入流相似,在向硬件设备做写出操作时,增大写出次数无疑也会降低写出效率,为此我们可以使用缓冲输出流来一次性批量写出若干数据减少写出次数来提高写 出效率。
BufferedOutputStream缓冲输出流内部也维护着一个缓冲区,每当我们向该流写数据时,都会先将数据存入缓冲区,当缓冲区已满时,缓冲流会将数据一次性全部写出
1.3.2. BOS实现写出缓冲
实现写出缓冲:
- public void testBos()throws Exception {
- FileOutputStream fos = new FileOutputStream("demo.dat");
- //创建缓冲字节输出流
- BufferedOutputStream bos
- = new BufferedOutputStream(fos);
- //所有字节被存入缓冲区,等待一次性写出
- bos.write("helloworld".getBytes());
- //关闭流之前,缓冲输出流会将缓冲区内容一次性写出
- bos.close();
- }