java基础-io(字符流)
1. 编码问题
java的文本(char)是16位无符号整数,是字符的unicode编码(双字节编码)
文本是byte byte byte..的数据序列
文本文件是文本(char)序列按照某种编码方案(utf-8,utf-16be,gbk)序列化为byte的存储
2.字符流 Reader/Writer --操作的是文本文本文件(gbk编码)
字符的处理,一个字符一个字符的处理
字符的底层依旧是字节序列
InputStreamReader 完成byte流解析为char流,按照编码解析
OutputStreamWriter 提供char流到byte流,按照编码处理
public static void main(String[] args) { InputStreamReader inputStreamReader = null; OutputStreamWriter outputStreamWriter = null; try { inputStreamReader = new InputStreamReader(new FileInputStream("demo/demo.dat"), "utf-8"); //默认项目的编码就是 // int c; // while ((c = inputStreamReader.read()) != -1){ // System.out.println((char)c); // } outputStreamWriter = new OutputStreamWriter(new FileOutputStream("demo/dos.dat"), "utf-8"); char[] buffer = new char[8 * 1024]; int c; while ((c = inputStreamReader.read(buffer, 0, buffer.length)) != -1) { String s = new String(buffer, 0, c); System.out.println(s); outputStreamWriter.write(buffer, 0, c); } outputStreamWriter.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (inputStreamReader != null) { inputStreamReader.close(); } if (outputStreamWriter != null) { outputStreamWriter.close(); } } catch (IOException e) { e.printStackTrace(); } } }
3. FileReader/FileWriter
public class FileReaderAndWriter { public static void main(String[] args) { FileReader fileReader = null; FileWriter fileWriter = null; try { fileReader = new FileReader("demo/raf.dat"); fileWriter = new FileWriter("demo/dos.dat", true); //true追加 char[] buffer = new char[8 * 1024]; int c; while ((c = fileReader.read(buffer, 0, buffer.length)) != -1) { fileWriter.write(buffer, 0, c); } fileWriter.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (fileReader != null) { fileReader.close(); } if (fileWriter != null) { fileWriter.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
4. 字符流过滤器
public static void main(String[] args) { //对文件进行操作 BufferedReader bufferedReader = null; BufferedWriter bufferedWriter = null; PrintWriter printWriter = null; try { bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream("demo/demo.dat"))); bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("demo/dos.dat", true))); printWriter = new PrintWriter("demo/dos.dat"); String line; while ((line = bufferedReader.readLine()) != null) { // System.out.println(line); // bufferedWriter.write(line); // bufferedWriter.newLine(); //识别换行 printWriter.println(line); } bufferedWriter.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (bufferedReader != null) { bufferedReader.close(); } if (bufferedWriter != null) { bufferedWriter.close(); } if (printWriter != null) { printWriter.close(); } } catch (IOException e) { e.printStackTrace(); } } }
5.序列化
5.1 对象的序列化与反序列化
就是将object对象转换成byte序列,反之就是反序列化
序列化流(ObjectOutputStream)是过滤流----->writeObject
反序列化流(ObjectInputStream)---->readObject
5.2 序列化接口(Serializable)
对象必须实现序列化接口,才能进行序列化,否则将出现异常
这个接口没有任何方法,只是一个规定
序列化
public class ObjectSeriDemo { public static void main(String[] args) { String file = "demo/obj.dat"; ObjectOutputStream objectOutputStream = null; //1.对象的序列化 try { objectOutputStream = new ObjectOutputStream(new FileOutputStream(file)); Student student = new Student(1,"张三"); objectOutputStream.writeObject(student); objectOutputStream.flush(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (objectOutputStream != null) { objectOutputStream.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
反序列化
public class ObjectSeriDemo { public static void main(String[] args) { String file = "demo/obj.dat"; ObjectInputStream objectInputStream = null; try { objectInputStream = new ObjectInputStream(new FileInputStream(file)); Student student = (Student) objectInputStream.readObject(); System.out.println(student.toString()); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { try { if (objectInputStream != null) { objectInputStream.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
5.3 transient
该关键字的作用是当序列化对象时,其中有不想要jvm序列化元素的时候,就需要在元素前加上该关键字。
也可以自己完成序列化工作
自定义序列化
在需要序列化的model类中增加这两个方法,首先反/序列化jvm能序列化的元素,再序列化自己需要自定义序列化的元素
private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{ s.defaultWriteObject(); //序列化jvm能默认序列化的元素 s.writeObject(name); } private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { s.defaultReadObject(); //把jvm默认反序列的元素进行反序列化操作 this.name = (String) s.readObject(); }