第二十一天
对象序列化:
对象要被序列化必须实现Serializable标记接口 可自定义序列号防止对象改变文件失败
public static final long serialVersionUID = 3672L;
如果不想对象中成员序列化加transient修饰 例如 transient int age;则age不再被序列化 静态也不能序列化
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt"));
oos.writeObject(new Person("lisi",28));用writerObject()方法写入对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt"));
Person p =(Person)ois.readObject();方法从文件中读取对象
管道流:
PipedOutputStream管道输出流 PipedInputStream管道输入流 可以用connect()或构造函数链接
双线程执行
RandomAccessFile:
该类不属于IO体系,直接继承Object类.是IO包中成员具备读写功能,内部封装一个数组通过指针对元素进行操作
getFilePointer获取指针位置 通过seek改变指针位置 内部封装字节输入输出流 rw来操作读写功能
如果模式为只读r,不会创建文件,会去读取一个已存在文件,文件不存在则报异常
如果为rw,操作的文件不存在会自动创建,存在不覆盖.
RandomAccessFile raf = new RandomAccessFile("t.txt","rw");具备读写功能
skipBytes();跳过指定字节数,只能一直往后跳 waiteInt();readInt();读写int型数据
可以直接在指定位置进行写入和修改
DataInputStream DataOutputStream可以用于操作基本数据类型的数据流对象要接收相应的字节流
writeUTF();写只能readUTF();读
ByteArrayInputStream构造时需要接收一个字节数组的源 ByteArrayOutputStream构造时不需要定义数据目的,内部自定义了可变长度字节数组
两个操作字节数组的流对象没有使用系统资源 无需关闭且不存在异常 writeTo(new OutputStream("a.txt"));直接写入目的文件
import java.io.*;
class ByteArrayStream
{
public static void main(String[]args)
{
DataInputStream bis = new DataInputStream("abcde".getBytes());将abcde封装入数组
DataOutputStream bos = DataOutputStream();无需目的
int by = 0;
while ((by=bis.read())!=-1)
{
bos.write(by);
}
bos.size();长度 bos.toString();变成字符串
}
}
操作字符数组:CharArrayReader CharArrayWriter 操作字符串StringReader StringWriter与字节数组的操作类似
指定编码表操作:
InputStreamReader(new FileInputStream("gbk.txt"),"gbk");指定编码读取 OutputStreamWriter()
byte[] b = s.getBytes("gbk");用gbk码表将字符串s装入数组 String ss = new String(b,"Gbk");将数组b用gbk码表变回字符串
出现乱码的话要先用解码的码表编码再用正确对应的码表进行解码
"联通"两个汉字的码要注意 因为符合utf-8的规则所以记事本会按照utf-8的码表解码,再加入其他字就可
练习:
从键盘录入学生(姓名和三门课的成绩)输出格式:如zhangsan,38,46,67计算出总成绩并把学生的信息和总分按由高到低
存入磁盘stud.txt文件中 步骤1,描述学生对象 2,定义一个操作学生的工具类
思路:
1,获取键盘录入一行数据,并将该行中的信息取出封装成学生对象
2,要将学生有序存储,用到TreeSet集合 3,将集合的信息写入文件中
import java.io.*;
import java.util.*;
class Student implements Comparable<Student>拥有比较性
{
private String name;
private int yu,ying,shu;
private int sum;
Student(String name,int yu,int ying,int shu)
{
this.name = name;
this.yu = yu;
this.ying = ying;
this.shu = shu;
sum = yu+ying+shu;
}
public String getName()
{
return name;
}
public int getSum()
{
return sum;
}
public int hashCode()防止存入HashSet集合中
{
return name.hashCode()+sum*12;
}
public boolean equals(Object obj)复写比较方法当姓名成绩都一样时视为同一个人
{
if (!(obj instanceof Student))
throw new ClassCastException("类型不匹配");
Student s = (Student)obj;
return this.name.equals(s.name) && this.sum==sum;
}
public int compareTo(Student s)覆写Comparable的compareTo方法
{
int num = new Integer(this.sum).compareTo(new Integer(s.sum));
if(num==0)
return this.name.compareTo(s.name);
return num;
}
public String toString()将学生信息变成字符串存储
{
return "String["+name+","+yu+","+ying+","+shu+"]";
}
}
class StudentInfoTool
{
public static Set<Student> getStudent()throws IOException当使用默认比较器时
{
return getStudent(null);
}
public static Set<Student> getStudent(Comparator<Student> cmp)throws IOException使用指定比较器
{
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
TreeSet<Student> ts = null;
if(cmp==null)
ts = new TreeSet<Student>();
else
ts = new TreeSet<Student>(cmp);
String line = null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
String[]info = line.split(",");
Student stu = new Student(info[0],Integer.parseInt(info[1]),Integer.parseInt(info[2]),Integer.parseInt(info[3]));
ts.add(stu);
}
bufr.close();
return ts;
}
public static void writeFile(Set<Student> stu)throws IOException
{
BufferedWriter bufw = new BufferedWriter(new FileWriter("stuinfo.txt"));
Iterator<Student> it = stu.iterator();
while (it.hasNext())
{
Student s = it.next();
bufw.write(s.toString());
bufw.write(s.getSum()+"");
bufw.newLine();
bufw.flush();
}
bufw.close();
}
}
class StudentDemo
{
public static void main(String[]args)throws IOException
{
Comparator<Student> cmp = Collections.reverseOrder();将默认比较方法逆转
Set<Student> stus = StudentInfoTool.getStudent(cmp);
StudentInfoTool.writeFile(stus);
}
}