新博客地址:Temijava
第一讲:IO流(对象的序列化)git
一,对象序列化的概念:将堆内存中的对象存入硬盘,保留对象中的数据,称之为对象的持久化(或序列化)。github
========被序列化对象必须实现 Serializable 接口,接口Serializable中没有方法,称之为标记接口===========web
==============静态成员,和被transient 修饰的成员没法被序列化。静态成员属于类级别的,因此不能序列化这里的不能序列化的意思,是序列化信息中不包含这个静态成员域你这个测试成功,是由于你都在同一个机器(并且是同一个进程),由于你这个jvm已经把count加载进来了,因此你获取的是加载好的count,若是你是传到另外一台机器或者你关掉程序重写写个程序读入test.obj,此时由于别的机器或新的进程是从新加载count的,因此count信息就是初始时的信息。====================数组
二,ObjectInputStream和ObjectOutputStream类的了解:dom
三,序列化操做步骤:jvm
四,代码练习:ide
1 import java.io.*; 2 3 public class ObjectStreamDemo { 4 public static void main(String[] args) { 5 //声明并实例化被序列化对象 6 Person per = new Person("lisi",23,01,"ss"); 7 8 //序列化对象 9 try { 10 myObjectStream_Write(per); 11 } catch (FileNotFoundException e) { 12 System.out.println("文件没有找到"+e.toString()); 13 } catch (IOException e) { 14 System.out.println("序列化发生错误!"+e.toString()); 15 } 16 17 //接收读取的对象 18 Person per2=null; 19 20 //反序列化对象 21 try { 22 per2 = (Person)myObjectStream_Reader(); 23 } catch (FileNotFoundException e) { 24 System.out.println("序列还文件不存在"+e.toString()); 25 } catch (ClassNotFoundException e) { 26 System.out.println("类文件没有找到"+e.toString()); 27 } catch (IOException e) { 28 System.out.println("读取发生错误"+e.toString()); 29 } 30 31 System.out.println(per2); 32 } 33 34 35 //自定义序列化 方法,将对象序列化到硬盘上 36 public static void myObjectStream_Write(Object obj) throws FileNotFoundException, IOException{ 37 38 //声明序列化输出流对像。并于文件相关联 39 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:/obj.txt")); 40 41 //将对象序列化到硬盘上 42 oos.writeObject(obj); 43 44 //关闭流 45 oos.close(); 46 } 47 48 49 //自定义读取序列化对象方法 50 public static Object myObjectStream_Reader() throws FileNotFoundException, IOException, ClassNotFoundException{ 51 52 //声明序列化输入流,并于文件关联 53 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:/obj.txt")); 54 55 56 //读入被序列化的对象 57 Object object = ois.readObject(); 58 59 //关闭流 60 ois.close(); 61 62 return object; 63 64 } 65 }
Person 类:函数
1 import java.io.Serializable; 2 3 4 //定义Person类实现Serializable接口,代表能够被序列化 5 public class Person implements Serializable{ 6 7 //定义serialVersionUID 代表版本号 8 private static final long serialVersionUID = 1L; 9 10 //定义类成员 11 private String name; 12 private int age; 13 14 //transient修饰符修饰的成员不能够被序列化 15 transient int id; 16 17 //静态成员不能够被序列化 18 static String country="aa"; 19 20 21 //定义构造方法 22 public Person(String name,int age,int id,String country){ 23 this.name=name; 24 this.age=age; 25 this.id=id; 26 this.country=country; 27 } 28 29 @Override 30 public String toString(){ 31 return "name:"+name+"---"+"age:"+age+"----"+"id:"+id+"----"+"country"+country; 32 } 33 34 }
第二讲:IO流(管道流)工具
一,管道流:PipedInputStream 和 PipedOutputStream (输入输出能够直接进行链接,不用再借助数组或集合等容器进行临时存储。经过结合线程使用)
PipedInputStream
。在使用前必须将其链接到 PipedOutputStream
。PipedInputStream
,并对管道缓冲区使用指定的管道大小。在使用前必须将其链接到 PipedOutputStream
。PipedInputStream
,使其链接到管道输出流 src
,并对管道缓冲区使用指定的管道大小。写入 src
的数据字节可用做此流的输入。src
。若是此对象已经链接到其余某个管道输出流,则抛出 IOException
。snk
的输入。IOException
。二,操做步骤:
三,代码练习:
1 import java.io.*; 2 3 //定义一个类,实现启动一个线程,次线程包括一个读的管道刘 4 class Read implements Runnable{ 5 private PipedInputStream in; 6 public Read(PipedInputStream in){ 7 this.in = in; 8 } 9 10 @Override 11 12 //覆写方法 13 public void run(){ 14 15 //接受输入数据 16 byte buff[] = new byte[1024]; 17 18 19 //记录数据长度 20 int len=0; 21 22 23 //循环接受数据 24 while(true){ 25 try{ 26 27 //尝试读取数据 28 len = in.read(buff); 29 30 //判断是否结束 31 if("over".equals(new String(buff,0,len-2))) 32 break; 33 34 //输出用户输入的内容 35 System.out.println("管道读取内容为:"+new String(buff,0,len)+len); 36 }catch(IOException e){ 37 System.out.println("读取异常"+e.toString()); 38 } 39 } 40 41 //给出运行完毕提示 42 System.out.println("运行完毕"); 43 } 44 } 45 46 //定义一个类,实现启动一个线程,此线程包括一个写的管道流 47 class Write implements Runnable{ 48 49 //声明管道流对象 50 private PipedOutputStream out; 51 52 //构造方法 53 public Write(PipedOutputStream out){ 54 this.out = out; 55 } 56 57 @Override 58 59 //覆写方法 60 public void run(){ 61 62 //接受管道数据 63 byte buff[] = new byte[1024]; 64 65 int len=0; 66 67 68 //循环读取 69 while(true){ 70 try{ 71 len=System.in.read(buff); 72 73 74 //输出数据 75 out.write(buff, 0, len); 76 77 //判断是否结束 78 if("over".equals(new String (buff,0,len-2))) 79 break; 80 }catch(IOException e){ 81 System.out.println("管道读取流发生异常"+e.toString()); 82 } 83 } 84 85 //给出结束提示 86 System.out.println("运行完毕"); 87 88 } 89 } 90 public class PipedStreamDemo { 91 public static void main(String[] args) { 92 93 //建立 管道流对象做为参数 94 PipedInputStream pis = new PipedInputStream(); 95 PipedOutputStream pos = null; 96 97 //将管道流相链接 98 try { 99 pos = new PipedOutputStream(pis); 100 } catch (IOException e) { 101 // TODO Auto-generated catch block 102 e.printStackTrace(); 103 } 104 105 //建立线程 106 Thread t1 = new Thread(new Read(pis)); 107 Thread t2 = new Thread(new Write(pos)); 108 109 110 //启动线程 111 t1.start(); 112 t2.start(); 113 } 114 }
第三讲:IO流(RandomAccessFile)
一,RandomAccessFile 类的简单了解。
File
参数指定。n
个字节以丢弃跳过的字节。返回:跳过的实际字节数。===注:只能够往前跳不能够日后跳==========注:关于读写模式的说明:若是模式为只读r,则不会建立文件,会去读一个已存在的文件,若文件不存在,则会出现异常。若是模式为读写rw,且该对象的构造函数要操做的文件不存在,会自动建立;若是存在,则不会覆盖。====
二,RandomAccessFile类的特色:
三,代码练习:
1 package com.examp.ch18; 2 //需求:使用RandomAccessFileDemo进行读写操做 3 4 import java.io.*; 5 public class RandomAccessFileDemo { 6 7 public static void main(String[] args)throws IOException { 8 9 //建立文件对象 10 File file =new File("E:/test.txt"); 11 12 //写数据 13 writeFile(file); 14 15 //读数据 16 readFile(file); 17 18 } 19 20 //读取指定文件中的数据 21 public static void readFile(File file)throws IOException{ 22 23 24 //建立随机读写对象,指定文件打开方式为只读 25 RandomAccessFile raf=new RandomAccessFile(file,"r"); 26 27 //设置指针位置 28 raf.seek(8); 29 30 //读取四个字节存入 31 byte[] by=new byte[4]; 32 33 34 //读数据 35 raf.read(by); 36 37 38 //将存入数据的字节数组转换为字符串 39 String name=new String(by); 40 41 42 //读取年龄 43 int age=raf.readInt(); 44 45 System.out.println("name="+name+"age="+age); 46 47 //关闭流对象 48 raf.close(); 49 } 50 51 //建立方法将数据写入指定文件中 52 public static void writeFile(File file)throws IOException{ 53 54 //建立对象,文件打开方式为读写 55 RandomAccessFile raf=new RandomAccessFile(file,"rw"); 56 57 //写入姓名 58 raf.write("张三".getBytes()); 59 60 61 //写入年龄,这里调用了写一个int方法 62 raf.writeInt(23); 63 64 raf.write("李四".getBytes()); 65 raf.writeInt(100); 66 67 //改变指针位置,改变第一个对象的值 68 raf.seek(8*0); 69 raf.write("小三".getBytes()); 70 raf.writeInt(3); 71 72 73 //改变指针位置 74 raf.skipBytes(8*2); 75 raf.write("王五".getBytes()); 76 raf.writeInt(5); 77 78 //关闭流 79 raf.close(); 80 } 81 }
第四讲:IO流(操做基本数据类型的流对象DataStream)
一,ByteArrayInputStream和ByteArrayOutputStream 类的简单了解:
二,对应的字符操做类:CharArrayReader和CharArrayWriter
对应的字符串操做类: StringReader和StringWriter
三,代码练习:
1 import java.io.*; 2 3 public class ByteArrayInputStreamDemo { 4 public static void main(String[] args) { 5 6 //定义字节操做输入流,源为一个字符串的字节数组形式 7 ByteArrayInputStream bais=new ByteArrayInputStream("abcdef".getBytes()); 8 9 //定义字节操做输出流 10 ByteArrayOutputStream baos=new ByteArrayOutputStream(); 11 12 //接受读入的内容 13 int by=0; 14 15 //循环读取写入内容 16 while((by = bais.read())!=-1){ 17 baos.write(by); 18 } 19 20 //输出字节操做流写入的内容 21 System.out.println(baos.toString()); 22 } 23 }
第五讲:IO流(ByteArrayStream)
第六讲:IO流(转换流的字符编码)
一,字符概述:
二,编码表的由来:计算机只能识别二进制数据,早期由来是电信号。为了方便应用计算机,让它能够识别各个国家的文字。就将各个国家的文字用数字来表示,并一一对应,造成一张表。这就是编码表。
UTF-8:最多用三个字节表示一个字符的编码表,根据字符所占内存空间不一样,分别用一个、两个、三个字节来编码。
三,代码练习:
1 import java.io.*; 2 3 4 public class EncodingStream { 5 public static void main(String[] args) { 6 7 //分别建立两个文件对象,用来存储两种编码格式的数据 8 File file_GBK = new File("E:/gbk.txt"); 9 File file_UTF = new File("E:/utf.txt"); 10 11 //分别按照两种编码格式写入数据 12 try { 13 writeText_GBK(file_GBK); 14 writeText_UTF(file_UTF); 15 } catch (IOException e) { 16 System.out.println("写入文件发生异常"+e.toString()); 17 } 18 19 20 //按照两种编码格式分别读取两个文件 21 try { 22 23 //正常 24 System.out.println("正常:"); 25 readText_GBK(file_GBK); 26 //乱码 27 System.out.println("乱码"); 28 readText_GBK(file_UTF); 29 //正常 30 System.out.println("正常:"); 31 readText_UTF(file_UTF); 32 //乱码 33 System.out.println("乱码"); 34 readText_UTF(file_GBK); 35 } catch (IOException e) { 36 System.out.println("读入文件发生错误"+e.toString()); 37 } 38 39 } 40 41 42 //定义方法将数据按GBK编码写入文件 43 public static void writeText_GBK(File file) throws IOException{ 44 45 //建立输出字符流,使用指定的文件,以及编码 46 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(file),"gbk"); 47 48 49 //写入内容 50 osw.write("黑马训练营"); 51 52 //刷新流 53 osw.flush(); 54 //关闭流 55 osw.close(); 56 } 57 58 59 //定义方法,将数据按照GBK编码从文件中读入 60 public static void readText_GBK(File file) throws IOException{ 61 62 //建立文件读取字符流,使用指定的编码,以及文件 63 InputStreamReader isr = new InputStreamReader(new FileInputStream(file),"gbk"); 64 65 //接受读入的字符 66 char ch[] = new char[1024]; 67 68 //标记读入的字符数 69 int len=0; 70 71 //循环读取打印 72 while((len=isr.read(ch))!=-1){ 73 System.out.println(new String(ch,0,len)); 74 } 75 //关闭流操做 76 isr.close(); 77 } 78 79 80 //定义方法,将数据按照UTF-8编码写入指定的文件 81 public static void writeText_UTF(File file) throws IOException{ 82 83 //建立输出字符流,使用指定的文件,以及编码 84 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(file),"UTF-8"); 85 86 //写出数据 87 osw.write("黑马训练营"); 88 89 osw.flush(); 90 91 osw.close(); 92 } 93 94 95 //定义方法,将数据按照UTF-8编码从指定文件读入 96 public static void readText_UTF(File file)throws IOException{ 97 //建立文件读取字符流,使用指定的编码,以及文件 98 InputStreamReader isr = new InputStreamReader(new FileInputStream(file),"UTF-8"); 99 100 //定义数组接受字符 101 char ch[] = new char[1024]; 102 103 //标记 104 int len=0; 105 106 //循环读取 107 while((len=isr.read(ch))!=-1){ 108 System.out.println(new String(ch,0,len)); 109 } 110 111 isr.close(); 112 } 113 }
第七讲:字符编码
一,编码和解码:
二,编码和解码的字符集转换注意事项:
三,代码练习:
1 import java.util.Arrays; 2 3 public class EncodingDemo { 4 public static void main(String args[]) throws Exception{ 5 6 //建立一个字符串 7 String s="您好"; 8 //得到字符串的GBK 码表 9 byte[] b1 = s.getBytes("gbk"); 10 //输出码表 11 System.out.println(Arrays.toString(b1)); 12 //从新编码 13 String s1 = new String(b1,"gbk"); 14 15 System.out.println("s1="+s1); 16 17 //获取字符串的ISO8859-1码表 18 byte[] b2 = s1.getBytes("ISO8859-1"); 19 //输出码表 20 System.out.println(Arrays.toString(b2)); 21 //从新编码 22 String s2 = new String (b2,"gbk"); 23 24 System.out.println(s2); 25 } 26 }
第八讲:字符编码-联通
一,对于中文的”联通“,这两个字比较特别,它的二进制位正好是和在UTF-8中两个字节打头的相同,因此在文本文件中,若是单独写“联通”或者和知足UTF-8编码格式的字符一块儿保存时,记事本就会用UTF-8来进行解码动做,这样显示的就会是乱码。
解决办法:在联通前面加上任意中文字符。
二,代码练习:
1 import java.io.UnsupportedEncodingException; 2 3 public class LianTongDemo { 4 public static void main(String[] args) throws UnsupportedEncodingException { 5 String s = "联通"; 6 7 byte[] bytes = s.getBytes("gbk"); 8 9 for(byte b : bytes){ 10 System.out.println(Integer.toBinaryString(b&255)); 11 } 12 } 13 }
第九讲:练习
一,需求分析:
有五个学生,每一个学生有3门课的成绩,从键盘输入以上数据(包括姓名,三门课成绩输入的格式:如:张三,30,40,60计算出总成绩,并把学生的信息和计算出的总分数由高低顺序存放在磁盘文件“stuinfo.txt”中
二,思路:
三,代码练习:
1 import java.io.*; 2 import java.util.*; 3 4 5 //学生类实现Comparable接口 6 class Student implements Comparable<Student>{ 7 private String name; 8 private int sx,yy,yw,sum; 9 Student(String name,int sx,int yw,int yy){ 10 this.name=name; 11 this.sx=sx; 12 this.yw=yw; 13 this.yy=yy; 14 sum=sx+yw+yw; 15 } 16 17 //获取总成绩 18 public int getSum(){ 19 return sum; 20 } 21 22 //获取姓名 23 public String getName() 24 { 25 return name; 26 } 27 28 //复写compareTo方法 29 public int compareTo(Student s) { 30 31 int num=new Integer(this.sum).compareTo(new Integer(s.sum)); 32 if(num==0) 33 return this.name.compareTo(s.name); 34 return num; 35 } 36 37 //复写hashCode 38 public int hashCode(){ 39 40 return name.hashCode()+sum*33; 41 } 42 43 //复写equals 44 public boolean equals(Object obj){ 45 46 if(!(obj instanceof Student)) 47 throw new ClassCastException("类型不匹配"); 48 Student s=(Student)obj; 49 return this.name.equals(s.name)&&this.sum==s.sum; 50 } 51 52 53 //复写toString 54 public String toString(){ 55 return "Student["+name+","+sx+","+yw+","+yw+"]"; 56 } 57 } 58 59 //学生工具类 60 class StudentTools{ 61 //从键盘读取学生信息方法,以学生自身排序方式存入集合中 62 public static Set<Student> getStudentInfo_1()throws IOException 63 { 64 return getStudentInfo_2(null); 65 } 66 67 //从键盘读取学生信息方法,以比较器排序方式存入集合中 68 public static Set<Student> getStudentInfo_2(Comparator<Student> cmp)throws IOException 69 { 70 //键盘录入 71 BufferedReader bis= 72 new BufferedReader(new InputStreamReader(System.in)); 73 String info=null; 74 75 //定义一个集合,用来存储学生对象 76 Set<Student> set=null;//--------- 77 if(cmp==null) 78 set=new TreeSet<Student>(); 79 else 80 set=new TreeSet<Student>(cmp); 81 82 //读取数据 83 while((info=bis.readLine())!=null) 84 { 85 86 if("over".equals(info)) 87 break; 88 89 String[] in=info.split(","); 90 //将学生对象存入集合中 91 set.add(new Student(in[0],Integer.parseInt(in[1]), 92 Integer.parseInt(in[2]), 93 Integer.parseInt(in[3]))); 94 } 95 bis.close();//关流 96 97 return set; 98 } 99 100 //把学生信息按照指定属性写入指定文件中 101 public static void writeToFile(Set<Student> set,File file)throws IOException 102 { 103 //关联文件 104 BufferedWriter bw=new BufferedWriter(new FileWriter(file)); 105 106 //遍历 107 for (Student stu : set) 108 { 109 //将学生信息写入指定文件中 110 bw.write(stu.toString()+"\t"); 111 bw.write(stu.getSum()+""); 112 bw.newLine(); 113 bw.flush(); 114 115 } 116 117 bw.close();//关流 118 } 119 } 120 121 122 public class StudentInfoTest 123 { 124 public static void main(String[] args) 125 { 126 //定义一个翻转自身比较性的比较器 127 Comparator<Student> cmp=Collections.reverseOrder(); 128 try 129 { 130 //指定文件 131 File file =new File("stdinfo.txt"); 132 133 //调用学生工具类的获取信息方法,将信息存入集合中 134 Set<Student> set=StudentTools.getStudentInfo_2(cmp); 135 136 137 //将学生信息写入指定文件中 138 StudentTools.writeToFile(set,file); 139 } 140 catch (IOException e) 141 { 142 throw new RuntimeException("学生信息获取写入失败"); 143 } 144 } 145 }