一、IO流的类层次图
一个流被定义为一个数据序列。输入流用于从源读取数据,输出流用于向目标写数据。
下图是一个描述输入流和输出流的类层次图。
粘贴自菜鸟教程-JAVA-流
二、FileInputStream
2.1概念
FileInputStream流被称为文件字节输入流,意思指对文件数据以字节的形式进行读取操作如读取图片视频等
2.2构造方法
可用字符串类型的文件名来创建一个输入流对象来读取文件:
InputStream f=new FileInputStream("C:\\java\\hello");
也可以使用一个文件对象来创建一个输入流对象来读取文件。我们首先得使用File()方法来创建一个文件对象:
File f=new file("C:\\java\\hello");
InputStream out= new FileInputStream(f);
通过使用文件描述符 fdObj 创建一个FileInputStream,该文件描述符表示到文件系统中某个实际文件的现有连接。
FileInputStream(FileDescriptor fdObj)
2.3方法
方法名 | 方法描述 |
public void close() throws IOException{} | 关闭此文件输入流并释放与此流有关的所有系统资源。抛出IOException异常。 |
protected void finalize()throws IOException {} | 这个方法清除与该文件的连接。确保在不再引用文件输入流时调用其 close 方法。抛出IOException异常。 |
public int read(int r)throws IOException{} | 这个方法从 InputStream 对象读取指定字节的数据。返回为整数值。返回下一字节数据,如果已经到结尾则返回-1。 |
public int read(byte[] r) throws IOException{} | 这个方法从输入流读取r.length长度的字节。返回读取的字节数。如果是文件结尾则返回-1。 |
public int read(byte[] byte[] b, int off, int len) throws IOException{} | 从此输入流中将最多 len 个字节的数据读入一个 byte 数组中。 |
public int available() throws IOException{} | 返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取的字节数。返回一个整数值。 |
public FileChannel getChannel() | 返回与此文件输入流有关的唯一FileChannel 对象。 |
FileDescriptor getFD() | 返回表示到文件系统中实际文件的连接的 FileDescriptor 对象,该文件系统正被此FileInputStream 使用。 |
long skip(long n) | 从输入流中跳过并丢弃 n 个字节的数据。 |
- 三种read方法比较:
1、查看三种read方法源码,其本质都是利用for循环对内容进行单字节的读取
2、从代码形式看,使用read(byte[] b)较为直观和简便,因此项目中可以此方法为主进行数据读取
3、其中read()返回的是读入的一个字节所对应的int值(0-255),而read(byte[] b) 和read(byte[] b, int off, int len) 返回的是读入的字节数
三、FileOutputStream
3.1概念
该类用来创建一个文件并将字节数据写出到文件。
如果该流在打开文件进行输出前,目标文件不存在,那么该流会创建该文件。
3.2构造方法
使用字符串类型的文件名来创建一个输出流对象:
OutputStream f = new FileOutputStream("C:/java/hello")
也可以使用一个文件对象来创建一个输出流来写文件。我们首先得使用File()方法来创建一个文件对象:
File f = new File("C:/java/hello");
OutputStream f = new FileOutputStream(f);
3.3方法
方法名 | 方法描述 |
public void close() throws IOException{} | 关闭此文件输入流并释放与此流有关的所有系统资源。抛出IOException异常。 |
protected void finalize()throws IOException {} | 这个方法清除与该文件的连接。确保在不再引用文件输入流时调用其 close 方法。抛出IOException异常。 |
public void write(int w)throws IOException{} | 这个方法把指定的字节写到输出流中。 |
public void write(byte[] w) | 把指定数组中w.length长度的字节写到OutputStream中。 |
public void write(byte[] w, int off, int len) | 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。 |
public FileChannel getChannel() | 返回与此文件输出流有关的唯一FileChannel 对象。 |
FileDescriptor getFD() | 返回与此流有关的文件描述符。 |
四、实例
4.1
将指定内容以二进制形式写进文件,同时输出到控制台上可能存在乱码。以下代码可解决乱码问题
import java.io.*;
public class Basic006 {
public static void main(String args[])throws IOException {
File f=new File("D:\\java\\test\\test003.txt");
FileOutputStream fop=new FileOutputStream(f);//构建FileOutputStream对象,文件不存在会自动新建。
OutputStreamWriter writer=new OutputStreamWriter(fop,"UTF-8");//构建OutputStreamWriter对象,参数可以指定编码,默认为操作系统默认编码,Windows上是gbk
writer.append("中文输入");//写入缓存区
writer.append("\r\n");//换行
writer.append("English");//刷新缓存冲,写入到文件,如果下面已经没有写入的内容了,直接close也会写入
writer.close();//关闭写入流,同时会把缓冲区内容写入文件,所以上面的注释掉
fop.close();//关闭输出流,释放系统资源。
FileInputStream fip=new FileInputStream(f);//构建FileInputStream对象
InputStreamReader reader=new InputStreamReader(fip,"utf-8");//构建InputStreamReader对象,编码与写入相同
StringBuffer sb=new StringBuffer();
while(reader.ready()) {
sb.append((char)reader.read());//转成char加到StringBuffer对象中
}
System.out.println(sb.toString());
reader.close();//关闭读取流
fip.close();//关闭输入流,释放系统资源
}
}
打印输出结果
D盘JAVA文件夹下test文件夹中新建的txt
4.2 使用这两个类进行文件复制
try {
FileInputStream fis=new FileInputStream("D:\\java\\test\\test001.txt");
FileOutputStream fos=new FileOutputStream("D:\\java\\test\\copy001.txt");
int read;
byte b[]=new byte[1024];
//读取文件,存入字节数组b,返回读取到的字符数,存入read,默认每次将b数组装满
read=fis.read(b);
while(read!=-1) {
fos.write(b,0,read);
read=fis.read(b);
}
fis.close();
fos.close();
}catch(IOException e){
e.printStackTrace();
}
关于fis.read(b)的值:
1、此文件中的数字和字母都是一个字节,汉字三个字节(不同字符编码字节数不同)
2、要在原本数字字母汉字的基础上加3(文件头的字节)是总的字节数
3、若b的值小于总字节数,则以b为准,直到到文件末尾,若b的值大于总字节数,则fis.read(b)=总字节数。
FileInputStream 和FileOutputStream适用于操作于任何形式的文件(因为是以字节为向导),如果想要操作文本文件,采用FileInputReader和FileOutputWriter效率更高。