1.字节流-----》读写以字节为单位
输入流: 读文件:InputStream
----------> FileInputSream---->把文件作为字节流进行写操作
----------> BufferedInputStream----->缓冲流,内部操作将读取内容缓冲至内存,待要读/写操作时直接在内存读取使用,从而使程序得到优化
----------->PipedInputStream(PipedOutputStream)-------->管道流
------------>DataInputStream--->数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型。
------------->System.in -------->从键盘读
输出流: 写文件 OutputSteam
----------> FileOutputSream
----------> BufferedOutputStream
----------->PipedOutputStream(PipedInputStream)
------------>PrintStream-->打印流
2.字符流-----》读写以字符为单位 只适合文本类文件
输入流: 读文件:Reader
------------>InputStreamReader:InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset
读取字节并将其解码为字符。它使用的字符集 可以由名称指定或显式给定,或者可以接受平台默认的字符集。 (字符转换流)
------------->FileReader:字符输入流
-------------->BufferedReader:字符流的过滤器,有时候可与PrintReader使用
输出流: 写文件 Writer
所有的IO操作都会产生IO异常
在打开文件后,要关闭文件,否则有可能会存在意想不到的问题(一般在finally中关闭)
3.序列化和反序列化
序列化就是将Object转换成byte序列,反之为反序列化
1.序列化流(ObjectOutputStream),是过滤流---writeObject
2.反序列化(ObjectInputStream)--------readObject
3序列化接口(Serializable)
对象必须实现序列化接口,才能够进行序列化,否则将出现异常,这个接口,没有任何方法,只是一个接口
4.transient:反序列化(防止被序列化)
5.序列化中,子类和父类的构造函数的调用问题
1)一个类实现了序列化接口,其子类都可以序列化
2)对子类对象进行反序列化操作时,若其父类没有实现序列化接口,那么其父类的构造函数会被调用
3)父类实现了serializable接口,子类继承就可序列化。子类在反序列化时,父类实现了序列化接口,则不会递归调用其构造函数。
结论:谁实现了可序列化(包括继承实现的),谁的构造函数就不会调用。
1 import java.io.FileInputStream; 2 import java.io.FileNotFoundException; 3 import java.io.IOException; 4 5 public class inputStreamDemo { 6 public static void main(String[] args){ 7 8 hh(); 9 // dh1();
10 11 } 12 13 public static void hh() { 14 FileInputStream dh=null; 15 try{ 16 dh =new FileInputStream("F:\\李刚1\\java\\jiava程序\\qq\\src\\jpanel.java"); 17 int aa; 18 aa=dh.read(); 19 while(aa!=-1){ 20 System.out.print((char)aa); 21 aa=dh.read(); 22 } 23 } catch (IOException e) { 24 25 e.printStackTrace(); 26 }finally{ 27 try { 28 dh.close(); 29 } catch (IOException e) { 30 e.printStackTrace(); 31 } 32 } 33 }
以上的方式存在两个问题:
1.以字符为单位的内容无法正常显示
2.读取的效率比较低
用以下方法可以解决
利用字节数组缓冲数据:
1 public static void dh1(){ 2 FileInputStream aa=null; 3 try { 4 aa=new FileInputStream("F:\\李刚1\\java\\jiava程序\\qq\\src\\jpanel.java"); 5 byte[] as=new byte[1024*10]; 6 int s=aa.read(as, 0, as.length); 7 String j=new String(as,0,s); 8 System.out.println(j); 9 } catch (Exception e) { 10 // TODO: handle exception 11 }finally{ 12 try { 13 aa.close(); 14 } catch (IOException e) { 15 // TODO Auto-generated catch block 16 e.printStackTrace(); 17 } 18 } 19 } 20 }
输出流:文件的写操作
1 import java.io.FileInputStream; 2 import java.io.FileNotFoundException; 3 import java.io.FileOutputStream; 4 import java.io.IOException; 5 6 public class inputStreamDemo { 7 public static void main(String[] args){ 8 9 hh(); 10 //dh1(); 11 12 } 13 14 public static void hh() { 15 FileInputStream in=null; 16 FileOutputStream out=null; 17 try{ 18 in =new FileInputStream("F:\\李刚1\\java\\jiava程序\\qq\\src\\jpanel.java"); 19 out=new FileOutputStream("F:\\李刚1\\java\\1.txt"); 20 21 int aa; 22 aa=in.read(); 23 while(aa!=-1){ 24 System.out.print((char)aa); 25 aa=in.read(); 26 out.write(aa); 27 } 28 } catch (IOException e) { 29 30 e.printStackTrace(); 31 }finally{ 32 try { 33 in.close(); 34 } catch (IOException e) { 35 e.printStackTrace(); 36 } 37 } 38 } 39 public static void dh1(){ 40 FileInputStream aa=null; 41 FileOutputStream bb=null; 42 try { 43 aa=new FileInputStream("F:\\李刚1\\java\\jiava程序\\qq\\src\\少说.txt"); 44 bb=new FileOutputStream("F:\\李刚1\\java\\1.txt"); 45 byte[] as=new byte[6]; 46 int s=aa.read(as, 0, as.length); 47 while(s!=-1){ 48 String j=new String(as,0,s,"UTF-8"); 49 bb.write(as, 0, s);//注意此处的s表示读取的(read)字节长度 50 System.out.print(j); 51 s=aa.read(as, 0, as.length);} 52 } catch (Exception e) { 53 // TODO: handle exception 54 }finally{ 55 try { 56 aa.close(); 57 } catch (IOException e) { 58 // TODO Auto-generated catch block 59 e.printStackTrace(); 60 } 61 } 62 } 63 }
BufferedInputStream & BufferedOutPutStream
1.flash()是为了刷新内存,写操作时使用。
2.Close()函数也能实现刷新操作。
1 import java.io.BufferedInputStream; 2 import java.io.BufferedOutputStream; 3 import java.io.FileInputStream; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 7 public class BufferedDemo { 8 public static void main(String[] args) { 9 BufferedInputStream in=null; 10 BufferedOutputStream out=null; 11 try { 12 in=new BufferedInputStream(new FileInputStream("D:\\电子公司质检部-李刚.JPG")); 13 out=new BufferedOutputStream(new FileOutputStream("E:\\b.jpg")); 14 byte[] bytes=new byte[1024]; 15 int sl; 16 sl= in.read(bytes, 0, bytes.length); 17 while(sl!=-1){ 18 19 20 out.write(bytes, 0,sl); 21 sl= in.read(bytes, 0,bytes.length); 22 } 23 out.flush(); 24 25 } catch (Exception e) { 26 // TODO Auto-generated catch block 27 e.printStackTrace(); 28 }finally{ 29 try { 30 in.close(); 31 } catch (IOException e) { 32 // TODO Auto-generated catch block 33 e.printStackTrace(); 34 } 35 try { 36 out.close(); 37 } catch (IOException e) { 38 // TODO Auto-generated catch block 39 e.printStackTrace(); 40 } 41 } 42 System.out.println("运行结束!"); 43 } 44 }
管道流
输入端和输出端始终保持数据一致
import java.io.IOException; import java.io.PipedInputStream; import java.io.PipedOutputStream; public class PioedDemo { public static void main(String[] args) { PipedInputStream in=null; PipedOutputStream out=null; try { out=new PipedOutputStream(); in=new PipedInputStream(out); byte value=(byte)(Math.random()*100); System.out.println(value); out.write(value); int as= in.read(); System.out.println((int)as); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
键盘输入流
示例:
1 import java.io.IOException; 2 public class systeminDemo { 3 public static void main(String[] args) { 4 try { 5 byte[] ad=new byte[1024]; 6 while (true) { 7 System.out.println("请输入:"); 8 int aa=System.in.read(ad,0,ad.length); 9 String ss=new String(ad,0,aa); 10 System.out.println(ss); 11 } 12 } catch (IOException e) { 13 e.printStackTrace(); 14 }} 15 }
字符转换流
将字节流转换成字符流
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import org.omg.CORBA.portable.InputStream; public class systeminDemo { public static void main(String[] args) { try { FileInputStream b= new FileInputStream("F:\\桌面壁纸\\aa.txt"); InputStreamReader in=new InputStreamReader(b, "GBK"); FileOutputStream b1= new FileOutputStream("F:\\桌面壁纸\\aa1.txt"); OutputStreamWriter out=new OutputStreamWriter(b1, "GBK"); char[] cbuf=new char[2048]; int c; while((c=in.read(cbuf, 0, cbuf.length))!=-1){ out.write(cbuf, 0, c); } out.flush(); in.close(); out.close(); } catch (IOException e) { e.printStackTrace(); }} }
字符流
字符流不能实现字符编码的转换,如需转换则需利用转换流实现
import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import org.omg.CORBA.portable.InputStream; public class systeminDemo { public static void main(String[] args) { try { FileReader in=new FileReader("F:\\桌面壁纸\\aa.txt"); FileWriter out=new FileWriter("F:\\桌面壁纸\\aa1.txt", true);//可文本内容追加 char[] ss=new char[2048]; int r; while((r=in.read(ss, 0, ss.length))!=-1){ out.write(ss, 0, r); } out.flush(); in.close(); out.close(); } catch (IOException e) { e.printStackTrace(); }} }
字符过滤器
使用println方法时,BufferedReader比PrintReader 、BufferedWriter比PrintWriter更简单
Pint写操作时不用单独换行
import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; public class systeminDemo { public static void main(String[] args) { try { BufferedReader in=new BufferedReader(new InputStreamReader( new FileInputStream("F:\\桌面壁纸\\aa.txt"))); PrintWriter out=new PrintWriter("F:\\桌面壁纸\\aa1.txt"); /* BufferedWriter out=new BufferedWriter(new OutputStreamWriter( new FileOutputStream("F:\\桌面壁纸\\aa1.txt")));*/ String line; while((line=in.readLine())!=null){ System.out.println(line);//必须手动换行,不然aa1中的字符时没有进行换行 /* out.write(line); out.newLine();//单独写出换行*/ out.println(line); } out.flush(); in.close(); out.close(); } catch (IOException e) { e.printStackTrace(); }} }
序列化,反序列化
1 import java.io.Serializable; 2 import java.io.FileInputStream; 3 import java.io.FileOutputStream; 4 import java.io.ObjectInputStream; 5 import java.io.ObjectOutputStream; 6 import java.io.Serializable; 7 public class systeminDemo { 8 public static void main(String[] args) { 9 try { 10 /* 11 * 序列化 12 * FileOutputStream out=new FileOutputStream("Demo\\aa.txt"); 13 ObjectOutputStream oos=new ObjectOutputStream(out); 14 Student1 s=new Student1("小明","001",20);*/ 15 //反序列化 16 FileInputStream in=new FileInputStream("Demo\\aa.txt"); 17 ObjectInputStream iin=new ObjectInputStream(in); 18 Student1 s1=(Student1) iin.readObject(); 19 System.out.println(s1); 20 /* oos.writeObject(s); 21 // oos.flush(); 22 // oos.close();*/ 23 iin.close(); 24 } catch (Exception e) { 25 e.printStackTrace(); 26 }} 27 } 28 29 30 class Student1 implements Serializable{ 31 private String name; 32 private int age; 33 private String xuehao; 34 public String getName() { 35 return name; 36 } 37 public void setName(String name) { 38 this.name = name; 39 } 40 public int getAge() { 41 return age; 42 } 43 public void setAge(int age) { 44 this.age = age; 45 } 46 public String getXuehao() { 47 return xuehao; 48 } 49 public void setXuehao(String xuehao) { 50 this.xuehao = xuehao; 51 } 52 public Student1() { 53 } 54 public Student1(String name, String xuehao,int age) { 55 super(); 56 this.name = name; 57 this.age = age; 58 this.xuehao = xuehao; 59 } 60 @Override 61 public String toString() { 62 return "Student1 [name=" + name + ", age=" + age + ", xuehao=" + xuehao 63 + "]"; 64 } 65 }
transient:防止属性被序列化
可重写writeObject和readObject可跳过transient
import java.io.Serializable; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.ConcurrentModificationException; public class systeminDemo { public static void main(String[] args) { try { /* * 序列化*/ /* FileOutputStream out=new FileOutputStream("Demo\\aa.txt"); ObjectOutputStream oos=new ObjectOutputStream(out); Student1 s=new Student1("小明","001",20);*/ //反序列化 FileInputStream in=new FileInputStream("Demo\\aa.txt"); ObjectInputStream iin=new ObjectInputStream(in); Student1 s1=(Student1) iin.readObject(); System.out.println(s1); /* oos.writeObject(s); oos.flush(); oos.close();*/ iin.close(); } catch (Exception e) { e.printStackTrace(); }} } class Student1 implements Serializable{ private String name; private transient int age;//transient:防止属性序列化(JVM不会对该属性进行序列化,要序列化就需自己手动完成,本例有完成) private String xuehao; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getXuehao() { return xuehao; } public void setXuehao(String xuehao) { this.xuehao = xuehao; } public Student1() { } public Student1(String name, String xuehao,int age) { super(); this.name = name; this.age = age; this.xuehao = xuehao; } @Override public String toString() { return "Student1 [name=" + name + ", age=" + age + ", xuehao=" + xuehao + "]"; } //参照ArrayList,手动序列化 private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{ s.defaultWriteObject();//默认可序列化属性 s.writeInt(this.age);//手动序列化 } private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { s.defaultReadObject(); this.age=(int)s.readInt(); } }
输出结果:防止序列化后:Student1 [name=小明, age=0, xuehao=001]
跳过transient后:Student1 [name=小明, age=20, xuehao=001]