文章目录
一、对象操作流
可以用于读写任意类型的对象
1.1 对象输出流
- 构造方法:
ObjectOutputStream (OutputStream out)
- 常用成员方法:
void writeObject()
1.2 对象输入流
- 构造方法:
ObjectInputStream(InputStream in)
- 常用成员方法:
void readObject()
输出代码示例
//学生类
public class Student implements Serializable {
private static final long serialVersionUID = -3480760401332925523L; //根据成员生成的序列号,随着成员的不同而不同
String name;
int age;
//String gender; //添加不同成员,会使序列号改变。
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
--------------------------------------------------------------------
1)创建对象输出流对象
FileOutputStream fos = new FileOutputStream("d:\\对象输出流demo.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
2)创建对象
Student s1 = new Student("张三", 18);
Student s2 = new Student("李四", 19);
3)写出对象
oos.write(s1);
oos.write(s2);
4) 释放资源
oos.close();
读取代码示例
1)创建对象输入流对象
ObjecetInputStream ois = new ObjectInputStream(new FileInputStream("d:\\对象输出流demo.txt"));
2)读取对象
Object obj = ois.readObject();
System.out.println(obj);
Object obj1= ois.readObject();
System.out.println(obj1);
2-1)改进后
try{
while(true){
Object obj = ois.readObject();
System.out.println(obj);
}
}catch(EOFException){ //这里捕获的错误只能是这个,输入过程中意外达到文件或流的末尾。
System.out.println("读到了文件的末尾");
}
为了解决对象输入流读取对象出现的异常问题(EOFException
),使用集合进行编写。
输出代码示例
1)创建对象输出流对象
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("e:\\oos.demo.txt"));
2)创建集合对象
ArrayList<Student> list = new ArrayList<Student>();
3)添加对象
list.add(new Student("张三", 18));
list.add(new Student("李四", 19));
4)写出集合对象
oos.writeObject(list);
5)释放资源
oos.close();
读取代码示例
1)创建对象输入流对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("e:\\oos.demo.txt"));
2)读取对象
Object obj = ois.readObject(); //直接输出obj也行,最好遍历
ArrayList<Student> list = (ArrayList<Student) obj;
for(Student student : list){
System.out.println(student);
}
3)释放资源
ois.close();
1.3 注意
解决对实现序列化接口出现的黄色警告,即没有设置默认序列化ID。
Serializable
:序列号,是一个标识标识接口,只能起到标识作用,没有方法。当一个类的对象需要IO流进行读写的时候,这个类必须实现该接口。NotSerializableException
:当实例需要具有序列化接口时,抛出此异常。java.io.InvalidClassException
:对象的系列号与类的序列号不匹配,主要原因可能有:1)该类的序列号与从流中读取的类描述的序列号不匹配;2)该类包含位置数据类型;3)该类没有可访问的无参构造方法。(序列号的生成默认与类的成员变量和构造方法相关)- 解决办法 ->设置默认序列化ID
代码示例
//学生类
public class Student implements Serializable {
private static final long serialVersionUID = -3480760401332925523L; //根据成员生成的序列号,随着成员的不同而不同
String name;
int age;
//String gender; //添加不同成员,会使序列号改变。
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
二、Properties
实现了Map
接口,是双列集合。特殊在于:可以与IO流结合,可以把内存中的键值对输出到文件中,吧文件中的键值对输出到内存中。表现了一个持久的属性集,属性列表中每个键及其对应值都是一个字符串。
2.1 构造方法
Properties()
2.2 成员方法
String getProperty(String key)
:用指定的在此属性列表中搜索属性。String getrProperty(String key, String defaultValue)
:用指定的键在此属性列表中搜索属性;找不到相应的key
,返回一个默认的value
。Object setProperty(String key, String value)
:调用Hashtable
的方法put()
,相当于Map
中的put()
。
代码示例
1)创建属性列表对象
Properties prop = new Properties();
2)添加映射关系
prop.put("hdu001", "张三");
prop.put("hdu002", "李四");
prop.put("hdu003", "王五");
3-1)通过遍历属性列表 —— key -> value
Set<Object> keys = prop.keySet();
for(Object obj : keys){
Object value = prop.get(key);
System.out.println(key + "---" + value);
}
3-2)获取所有的entry对象,通过结婚证对象获取
Set<Map.Entry<Object, Object>> entrys = prop.entrySet();
for(Map.Entry<Object, Object> entry : entrys){
Object key = entry.getKey();
Object value = entry.getValue();
System.out.println(key + "---" + value);
}
4.3 Properties与IO流结合的功能
void list(PrintWriter out)
:可以接收打印流,将属性列表输出到指定的输出流。
代码示例
1)创建属性列表对象
Properties prop = new Properties();
2)添加映射关系
prop.setProperties("hdu001", "张三");
prop.setProperties("hdu002", "李四");
prop.setProperties("hdu003", "王五");
3)创建打印流对象
PrintWriter out = new PrintWriter("d.txt");
prop.list(out); //把list根据out指向的地址,输出到d.txt文件中
4)释放资源
out.close();
void load(Reader reader)
:按简单的面向行的格式从输入字符流中读取属性列表(键和元素对)。
代码示例
1)创建属性列表对象
Properties prop = new Properties();
2)创建一个输入流对象
FileReader fr = new FileReader("d.txt");
3)装载读取
prop.load(fr);
4)释放资源
fr.close();
System.out.println(prop);
void store(Writer writer, String comments)
:可以接收任意输出流,以适合使用load(Reader reader)
方法的格式,将次Properties
属性列表(键和元素对)写入输出字符。
代码示例
1)创建属性列表对象
Properties prop = new Properties();
2)添加映射关系
prop.setProperties("hdu001", "张三");
prop.setProperties("hdu002", "李四");
prop.setProperties("hdu003", "王五");
3)创建输出流对象
FileWriter fw = new FileWriter("e.txt");
prop.store(fw, "helloworld"); //后面是描述性文本,可有可无
4)释放资源
out.close();
三、编码问题
3.1 编码表
把计算机语言的二进制数据转换成我们能看懂的字符。如有ACSII
、GB2312
、Unicode
、UTF-8
。GBK
一个字符两个字节,UTF-8
一个字符三个字节。
3.2 主要方法
byte[] getBytes(String chasrserName)
:使用指定的编码转换成字节数组。String(byte[] bytes, int offset, int length, String charsetName)
:使用指定字符集解码
代码示例
String s = "高薪就业";
byte[] bys = s.getBytes("UTF-8"); //不填就是默认编码
FileOutputStream fos = new FileOutputStream("a.txt");
fos.write(bys);
fos.close();
FileInputStream fis = new FileInputStream("a.txt");
byte[] bys = new byte[1024];
int len = fis.read(bys);
System.out.println(bys, 0, len, "UTF-8");