黑马程序员——Java基础---IO(二)---对象流、管道流、RandomAccessFile、数据流、数组流、字符编码

来源:互联网 发布:java jar软件下载 编辑:程序博客网 时间:2024/05/16 15:16

-----------android培训java培训、java学习型技术博客、期待与您交流!------------

第一讲. 对象流 ObjectInputStream, ObjectOutputStream 

  1. 对象流可以把堆内存中的对象存储起来。首先要求对象本身implements Serializable接口,标示其可以序列化,否则会有NotSerializableException。
  2. Serializable 是一个标记接口,本身不要求其实现类为其实现任何方法。
  3. 静态成员无法序列化,即不会被存入硬盘中,因为它在方法区存储,而不在堆内存中
  4. 可以加入transient 关键字修饰类成员,令其不会被序列化

import java.io.*;class ObjectIODemo{public static void main(String[] args) throws Exception {ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("object.txt"));ObjectInputStream in = new ObjectInputStream(new FileInputStream("object.txt"));out.writeObject(new Person("Lisi",20));Person p = (Person)in.readObject();System.out.println(p);in.close();out.close();}}class Person //implements Serializable  /**<span style="white-space:pre"></span>序列号uid是通过类的成员计算得到的。也可以自己指定。**/{private static final long serialVersionUID = 42L; //自定义uidString name;int age;Person(String name,int age){this.name = name;this.age = age;}public String toString(){return "name="+name+";age="+age;}}

第二讲. 管道流PipedInputStream PipedOutputStream

  1. 管道流为多线程而设计的IO流,单线程会导致死锁,读写两个管道应异步进行。
  2. 可以对接,读写双发可以在创建时把对方当参数传入,也可以利用connect方法

import java.io.*;class PipedStreamDemo {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[] buff = new byte[1024];int len = in.read(buff);String s = new String(buff,0,len);System.out.println(s);in.close();}catch(IOException e){throw new RuntimeException("Error in input Pipe!");}}}class Write implements Runnable{private PipedOutputStream out;Write(PipedOutputStream out){this.out = out;}public void run(){try{out.write("hahahaha!".getBytes());out.close();}catch(IOException e){throw new RuntimeException ("Error in output Pipe~"); }}}

第三讲.RandomAccessFile  

  1. 工具类,直接继承自Object 
  2. 里面封装了一个数组,通过指针对元素进行操作
  3. 在内部封装了字节输入和输出流
  4. 只能操作文件,而且有模式限制(只读"r",读写"rw"等)。rw对文件进行追加,若没有则创建。r不会创建文件。当然为了防止你写错,会抛异常。
  5. 可以实现多线程下载(通过指针指定文本的不同位置),即异步同时写入

