IO指的是Input,Output.即:输入与输出
流按照方向实际是按照功能进行划分,参照方向是我们的程序
输入流用于读取,即:从外界进入程序的过程,获取数据
输出流用于写出,即:程序发送到外界的过程,发送数据
流划分为两类:
节点流,处理流
节点流:又称为低级流,是真实连接程序与数据源的”管道”,负责实际搬运数据.读写一定是建立在节点流的基础之上进行的
处理流:又称为高级流,高级流不能独立存在(没有意义),一定是连接在其他流上使用的目的是通过其连接的流将数据流经此流时对数据进行加工处理,从而简化我们实际对读写的数据加工的操作
流的链接:在低级流的基础上,通过组合多个高级流在读写过程中完成一系列的数据加工操作的过程,称为流的链接.
这也是java标准IO操作的精髓所在(学习重点就是学习如何组建流链接,完成一些列读写操作)
java.io.InputStream:所有字节输入流的超类,规定了所有输入流都应当具备的读写字节的相关方法
java.io.OutputStream:所有字节输出流的超类,规定了所有输出流都应当具备的写出字节的相关方法
文件流:是一对低级流,用来读写文件数据
java.io.FileInputStream:文件输入流,用来向文件中读取字节的流
java.io.FileOutputStream:文件输出流,用于向文件中写出字节的流
论功能,与RandomAccessFile一致,但是RAF又能读又能写,而文件流要根据做读或写操作选取输入或输出流进行.
并且它们的底层实际读写操作是不一样的,RAF是基于指针对文件进行读写,所以可以根据指针进行部分覆盖写操作等,
做到对文件数据编辑操作.但是流做不到,因为流是[顺序读写]操作.所以对于灵活性而言,RAF是优于文件流的.但是文件流基于IO操作可以通过连接不同高级流更轻松的完成复杂的读写操作
对于读写文件而言:
RAF是基于指针的读写,称为”随机读写”.可以移动指针对任意位置读写操作.
文件流是流的读写方式,而流是”顺序读写”,只能顺序往后读写操作,是不能回退操作的.
FOS演示
public class FOSDemo {
public static void main(String[] args) throws IOException {
/*
* 文件输出流创建出来,默认为覆盖模式
* 即:当操作文件已经存在,那么在创建号文件输出流时会先将该文件所有数据清除. 然后通过该流写出的所有数据作为文件数据
*
* 文件流还支持重载构造方法,在第一个参数基础上可以再传入一个boolean类型的参数,当该值为true时,即是追加模式
* 即:文件原有数据全部保留,通过该流写出的数据会被追加到文件末尾
*/
FileOutputStream fos = new FileOutputStream("fos.txt"); //默认覆盖模式
//FileOutputStream fos = new FileOutputStream("fos.txt",true); //追加模式
String line = "一天天天天天";
byte[] data = line.getBytes("GBK");
fos.write(data);
line = ",一月月月月月";
data = line.getBytes("GBK");
fos.write(data);
System.out.println("写出完毕");
fos.close();
}
}
FIS演示
public class FISDemo {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("fos.txt");
byte[] data = new byte[1024];
int len = fis.read(data);
String str = new String(data,0,len,"GBK");
System.out.println(str);
fis.close();
}
}
使用文件流完成文件的复制操作
public class CopyDemo1 {
public static void main(String[] args) throws IOException {
/*
* 步骤:
* 1.创建文件输入流用于读取原文件
* 2.创建文件输出流用于写出复制文件
* 3.顺序从原文件读取字节并写入到复制文件中完成复制操作
*/
FileInputStream fis = new FileInputStream("fos.txt");
FileOutputStream fos = new FileOutputStream("fos_copy.txt");
byte[] data = new byte[1024];
int len = -1;
while((len=fis.read(data))!=-1){
fos.write(data,0,len);
}
System.out.println("操作完毕");
fos.close();
fis.close();
}
}
处理流,也称高级流
在IO操作中,通常我们会在低级流上连接一些高级流,
这样当数据流经这些高级流时,它们可以对数据进行相应的加工处理,
以简化我们对数据的相关操作.而这个过程,称为流链接处理
缓冲流
缓冲流是一对高级流,作用是提高读写效率.
缓冲流内部维护一个数组,无论我们做随机读写还是块读写操作,最终都会在流经缓冲流时改变为块读写操作,从而提高了读写效率
缓冲流演示
public class CopyDemo2 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("movie.mp4");
FileOutputStream fos = new FileOutputStream("movie_copy.mp4");
//连接缓冲字节输出流,提高读写效率
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int d=-1;
while((d = bis.read())!=-1){
bos.write(d);
}
System.out.println("复制完成");
/*
* 关闭流的时候,只需要关闭最外层高级流即可
*
*/
bis.close();
bos.close();
}
}
缓冲输出流的缓冲区问题
public class BOS_flush {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("bos.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
String line = "秒针转动,滴滴答";
byte[] data = line.getBytes();
bos.write(data);
/*
* void flush()
* 缓冲流的flush方法用于强制将缓冲区中已缓存的数据进行一次性写出.
* 频繁的调用flush方法会降低写效率,但是能保证写出数据的即时性
*/
//bos.flush();
System.out.println("写出完毕");
//close方法中有一次flush操作
bos.close();
}
}
对象流
java.io.ObjectOutputStream
java.io.ObjectInputStream
对象流是一对高级流,使用它们可以很方便的进行java中任何对象的读写操作
public class OOSDemo {
public static void main(String[] args) throws IOException {
String name = "nick";
int age = 18;
String gender = "man";
String[] otherInfo = {"A","B","C"};
Person person = new Person(name,age,gender,otherInfo);
/*
* 将person对象写入文件"person.obj"
*/
FileOutputStream fos = new FileOutputStream("person.obj");
/*
* 为了方便写出对象,连接对象输出流
*/
ObjectOutputStream oos = new ObjectOutputStream(fos);
/*
*对象输出流提供方法
*void writeObject(Object obj)
*该方法用于将给定对象转换为一组字节后写出
*需要注意,写出的对象必须实现接口:Serializable,否则会抛出异常
*/
oos.writeObject(person);
System.out.println("写出完毕");
oos.close();
}
}