1、ObjectInputStream,ObjectOutputStream
对象需要继承Serializable(标记接口,其中没有方法)
成员加上static后可以防止序列化;成员变量加上transient后防止序列化。
UID是序列号。
public class ObjectStreamDemo1 { public static void main(String[] args) throws Exception{ //writeObj(); readObj(); } public static void readObj() throws Exception{ ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d:\\test\\a.txt")); Person p = (Person)ois.readObject(); System.out.println(p); ois.close(); } public static void writeObj() throws IOException { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("d:\\test\\a.txt")); oos.writeObject(new Person("zhangsan",34,"kr")); oos.close(); } } class Person implements Serializable { //public static final long serialVersionUID = 42L; private String name ; transient int age ;//防止序列化 static String country = "cn";//防止序列化 Person(String name,int age,String country){ this.name = name ; this.age = age; this.country = country; } public String toString(){ return name+":"+age+":"+country; } }2、管道流PipedInputStream和PipedOutputStream
输入输出可以直接进行连接,通过结合线程使用
public class PipedStreamDemo1 { public static void main(String[] args) throws IOException{ PipedInputStream in = new PipedInputStream(); PipedOutputStream out = new PipedOutputStream(); in.connect(out); Read r = new Read(in); Write w = new Write(out); new Thread(r).start(); new Thread(w).start(); } } class Read implements Runnable { private PipedInputStream in; Read(PipedInputStream in) { this.in = in; } public void run() { try { byte[] buf = new byte[1024]; System.out.println("读取前。。。没有数据阻塞"); int len = in.read(buf); System.out.println("读到数据、、、、阻塞结束"); String s = new String(buf,0,len); System.out.println(s); in.close(); }catch(IOException e) { throw new RuntimeException("管道读取流失败"); } } } class Write implements Runnable { private PipedOutputStream out; Write(PipedOutputStream out) { this.out = out; } public void run() { try{ System.out.println("开始写入数据,等待6秒后。"); Thread.sleep(6000); out.write("piped lai la".getBytes()); out.close(); }catch(Exception e) { throw new RuntimeException("管道输出流失败"); } } }
3、RandomAccessFile随机访问文件
该类不是IO体系中的子类,而是直接继承自Object。但是它是IO包中成员,因为它具备读和写功能,内部封装了一个数组,而且通过指针对数组的元素进行操作,可以通过getFilePointer获取指针的位置,同时可以通过seek改变指针的位置。
其实完成读写的原理就是内部封装了字节输入流和输出流。
通过构造函数可以看出,该类只能操作文件,而且操作文件还有模式。只读r,读写rw等。
如果模式为只读r,不会创建文件,会去读取一个已存在文件,如果该文件不存在,则会出现异常,如果模式为rw,操作的文件不存在会自动创建,如果存在不会覆盖。
public class RandomAccessFileDemo1 { public static void main(String[] args)throws IOException { //writeFile(); //readFile(); writeFile2(); } public static void readFile() throws IOException { RandomAccessFile raf = new RandomAccessFile("d:\\test\\ran.txt","r"); //调整对象中指针 raf.seek(8*1); //跳过指定字节数,只能向后跳,不能向前跳 raf.skipBytes(8); byte[] buf = new byte[4]; raf.read(buf); String name = new String(buf); int age = raf.readInt(); System.out.println("name="+name); System.out.println("age="+age); raf.close(); } public static void writeFile2() throws IOException { RandomAccessFile raf = new RandomAccessFile("d:\\test\\ran.txt","rw"); raf.seek(8*3); raf.write("周期".getBytes()); raf.writeInt(103); raf.close(); } public static void writeFile() throws IOException { RandomAccessFile raf = new RandomAccessFile("d:\\test\\ran.txt","rw"); raf.write("李四".getBytes()); raf.writeInt(97); raf.write("王五".getBytes()); raf.writeInt(99); raf.close(); } }
4、DataInputStream与DataOutputStream可以用于操作基本数据类型的数据的流对象。
public class DataStreamDemo1 { public static void main(String[] args) throws IOException{ //writeData(); //readData(); //writeUTFDemo(); //OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d:\\test\\utf"),"utf-8"); //osw.write("你好"); //osw.close(); readUTFDemo(); } public static void readUTFDemo() throws IOException { DataInputStream dis = new DataInputStream (new FileInputStream("d:\\test\\utfdata.txt")); String s = dis.readUTF(); System.out.println(s); dis.close(); } public static void writeUTFDemo() throws IOException { DataOutputStream dos = new DataOutputStream(new FileOutputStream("d:\\test\\utfdata.txt")); dos.writeUTF("你好"); dos.close(); } public static void readData() throws IOException { DataInputStream dis = new DataInputStream(new FileInputStream("d:\\test\\data.txt")); int num = dis.readInt(); boolean b = dis.readBoolean(); double d = dis.readDouble(); System.out.println("num="+num); System.out.println("b="+b); System.out.println("d="+d); dis.close(); } public static void writeData() throws IOException { DataOutputStream dos = new DataOutputStream(new FileOutputStream("d:\\test\\data.txt")); dos.writeInt(234); dos.writeBoolean(true); dos.writeDouble(9887.543); dos.close(); } }
5、用于操作字节数组的流对象:
ByteArrayInputStream:在构造的时候,需要接收数据源,而且数据源是一个字节数组。
ByteArrayOutputStream:在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组,这就是数据目的地。
因为这两个流对象都操作的数组,并没有使用系统资源,所以,不用进行close关闭。
用流的读写思想来操作数据。
public class ByteArrayStreamDemo { public static void main(String[] args) { //数据源 ByteArrayInputStream bis = new ByteArrayInputStream("ABCDEFG".getBytes()); //数据目的。 ByteArrayOutputStream bos = new ByteArrayOutputStream(); int by = 0; while((by=bis.read())!=-1) { bos.write(by); } System.out.println(bos.size()); System.out.println(bos.toString()); } }
6、用于操作字符数组的流对象:
CharArrayReader与CharArrayWriter
7、用于操作字符串的流对象:
StringReader与StringWriter
8、常见的编码表:
ASCII:美国标准信息交换码。用一个字节的7位可以表示
ISO8859-1:拉丁码表,欧洲码表。用一个字节的8位表示。
GB2312:中国的中文编码表。
GBK:中国的中文编码表升级,融合了更多的中文文字符号。
Unicode:国际标准码,融合了多种文字。所有文字都用两个字节来表示,java语言使用的就是unicode
UTF-8:最多用3个字节来表示一个字符。
public class EncodeDemo1 { public static void main(String[] args) throws IOException{ //writeText(); readText(); } public static void readText() throws IOException { InputStreamReader isr = new InputStreamReader(new FileInputStream("d:\\test\\gbk.txt"),"utf-8"); char[] buf = new char[1024]; int len = isr.read(buf); String str = new String(buf,0,len); System.out.println(str); isr.close(); } public static void writeText() throws IOException { OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("d:\\test\\gbk.txt")/*,"utf-8"*/); osw.write("你好啊"); osw.close(); } }
9、编码与解码
编码:字符串变成字节数组
解码:字节数组变成字符串
String-->byte[ ]; str.getBytes(charsetName);
byte[ ] -->String; new String(byte[ ], charsetName);
在解码时如果出错,可以再进行编码解码,用相应的编码表。
public static void main(String[] args) throws Exception{ String s = "哈哈"; byte[] b1 = s.getBytes("GBK"); System.out.println(Arrays.toString(b1)); String s1 = new String(b1,"iso8859-1"); System.out.println(s1); //对s1进行编码 byte[] b2 = s1.getBytes("iso8859-1"); System.out.println(Arrays.toString(b2)); String s2 = new String (b2,"gbk"); System.out.println(s2); }
10、练习
/* 有五个学生,每个学生有3门课的成绩 从键盘输入以上数据(包括姓名,三门课成绩) 输入的格式:如:zhangsan,30,40,50 计算出总成绩 并把学生的信息和计算出的总分数高低顺序放在磁盘文件"stud.txt"中 1、描述学生对象 2、定义一个可操作学生对象的工具类 思想: 1、通过获取键盘录入一行数据,并将该行中的信息取出封装成学生对象。 2、因为学生有很多,那么就要存储,使用到集合,因为要对学生的总分排序,所以可以使用TreeSet 3、将集合的信息写入到一个文件中 */ public class StudentInfoTest { public static void main(String[] args) throws IOException{ Comparator<Student> cmp = Collections.reverseOrder(); Set<Student> stus = StudentInfoTool.getStudents(cmp); StudentInfoTool.write2File(stus); } } class Student implements Comparable<Student>{ private String name ; private int ma, cn ,en ; private int sum; Student(String name ,int ma, int cn ,int en ){ this.name = name; this.ma = ma; this.cn = cn; this.en = en; sum= ma+cn+en; } public int compareTo(Student s) { int num = new Integer(this.sum).compareTo(new Integer(s.sum)); if(num==0) return this.name.compareTo(s.name); return num; } public String getName() { return name; } public int getSum() { return sum; } public int hashCode() { return name.hashCode()+sum*78; } public boolean equals(Object obj) { if(!(obj instanceof Student)) throw new ClassCastException("类型不匹配"); Student s = (Student)obj; return this.name.equals(s.name)&&this.sum==s.sum; } public String toString() { return "student["+name+","+ma+","+cn+","+en+"]"; } } class StudentInfoTool { public static Set<Student> getStudents() throws IOException{ return getStudents(null); } public static Set<Student> getStudents(Comparator<Student> cmp) throws IOException{ BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); String line = null; Set<Student> stus = null; if(cmp==null) stus = new TreeSet<Student>(); else stus= new TreeSet<Student>(cmp) ; while((line = bufr.readLine())!=null) { if("over".equals(line)) break; String[] info = line.split(","); Student stu = new Student(info[0],Integer.parseInt(info[1]), Integer.parseInt(info[2]), Integer.parseInt(info[3])); stus.add(stu); } bufr.close(); return stus; } public static void write2File(Set<Student> stus) throws IOException{ BufferedWriter bufw = new BufferedWriter(new FileWriter("d:\\test\\stuinfo.txt")); for(Student stu : stus) { bufw.write(stu.toString()+"\t"); bufw.write(stu.getSum()+""); bufw.newLine(); bufw.flush(); } bufw.close(); } }
---------------------- ASP.Net+Android+IOS开发、 href="http://edu.csdn.net"target="blank">.Net培训、期待与您交流! ----------------------详细请查看: http://edu.csdn.net