概念
流的本质是数据传输,根据数据传输的特性将流抽象为各种类,方便直接操作。可以类比水流(流就是一个管道里面有流水,这个管道连接了文件和程序)。
分类
根据处理数据类型的不同可以分为:字节流和字符流
根据数据流向不同可分为:输入流和输出流
由上图可知
java字节流
InputStream是所有字节输入流的祖先,而OutputStream是所有字节输出流的祖先。
java字符流
Reader是所有读取字符串输入流的祖先,而writer是所有输出字符串的祖先。
上面的几个类都是抽象类
Java字节流
一、FileInputStream和FileOutputStream
第一个类的源端和第二个类的目的端。它们的构造方法允许通过文件的路径名来构造相应的流。
FileInputStream fis = new FileInputStream("读取文件的路径");
注:读取文件的路径必须是存在并且可读的。
FileOutputStream fos = new FileOutputStream("写入文件的路径");
注:如输出文件已存在,则必须是可覆盖的(如果不想覆盖则可以后面加一个boolean参数为true)。
FileInputStream使用:
使用read()从此输入流中读取一个数据字节。FileInputStream fis = new FileInputStream("aa.txt");
int b;
while((b = fis.read())!=-1){ //如果已到达文件末尾,则返回 -1。我们可以用-1来判断是否是最后一个字节
System.out.println(b);
}
fis.close(); //关流释放资源一定要关闭资源
FileOutputStream使用:
使用write()写入
FileOutputStream fos = new FileOutputStream("yy.txt");
fos.write("你好啊...".getBytes()); //转化为字节数组
fos.close(); //关流释放资源一定要关闭资源
拷贝
第一种:一个一个字节的拷贝效率太慢
FileInputStream fil = new FileInputStream("/Users/Ms.chang/Desktop/IMG_1328.jpg");
第二种:定义一个字节数组来拷贝(如果是几M还可也考虑使用,但是如果是一个几G的电影我们就不可能使用他了)
FileOutputStream fos = new FileOutputStream("/Users/Ms.chang/Desktop/JavaFiel/1.jpg");
int b;
while((b = fil.read())!=-1){
fos.write(b);
}
fos.close();
fil.close();
FileInputStream fis = new FileInputStream("/Users/Ms.chang/Desktop/a.mp3");
FileOutputStream fos = new FileOutputStream("/Users/Ms.chang/Desktop/JavaFiel/appe.mp3");
byte [] arr = new byte[fis.available()];//创建跟文件大小一样的字节数组
fis.read(arr);//文件上的字节读取到内存中
fos.write(arr);//将字节中字节数据写到文件上;
fis.close();
fos.close();
第三种:定义一个小数组
FileInputStream fis = new FileInputStream("/Users/Ms.chang/Desktop/JavaFiel");
FileOutputStream fos = new FileOutputStream("yy.txt");
byte [] arr = new byte[1024 * 8];
int b;
while((b=fis.read(arr))!=-1){ //如果忘记加arr返回的就不是读取的字节个数,而是字节的码表值
fos.write(arr,0,b);
}
fis.close();
fos.close();
二、BufferedInputStream和BufferedOutputStream
它们是过滤器流,其作用是提高输入输出的效率。自带字节数组。
拷贝
//创建输入流对象
FileInputStream fis = new FileInputStream("/Users/Ms.chang/Desktop/a.mp3");
//创建输出流对象
FileOutputStream fos = new FileOutputStream("/Users/Ms.chang/Desktop/JavaFiel/aa.mp3");
//创建缓冲流对象.BufferedInputStream初始化需要放入InputStream类或者他的子类;
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream 需要放入OutputStream类或者子类
BufferedOutputStream bos = new BufferedOutputStream(fos);
int b;
while((b=bis.read())!=-1){
bos.write(b);
}
bis.close();
bos.close();
注:关闭流资源的时候只需要关闭缓冲流对象就可以了
java字符流
一、FileReader和FileWriter
以字符为单位读取文件,常用于读文本,数字等类型的文件
FileReader使用
FileReader fr = new FileReader("/Users/Ms.chang/Desktop/JavaFiel/b.txt");
int c;
while((c=fr.read())!=-1){ //通过项目默认的码表一次读取一个字符
System.out.print((char)c);
}
fr.close();
FileWriter使用
FileWriter fw = new FileWriter("/Users/Ms.chang/Desktop/JavaFiel/b.txt",true);
fw.write("大家好");
fw.close();
二、BufferedReader和BufferedWriter
BufferedReader br = new BufferedReader(new FileReader("/Users/Ms.chang/Desktop/JavaFiel/b.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("/Users/Ms.chang/Desktop/JavaFiel/tt.txt"));
String line;
while((line = br.readLine())!=null){//readLine()的方法可以获取到一行的文字
bw.write(line);
bw.newLine();//写出回车换行符
}
br.close();
bw.close();
三、LineNumberReader
使用这个类可以获取行号或者添加行号
LineNumberReader lnr = new LineNumberReader(new FileReader("/Users/Ms.chang/Desktop/JavaFiel/b.txt"));
String line;
lnr.setLineNumber(100);//设置行号
while((line = lnr.readLine())!=null){
System.out.println(lnr.getLineNumber() + line);//getLineNumber()获取行号
}
java的序列化和反序列化
一、什么是序列化和反序列化
把对象转换为字节序列的过程称为对象的序列化。
把字节序列恢复为对象的过程称为对象的反序列化。
二、序列化和反序列化的用途
把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
三、怎么实现
public class Person implements Serializable{ 这个类需要实例化必须要实现implements Serializable接口
private String name;
private int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Person() {
super();
}
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
public class Ob {public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
//实例化Person对象
Person p1 = new Person("111",11);
Person p2 = new Person("fsd", 12);
Person p3 = new Person("1s",114);
Person p4 = new Person("fasdfvad", 122);
//创建Person列表
Listlist<Person> = new ArrayList<>();
//给列表添加元素
list.add(p1);
list.add(p2);
list.add(p3);
list.add(p4);
//使用ObjectOutputStream类来进行序列化 初始化参数需要放入OutputStream类或者子类
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/Users/Ms.chang/Desktop/JavaFiel/aaa.txt"));
//把列表序列化
oos.writeObject(list);
oos.close();//关闭流资源
//使用ObjectInputStream类来反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("/Users/Ms.chang/Desktop/JavaFiel/aaa.txt"));
ArrayListlist1 =(ArrayList) ois.readObject();//readObject()来反序列化
//从数字中遍历出Person对象打印
for (Person person : list1) {
System.out.println(person);
}
ois.close();//关闭流资源
}