文章目录
0.前言
生活中存在水流、电流、车流等流。程序出于生活,程序中也有流。
JAVA中,往往通过流与外部进行数据交换。
我们可以将流理解为连接程序与外部设备之间的管道,管道里流的是字节。
1.流
从方向上对流进行初步的分类:以程序为原点,向文件输出数据的称作输出流OutputStream,读取文件的称为输入流InputStream。
本节介绍常用的流。
1.1 字节流
InputStream 和 OutStream 分别是字节输入、输出流,抽象类。
FileInputStream 和 FileOutputStream 分别继承自InputStream 、 OutputStream ,用于文件的读写。
至于JAVA文件的常用方法以及学习过程中可能遇到的异常处理问题,可参见JAVA基础之文件与异常处理
1.2.1 FileInputStream
作用:读取文件
例子:
FileInputStream fis = new FileInputStream("./test.txt");
/**
* 读取规则,一位一位地读,输出低八位,余位补0,读到末尾返回-1的补码
* 用基本类型接收的时候,会输出该位的二进制
* */
int index = 24;
while(index > 0 ){
char d = (char) fis.read();
System.out.println(d);
index --;
}
fis.close();
1.2.2 FileOutputStream
作用:写入文件
例子:
//向文件test.txt写入一个字节
FileOutputStream fos = new FileOutputStream("./test.txt");
//以程序为原点,要将东西写入文件,使用输出流
/*
* void write (int d)
* 写出一个字节,写出的内容是给定的int值对应的二进制的低八位
* */
int index = 26;
while(index >0){
fos.write(index+97);
index --;
}
System.out.println("写出完毕");
//流每次用完都需要关闭
fos.close();
File f = new File("./test.txt");
if(f.isFile()){
System.out.println(f.length());
}
根据上述例子学习完字节流,可以利用字节流复制文件玩一玩
public class CopyDemo {
public static void main(String[] args) throws IOException {
//定义流
long now = System.currentTimeMillis();
FileInputStream fis = new FileInputStream("./CpDemoPlus.mp4");
FileOutputStream fos = new FileOutputStream("./CpDemoPlus2.mp4");
//用比较简洁的方式复制
int index;
while ((index = fis.read())!=-1){
fos.write(index);
}
System.out.println("复制完毕!");
fis.close();
fos.close();
long after = System.currentTimeMillis();
System.out.println("复制经历了"+(after-now)+"ms");
}
}
在学习字节流的过程中,我们需要注意的是流用完后需要关闭,需要异常处理。
1.2 字符流
流按照处理的单位来分类,可以分为字节流和字符流,顾名思义就是分别以字节、字符为单位处理数据。
字符流的父类分别为Reader字符输入流、Writer字符输出流。
文件的字符流FileReader 和 FileWriter 分别是 Reader、Writer 的子类,我们再次以文件流为例学习
1.2.1 FileReader
public static void main(String[] args) throws IOException {
File f = new File("eng.txt");
FileReader fr = new FileReader(f);
//读取
char [] cs = new char[(int) f.length()];
fr.read(cs);
for(char r : cs) {
System.out.println(r);
}
fr.close();
1.2.2 FileWriter
File file = new File("eng.txt");
// 创建文件
file.createNewFile();
FileWriter fw = new FileWriter(file);
// 向文件写入内容
fw.write("a\n b\n c\n");
fw.flush();
fw.close();
1.3 缓冲流
从流的功能来进行分类,流又可以分为节点流(低级流)、处理流(高级流)。打个现实生活中的比方,我们用水管进行类比,生活中的自来水管可以看作是低级流,那么接在水管上的热水器就可以看作是处理流,是对水管里的水进行处理的,同时,热水器也必须接在水管上。换言之,处理流必须基于节点流来对数据进行处理。
这里先介绍缓冲流。
缓冲流可以在对数据进行读写的时候,会对数据进行缓存处理,达到提高效率的目的。
1.3.1 BufferedReader
//将当前源代码输出到控制台上
//建立流连接
FileInputStream fis = new FileInputStream("./src/io/BRDemo.java");
//转换流与高级流
InputStreamReader isr = new InputStreamReader(fis);
//高级流
BufferedReader br = new BufferedReader(isr);
//解决只读取一行的问题
String line;
while ((line = br.readLine())!=null){
System.out.println(line);
}
1.3.2 PrintWriter
//用PrintWriter向文件写数据,其中支持自动换行
PrintWriter pw = new PrintWriter("PWD.txt","utf-8");
pw.println("喜羊羊美羊羊");
pw.println("喜羊羊美羊羊*2");
System.out.println("写出完毕");
pw.close();
}
注意,上面的代码例子只是省略了连接低级流的过程,实际上PrintWriter可以进行手动流连接
//如果要追加模式,在第一层的文件流里写
FileOutputStream fos = new FileOutputStream("pw2.txt",true);
OutputStreamWriter osw = new OutputStreamWriter(fos);
BufferedWriter bw = new BufferedWriter(osw);
PrintWriter pw = new PrintWriter(bw);
pw.println("您好!");
System.out.println("写出完毕");
pw.close();
1.4 对象流
对象流也是一种处理流,将一个对象以流的形式进行传输,即将一个对象进行序列化与反序列化。
1.4.1 序列化
/**实现序列化接口*/
public class Person implements Serializable {
/**版本号,解决反序列化过程中对象版本不一致的问题*/
public static final long serialVersionUID = 1L;
/**定义属性*/
private String name;
private int age ;
private String gender;
private transient String [] otherInfo;
String name = "喜羊羊";
int age = 6;
String gender = "公";
String[] otherInfo = {"HelloWorld","123"};
//创建对象
Person p = new Person(name,age,gender,otherInfo);
//对象流
FileOutputStream fos = new FileOutputStream("person.obj");
ObjectOutputStream oos = new ObjectOutputStream(fos);
//将对象写进去
oos.writeObject(p);
System.out.println("写出完毕");
oos.close();
}
1.4.2 反序列化
FileInputStream fis = new FileInputStream("person.obj");
ObjectInputStream ois = new ObjectInputStream(fis);
Person person = (Person)ois.readObject();
System.out.println(person);
ois.close();
2.总结
本文我们学习了JAVA中常见的流的基本用法。流从方向上分为输入流、输出流;从处理的数据上,分为字节流、字符流;从功能上分,又分为节点流(低级流)、处理流(高级流)。每种流我们都选取了一些例子进行学习,学习过程中,需要注意异常处理、流的关闭以及高级流的嵌套关系。
希望对读者有所帮助。下一篇文章见!