import java.io.*;class RandomAccessFileDemo {public static void main(String[] args) throws IOException{writeFile();readFile();}private static void writeFile() throws IOException{RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");raf.write("李四".getBytes());raf.writeInt(97);//raf.write(97);  // 只取最低8位raf.write("王五".getBytes());raf.writeInt(99);raf.seek(8*3);raf.write("周七".getBytes());raf.writeInt(102);raf.close();}private static void readFile() throws IOException{RandomAccessFile raf = new RandomAccessFile("ran.txt","r");raf.seek(8);  //raf.skipBytes(8);byte[] buff = new byte[4];raf.read(buff);String name = new String(buff);int age = raf.readInt();System.out.println(name+age);raf.close();}}

第四讲. DataInputStream, DataOutputStream 专门用来操作基本数据类型

  1. 数据流,可以用它处理各种基本类型数据
  2. writeUTF方法写入的数据只能用对应的readUTF读,它写入的格式跟一般utf格式是不一样的。

import java.io.*;class DataStreamDemo {public static void main(String[] args) throws IOException{writeData();readData();}private static void writeData() throws IOException{DataOutputStream out = new DataOutputStream (new FileOutputStream("data.txt"));//out.writeInt(345);out.writeUTF("你好");//只能用对应的readUTF读out.close();}private static void readData() throws IOException{DataInputStream in = new DataInputStream (new FileInputStream ("data.txt"));System.out.println(in.readUTF());in.close();}}

第五讲. ByteArrayInputStream,ByteArrayOutputStream 不涉及底层资源操作,直接读写数组 

  1. 用流的读写思想操作数组,同理也有CharArrayReader,CharArrayWriter;StringReader,StringWriter
  2. ByteArrayInputStream需指定一个字节数组作为数据源;ByteArrayOutputStream内部封装一个可变长度的字节数组,不用定义目的
  3. 没有IO异常,close方法无效(也没必要)
  4. ByteArrayOutputStream 有writeTo(OutputStream out) ,讲字节数组缓冲区中的数据写入到一个目的中(只有这个涉及底层操作)

import java.io.*;class  ByteArrayStreamDemo{public static void main(String[] args) {ByteArrayInputStream in = new ByteArrayInputStream ("ABCDEFG".getBytes());ByteArrayOutputStream out = new ByteArrayOutputStream();int by;while((by=in.read())!=-1)out.write(by);System.out.println(out.toString());}}

第六讲. 字符编码

Ascii 码表美国标准信息交换码 ,用一个字节的7位可以表示ISO8859-1拉丁码表、欧洲码表,用一个字节的8位表示,一些服务器会使用GB2313中国的中文编码表,两个字节表示。为了兼容英文码表,两个字节高位都是1(都是负数),6k~7k字GBK中文编码表升级版,容纳更多的字,约20k字Unicode国际标准编码表,融合多种文字,所有都两个字节表示UTF-8:8-bit unicode transformation format最少用一个字节,最多用三个字节表示一个字符,为使其便于识别,每个字节前都加入特定码头,如下图:

                                                   

  1. “你好”的utf-8编码形式,被GBK解码得到“浣犲ソ”;“你好”GBK编码被utf-8解码得到“??”
  2. 像“联通”,它的编码是符合uft-8的编码头的,用记事本打开会按照utf-8解码
  3. 为 String.getBytes(String charSet) 方法指定字符集时会抛出UnsupportedEncodingException异常,防止不支持的字符集输入

/**编码:字符串变字节数组 String str;str.getBytes(String charsetName);解码:字节数组变字符串 new String(byte[],charsetName);**/import java.util.*;class  EncodeDemo{public static void main(String[] args) throws Exception{String str1 = "你好";byte[] b1 = str1.getBytes("uft-8"); //默认是GBK//模拟服务器端应用欧洲码表的场景,此时需用重编解码的方式获得原中文文本String str2 = new String(b1,"iso8859-1"));byte[] b2 = str2.getBytes("ios8859-1"));String str3 = new String(b2,"utf-8");}}

练习题

/** 练习:1.有五个学生,每个学生有三门课的成绩2.有键盘输入,格式如Lisi,45,48,87 , 计算总分3.按总成绩大小顺序将学生信息输出到"stud.txt"文件中**/import java.io.*;import java.util.*;class Test {public static void main(String[] args) throws IOException{BufferedReader in = new BufferedReader(new InputStreamReader(System.in));Set<Student> students = new TreeSet<Student>();String name;int[] scores = new int[3];for (int i=1;i<=5 ;i++ ){System.out.println("请输入第"+i+"名学生的信息:");String line = in.readLine();String[] strs = line.split(",");name=strs[0].trim();for (int j=2;j<=strs.length ;j++ )scores[j-2]=Integer.parseInt(strs[j-1].trim());students.add(new Student(name,scores));}in.close();PrintStream out = new PrintStream("stud.txt");out.println(students);out.close();}}class Student implements Comparable<Student>{private String name;private int[] scores = new int[3];private int score;Student(String name,int[] scores){this.name = name;for (int i=0;i<scores.length ;i++ ){this.scores[i]=scores[i];score+=scores[i];}}public int compareTo(Student stu){return stu.score-this.score;}public boolean equals(Object stu){if (!(stu instanceof Student))return false;return this.name.equals(((Student)stu).name);}public String toString(){StringBuilder str = new StringBuilder();str.append(name+",");for (int i=0;i<3 ;i++ ){str.append(scores[i]);str.append(",");}str.append("总分:"+score+"\n");return str.toString();}}


0 0
原创粉丝点击