内存输出流
1、名字是输出流,体系也是在IO的体系中,但是其实没有内存和其他设备的交互,仅仅是在内存中做了拷贝。所以没有真正的IO。
2、类名:ByteArrayOutputStream
3、作用:当读取的字节信息不完整时,需要一个容器缓存不完整信息,这个类型就可以充当这个容器,因为这个容器可以自动增长。
4、本质上就是一个可以自动增长的字节数组
5、常用方法:
toByteArray():获取对象中的字节信息,返回一个字节数组
toString():将对象中的字节信息进行解码,返回解码后的字符串
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
public class Demo01 {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("a.txt");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] b = new byte[3];
int len=0;
while((len=fis.read(b))!=-1) {
baos.write(b, 0, len);
}
System.out.println(baos.toString());
byte[] result = baos.toByteArray();
System.out.println(Arrays.toString(result));
}
}
内存输出流
对象操作流
1、对象输出流 序列化
1.ObjectOutputStream:是一个字节输出流,是OutputStream的子类,用于将内存中的对象写到其它设备中。
2.是一个包装类,可以将一个没有输出对象功能的字节输出流,包装成有输出对象功能的字节流,包装完成后,就多了一些方法。
3.构造方法
ObjectOutputStream(OutputStream 普通的字节输出流对象);
4.成员方法
writeObject(Object obj):将对象输出到对象流中
5.注意:
要存储到文件中的对象所属类型必须实现Serializable接口,属于java.io包
使用此方法存入的文件无法阅读,只能以对象输入流打开读取
2、对象输入流 反序列化
1.ObjectInputStream:是一个字节输入流,也是一个包装类
2.作用:将文件中的对象读取到内存中进行使用
3.构造方法
ObjectInputStream(InputStream is):将一个普通的字节输入流,包装成对象流
4.特有方法
readObject():将流中的对象读取到内存中
对象所属类型必须实现Serializable接口
3、异常:
对象操作流可能会产生一个异常EOFException,End Of File Exception,文件末尾异常 当文件到达末尾时继续读文件会产生这个异常
4、使用方法:
可以将对象整体写进集合中,然后将集合整体写入文件,相当于只写入一个集合对象。读取时只用读取一个集合对象,遍历集合即可。
5、版本号问题
不要使用自动生成的序列化版本ID,手动写一个,将来可以从版本ID判断是否修改过。
如果修改了,那么文件中的对象类型和本地类型就不兼容,如果没有修改这个版本ID,那么无论怎样修改了类型内容,都可以做到文件对象类型和本地类型兼容。
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
public class Demo02 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
FileOutputStream fos = new FileOutputStream("b.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
ArrayList<Person> al = new ArrayList<>();
al.add(new Person("qq",11));//将对象写进集合
al.add(new Person("ww",21));
oos.writeObject(al);//只写入一个集合对象
oos.close();
FileInputStream fis = new FileInputStream("b.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
Object obj = ois.readObject();
ArrayList<Person> al1 = (ArrayList<Person>)obj;
for(Person p:al1) {
System.out.println(p.getName()+"..."+p.getAge());
}
ois.close();
}
}
class Person implements Serializable{
private static final long serialVersionUID = 1L;
private String name;
private int age;
public Person(String name, int age) {
super();
= name;
this.age = age;
}
public Person() {}
@Override
public String toString() {
return "name=" + name + ", age=" + age ;
}
public String getName() {
return name;
}
public void setName(String name) {
= name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
对象操作流
随机访问流
1、RandomAccessFile,不是一个流对象,但比流对象功能强大:可以读也可以写,还可以随机访问。实现方式是字节读取。
2、随机访问:可以设定光标位置
3、构造方法:
RandomAccessFile(String path, String mode)
path:文件的路径
mode:操作文件的模式, “r”是只读,”rw”是读写
4、常用成员方法:
read():读取一个字节
read(byte[] arr):读取若干字节,存储到arr中
write(int b):写出一个字节到文件中
write(byte[] arr):将一个字节数组的内容写出
write(byte[] arr, int offset, int len):将字节数组的一部分写出
readLine():一次读取一行
readXxx:可以将基本类型直接从文件中读取
writeXxx:可以将基本类型直接以字符串的形式写入文件中
seek(long pos):用于设定光标的位置,从指定位置开始读写
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
public class Demo03 {
public static void main(String[] args) throws IOException {
RandomAccessFile raf = new RandomAccessFile("a.txt", "rw");
raf.seek(3);//移动光标位置
System.out.println((char)raf.read());
byte[] b = new byte[3];
int len=0;
while((len=raf.read(b))!=-1) {
System.out.println(new String(b,0,len));
}
System.out.println(raf.readLine());
raf.close();
}
}
随机访问流
打印流
1、打印字节流和字符流(PrintStream和PrintWriter)
2、特点:
提供了很多print和println方法,可以很方便的将各种数据类型以字符串的形式进行输出(会将所有数据类型先转换成字符串然后输出)。
3、说明
字节流和字符流的本身的方法他们都有,但更多的是使用print和pringln方法,对于这两个方法,二者并无太大区别。
4、PrintStream打印字节流
构造方法:
PrintStream(File f)
PrintStream(String path)
PrintStream(OutputStream os):将一个普通的字节输出流,包装成打印流
需要强调的方法:
print(char[] arr)其它的数组都是数组地址,只有字符数组会打印内容
5、PrintWriter是字符流,是Writer的子类,所以有一个缓存区,所以需要刷新
格式PrintWriter(字符流对象,boolean flush);
(后面有代码说明)
标准输入输出流
1、标准输入流:System.in
类型:InputStream类
分类:字节输入流
设备:默认关联键盘
包装:使用转换流可以包装成字符流、使用BufferedReader可以包装成缓冲流
setIn(InputStream is)
2、标准输出流:System.out
类型:PrintStream类
分类:打印字节流
设备:默认关联到控制台
setOut(PrintStream ps)
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
public class Demo04 {
public static void main(String[] args) throws IOException {
System.setIn(new FileInputStream("a.txt"));
InputStream is = System.in;
System.setOut(new PrintStream("c.txt"));
System.out.println((char)is.read());
}
}
标准输入输出流