新博客地址: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 }