day05
对象流:
ObjectOutputStream 对象输出流
ObjectInputStream 对象输入流
对象流是一组高级流,作用是通过这组流可以方便的读写java中的任何对象.
1. 对象输出流:ObjectOutputStream 用于写出对象,由于底层读写都是字节读写,所以无论什么样的数据都要转换为字节才能写出.对象输出流可以自行将给定的对象转换为一组字节然后写出.省去了我们将对象按照结构转化为字节的麻烦.
ObjectOutputStream提供了写对象的方法:
void writeObject(Object obj)
该方法会将给定的对象转换为一组字节然后通过其处理的流写出
这里涉及到两个操作:
1) 对象序列化:将一个对象按照结构转换为一组字节的过程
2) 对象持久化:将该对象写入文件(硬盘中)的过程.
2. 对象输入流:ObjectInputStream 用于进行对象反序列化
public class am03_ObjectOutputStream_writeObject {
public static void main(String[] args) throws IOException {
/*
* 将一个Person实例写入文件保存
*/
am02_Person p = new am02_Person();
p.setName("苍老师");
p.setAge(18);
p.setGender("女");
String[] otherInfo = {"是一名演员","爱好是写毛笔字","促进中日文化交流","广大男性同胞的启蒙老师"};
p.setOtherInfo(otherInfo);
System.out.println(p);
/*
* 文件输出流作用:将给定的字节写入到指定文件
*/
FileOutputStream fos
= new FileOutputStream("person.obj");
/*
* 对象输出流作用:将给定的java对象转换为一组
* 字节后写出
*/
ObjectOutputStream oos
= new ObjectOutputStream(fos);
/*
* ObjectOutputStream提供了写对象的
* 方法:
* void writeObject(Object obj)
* 该方法会将给定的对象转换为一组字节然后
* 通过其处理的流写出
*
*
* 这里的操作是先通过OOS将p对象转换为
* 了一组字节,然后再将该组字节通过FOS
* 写入到了文件person.obj中
* 这里涉及到两个操作:
* 1:对象序列化.将一个对象按照结构转换
* 为一组字节的过程
* 2:对象持久化.将该对象写入文件(硬盘中)
* 的过程.
*
*/
oos.writeObject(p);
System.out.println("写出完毕!");
oos.close();
}
}
public class am04_ObjectInputStream_readObject {
public static void main(String[] args) throws IOException, ClassNotFoundException {
FileInputStream fis
= new FileInputStream("person.obj");
ObjectInputStream ois
= new ObjectInputStream(fis);
/*
* ObjectInputStream提供方法:
* Object readObject()
* 该方法可以读取字节并还原为指定的对象
* 需要确保OIS读取的字节是通过对象输出流(OOS)
* 将一个对象写出的字节.否则会抛出异常.
*/
am02_Person p = (am02_Person)ois.readObject();
System.out.println(p);
ois.close();
}
}
转换流:
OutputStreamWriter,InputStreamReader
java根据读写数据的单位划分了:字节流,字符流
InputStream,OutputStream是所有字节输入流与
字节输出流的父类,常用实现类:FileInputStream,
BufferedInputStream等.
Reader,Writer是所有字符输入流与字符输出流的父类
字节流的读写单位是字节,而字符流的读写单位是字符.
所以字符流有局限性,只适合读写字符数据.
但实际字符流底层本质还是读写字节,只是字符与字节
的转换工作不用我们来做了.
public class pm01_OutputStreamWriter_write {
public static void main(String[] args) throws IOException {
FileOutputStream fos
= new FileOutputStream("osw.txt");
/*
* 构造方法若只传入流,那么通过当前转换流
* 写出的字符会按照系统默认的字符集转化为
* 对应的字节,不推荐.
* 可以使用重载的构造方法,在第二个参数中
* 明确使用的字符集.
*/
OutputStreamWriter osw
= new OutputStreamWriter(fos,"GBK");
String str = "夜空中最亮的星,能否听清.";
osw.write(str);
osw.write("那仰望的人,心底的孤独和叹息.");
System.out.println("写出完毕!");
osw.close();
}
}
public class pm02_InputStreamReader_read {
public static void main(String[] args) throws IOException {
FileInputStream fis
= new FileInputStream("osw.txt");
InputStreamReader isr
= new InputStreamReader(fis,"GBK");
// char[] data = new char[100];
// int len = isr.read(data);
// String str = new String(data,0,len);
// System.out.println(str);
StringBuilder builder = new StringBuilder();
String str = "";
int d = -1;
while((d = isr.read())!=-1){
builder.append((char)d);
}
str = builder.toString();
System.out.println(str);
isr.close();
}
}
缓冲字符流:
PrintWriter
缓冲字符流由于内部有缓冲区,读写字符的效率高.
并且字符流的特点是可以按行读写字符串.
BufferedWriter,BufferedReader
PrintWriter也是缓冲字符输出流,它内部总是连接
BufferedWriter,除此之外PW还提供了自动行刷新
功能.所以更常用.
PrintWriter提供了直接对文件进行写操作
的构造方法:
PrintWriter(File file)
PrintWriter(String fileName)
若希望按照指定的字符集向文件写出字符串,
可以使用对应重载的构造方法:
PrintWriter(File file,String csn)
PrintWriter(String fileName,String csn)
第二个参数可以指定字符集的名字(charSetName)
public class pm03_PrintWriter_println {
public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
/*
* PrintWriter提供了直接对文件进行写操作
* 的构造方法:
* PrintWriter(File file)
* PrintWriter(String fileName)
* 若希望按照指定的字符集向文件写出字符串,
* 可以使用对应重载的构造方法:
* PrintWriter(File file,String csn)
* PrintWriter(String fileName,String csn)
* 第二个参数可以指定字符集的名字(charSetName)
*/
PrintWriter pw
= new PrintWriter("pw.txt","GBK");
pw.println("董小姐,你从没忘记你的微笑.");
pw.println("就算你和我一样,渴望着衰老.");
System.out.println("写出完毕!");
pw.close();
}
}
PrintWriter提供了常规的构造方法,允许传入
一个字节流或者字符流完成流连接的创建形式
public class pm04_PrintWriter_println2 {
public static void main(String[] args) throws IOException {
FileOutputStream fos
= new FileOutputStream("pw2.txt");
/*
* 若希望指定字符集,需要自行连接转换流
* 因为转换流可以将字符按照指定的字符集
* 转换为字节
*/
OutputStreamWriter osw
= new OutputStreamWriter(fos,"GBK");
PrintWriter pw
= new PrintWriter(osw);
/*
* PW的构造方法允许直接传入字节流,但实际
* 内部还是会根据流连接最终变为PW的.只是
* 这样做不能指定字符集
*/
// PrintWriter pw
// = new PrintWriter(fos);
pw.println("我在二环路的里边,想着你.");
pw.println("你在远方的山上,春风十里.");
pw.close();
}
}
缓冲字符输入流:
BufferedReader
/**
* java.io.BufferedReader
* 缓冲字符输入流.特点:可以按行读取字符串
* 由于有缓冲,读取字符时的效率好.
*/
public class pm06_BufferedReader_readLine {
public static void main(String[] args) throws IOException {
/*
./JSD1708_SE\src\day05
*/
FileInputStream fis = new FileInputStream("./JSD1708_SE"+ File.separator+"src"+File.separator+"day05"+File.separator+"pm06_BufferedReader_readLine.java");
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine())!=null){
System.out.println(line);
}
br.close();
}
}
练习:
/**
* 简易记事本
* 使用PW将用户输入的每行字符串写入用户指定的文件中
* 构造方法使用流连接形式,不使用直接对文件操作的.
*/
public class pm05_Note {
public static void main(String[] args) throws FileNotFoundException {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个文件名:");
String fileName = scanner.nextLine();
FileOutputStream fos = new FileOutputStream(fileName);
OutputStreamWriter osw = new OutputStreamWriter(fos);
/*
当PrintWriter的构造方法第一个参数为流(字节流,字符流均可)时,
那么支持一个重载的构造方法可以传入一个boolean值,该值若为true
,则当前PrintWriter具有自动刷新功能即:每当调用Println方法写出
一行字符串后会
自动调用flush方法将其真实写出.
需要注意,调用print方法是不会flush的
*/
PrintWriter pw = new PrintWriter(osw,true);
System.out.println("请开始你的表演");
String line = null;
while (true) {
line = scanner.nextLine();
if (line.equals("exit")) {
break;
}
pw.println(line);
}
System.out.println("再见!");
pw.close();
}
}