java14 处理流
二、处理流 2.引用类型,保留数据+类型 序列化:将对象保存到文件或者字节数组中保存起来,叫序列化。输出流:ObjectOutputStream。writeObject(). 反序列化:从文件或者字节数组中拿出这个对象叫反序列化,反序列化也是创建对象的一种方式。输入流:ObjectInputStream。readObject(). 注意: 1.先序列化后饭序列化 2.不是所有的对象都可以序列化,必须实现java.io.Serializable接口。 不是所有的属性都需要序列化。不序列化的属性使用transient。 ** * 空接口只是标识,告诉JVM这个对象可以序列化。 */ public class Employee implements java.io.Serializable { //不需要序列化 private transient String name; //需要序列化 private double salary; public Employee() { } public Employee(String name, double salary) { super(); this.name = name; this.salary = salary; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } } /** * 不是所有的對象都可以序列化 java.io.NotSerializableException * 不是所有的屬性都需要序列化 transient */ public class ObjectDemo01 { public static void main(String[] args) throws ClassNotFoundException { try { seri("e:/xp/test/ser.txt"); read("e:/xp/test/ser.txt"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //反序列化 public static void read(String destPath) throws IOException, ClassNotFoundException{ //创建源 File src =new File(destPath); //选择流,反序列化对象,所以选择ObjectInputStream这个输入流。输入输出流是以程序为中心,写到程序是输入流,从程序写出去是输出流。 ObjectInputStream dis =new ObjectInputStream( new BufferedInputStream( new FileInputStream(src) ) ); //操作 读取的顺序与写出一致 必须存在才能读取 //不一致,数据存在问题 Object obj =dis.readObject();//先用Object接收,然后强制转换。 if(obj instanceof Employee){ Employee emp=(Employee)obj; System.out.println(emp.getName()); System.out.println(emp.getSalary()); } obj =dis.readObject(); int[] arr=(int[])obj; System.out.println(Arrays.toString(arr)); dis.close(); } //序列化 public static void seri(String destPath) throws IOException{ String s; Integer a;//String自己实现了序列化接口,所以可以自动序列化,没有实现java.io.Serializable接口的,手动实现这个接口就可以序列化了。 Employee emp =new Employee("bjsxt",1000000); int[] arr ={1,2,3,45};//数组也是对象,所以也可以序列化。数组是实现了java.io.Serializable接口,不能序列化的就要手动实现java.io.Serializable接口。 //创建源对象 File dest =new File(destPath); // 由于是写入对象,所以选择流 ObjectOutputStream ObjectOutputStream dos =new ObjectOutputStream( new BufferedOutputStream( new FileOutputStream(dest) ) ); //操作 写出的顺序 为读取准备 dos.writeObject(emp);//向文本中写入对象 dos.writeObject(arr); //释放资源 dos.close(); } } 流关闭的方法: 1.编写工具类,实现关闭功能。 import java.io.Closeable; public class FileUtil { /** * 工具类关闭流 * 可变参数: ... 只能形参最后一个位置,处理方式与数组一致 * FileUtil.closeAll(os,is); */ public static void close(String info, int a , float b,Closeable ... io){//3个点表示可变参数,个数随便,但是类型是Closeable。 for(Closeable temp:io){ try { if (null != temp) { temp.close();//凡事实现了Closeable接口的都有close()方法。 } } catch (Exception e) { } } } /** * 使用泛型方法 */ public static <T extends Closeable> void closeAll(T ... io){ for(Closeable temp:io){ try { if (null != temp) { temp.close(); } } catch (Exception e) { } } } } jdk1.7之后的新特性关闭流: /** * 1.7新特性 try --with --resource * @param srcPath * @param destPath * @throws FileNotFoundException * @throws IOException */ public static void copyFile2(String srcPath,String destPath) throws FileNotFoundException,IOException { //1、建立联系 源(存在且为文件) +目的地(文件可以不存在) // File src =new File(srcPath); //File dest =new File(destPath); //if(! src.isFile()){ //不是文件或者为null /// System.out.println("只能拷贝文件"); // throw new IOException("只能拷贝文件"); //} //2、选择流 try(//声明的部分加载try里面 InputStream is =new FileInputStream(src); OutputStream os =new FileOutputStream(dest); ){ //3、文件拷贝 循环+读取+写出 byte[] flush =new byte[1024]; int len =0; //读取 while(-1!=(len=is.read(flush))){ //写出 os.write(flush, 0, len); } os.flush(); //强制刷出 }catch(e){ } } /** * PrintStream 打印流(字节流),肯定是一个处理流 */ public class PrintStreamDemo01 { public static void main(String[] args) throws FileNotFoundException { System.out.println("test"); PrintStream ps =System.out; ps.println(false); //输出到文件 File src = new File("e:/xp/test/print.txt"); ps = new PrintStream(new BufferedOutputStream(new FileOutputStream(src)));//java.io.PrintStream.PrintStream(OutputStream out) ps.println("io is so easy....啊啊啊啊啊啊啊啊");//这样就写入到文件了。 ps.close(); } } /** * 三个常量 * 1、System.in 输入流 键盘输入 * 2、System.out 输出流 控制台输出 * System.err,通常用于输出错误。 * * ==>重定向 * setIn() * setOut() * setErr() * FileDescriptor.in * FileDescriptor.out */ public class SystemDemo01 { public static void main(String[] args) throws FileNotFoundException { test1(); test2(); //重定向,System.out.println不再向控制台输出,而是向文件中输出。true表示自动刷新。 System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream("e:/xp/test/print.txt")),true));//e:/xp/test/print.txt不存在可以创建 System.out.println("a嗖嗖嗖"); //控制台 -->文件 System.out.println("test柔柔弱弱"); while(true){System.out.println("back..ss嗖嗖嗖.."+i);i++;}//一直往文件中写 //回控制台 System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)),true));//FileDescriptor.out就代表了控制台,控制台也是一个文件。 System.out.println("back..ss嗖嗖嗖..");// } public static void test2() throws FileNotFoundException{ InputStream is =System.in; //System.in代表键盘输入 //is = new BufferedInputStream(new FileInputStream("e:/xp/test/print.txt"));//从文件输出到控制台。 Scanner sc = new Scanner(is);//Scanner也是一个处理流。 System.out.println("请输入:");//这是一个阻塞 System.out.println(sc.nextLine());//输出键盘输入的内容 } public static void test1(){ System.out.println("test"); System.err.println("err");//输出为红色。System.out和System.err是一样的,只是颜色不同,System.err用于输出错误信息,System.out用于输出一般的信息。 } } /** * 自己封装一个输入 */ public class BuffereIn { public static void main(String[] args) throws IOException { InputStream is =System.in;//System.in是一个节点流,并且是一个字节流,也是输入流。 BufferedReader br = new BufferedReader(new InputStreamReader(is)); System.out.println("请输入。。。。"); String msg =br.readLine();//这行执行后程序会阻塞等待输入。 System.out.println(msg); } }