程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 一同學 Java(四) File、Try 、序列化、MySQL、Socket

一同學 Java(四) File、Try 、序列化、MySQL、Socket

編輯:關於JAVA

一同學 Java(四) File、Try 、序列化、MySQL、Socket。本站提示廣大學習愛好者:(一同學 Java(四) File、Try 、序列化、MySQL、Socket)文章只能為提供參考,不一定能成為您想要的結果。以下是一同學 Java(四) File、Try 、序列化、MySQL、Socket正文


一、Java 流(Stream)、文件(File)和IO

Java.io 包簡直包括了一切操作輸出、輸入需求的類。一切這些流類代表了輸出源和輸入目的。

Java.io 包中的流支持很多種格式,比方:根本類型、對象、本地化字符集等等。

一個流可以了解為一個數據的序列。輸出流表示從一個源讀取數據,輸入流表示向一個目的寫數據。

Java 為 I/O 提供了弱小的而靈敏的支持,使其更普遍地使用到文件傳輸和網絡編程中。

 

Java BufferedReader 類 讀取控制台輸出

Java 的控制台輸出由 System.in 完成。

為了取得一個綁定到控制台的字符流,你可以把 System.in 包裝在一個 BufferedReader 對象中來創立一個字符流。

上面是創立 BufferedReader 的根本語法:

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

BufferedReader 對象創立後,我們便可以運用 read() 辦法從控制台讀取一個字符,或許用 readLine() 辦法讀取一個字符串。

從控制台讀取多字符輸出

從 BufferedReader 對象讀取一個字符要運用 read() 辦法,每次調用 read() 辦法,它從輸出流讀取一個字符並把該字符作為整數值前往。 當流完畢的時分前往 -1。該辦法拋出 IOException。

// 運用 BufferedReader 在控制台讀取字符

package four;

import java.io.*;

public class BRRead {
  public static void main(String args[]) throws IOException
  {
    char c;
    // 運用 System.in 創立 BufferedReader 
    BufferedReader br = new BufferedReader(
                new InputStreamReader(System.in)
            );
    System.out.println("輸出字符, 按下 'q' 鍵加入。");
    // 讀取字符
    do {
       c = (char) br.read();
       System.out.println(c);
    } while(c != 'q');
  }
}


/*輸入後果
輸出字符, 按下 'q' 鍵加入。
suoning
s
u
o
n
i
n
g




q
q

*/
View Code 從控制台讀取字符串

從規范輸出讀取一個字符串需求運用 BufferedReader 的 readLine() 辦法。

它的普通格式是:

String readLine( ) throws IOException
// 運用 BufferedReader 在控制台讀取字符

package four;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class BRReadLines {
     public static void main(String args[]) throws IOException
      {
        // 運用 System.in 創立 BufferedReader 
        BufferedReader br = new BufferedReader(new
                                InputStreamReader(System.in)
                );
        String str;
        System.out.println("Enter lines of text.");
        System.out.println("Enter 'end' to quit.");
        do {
           str = br.readLine();
           System.out.println(str);
        } while(!str.equals("end"));
      }
}

/*輸入後果
Enter lines of text.
Enter 'end' to quit.
suoning
suoning
end
end
*/
View Code 控制台輸入

控制台的輸入由 print( ) 和 println() 完成。這些辦法都由類 PrintStream 定義,System.out 是該類對象的一個援用。

PrintStream 承繼了 OutputStream類,並且完成了辦法 write()。這樣,write() 也可以用交往控制台寫操作。

PrintStream 定義 write() 的最復雜格式如下所示:

     該辦法將 byteval 的低八位字節寫到流中。
void write(int byteval)
// 演示 System.out.write().


import java.io.*;

public class WriteDemo {
    public static void main(String args[]) {
          int b; 
          b = 'S';
          System.out.write(b);
          System.out.write('\n');
       }
}

/*輸入後果
S
*/
View Code

 

Java Scanner 類

java.util.Scanner 是 Java5 的新特征,我們可以經過 Scanner 類來獲取用戶的輸出。

上面是創立 Scanner 對象的根本語法:

Scanner s = new Scanner(System.in);

 

package four;

import java.util.Scanner;

public class ScannerDemo {
    public static void main(String[] args) {  
        Scanner scan = new Scanner(System.in); 
    // 從鍵盤接納數據  
 
    //next方式接納字符串
        System.out.println("next方式接納:");
        // 判別能否還有輸出
        if(scan.hasNext()){   
          String str1 = scan.next();
          System.out.println("輸出的數據為:"+str1);  
        }
    }
}

/*輸入後果
next方式接納:
suo ning
輸出的數據為:suo
*/
next
package four;

import java.util.Scanner;

public class ScannerLinesDemo {
    public static void main(String[] args) {  
        Scanner scan = new Scanner(System.in); 
    // 從鍵盤接納數據  
 
    //nextLine方式接納字符串
        System.out.println("nextLine方式接納:");
        // 判別能否還有輸出
        if(scan.hasNextLine()){   
          String str2 = scan.nextLine();
          System.out.println("輸出的數據為:"+str2);  
        }
    }
}

/*輸入後果
nextLine方式接納:
suo ning
輸出的數據為:suo ning
*/
nextLine

 

next() 與 nextLine() 區別

next():

  • 1、一定要讀取到無效字符後才可以完畢輸出。
  • 2、對輸出無效字符之前遇到的空白,next() 辦法會自動將其去掉。
  • 3、只要輸出無效字符後才將其前面輸出的空白作為分隔符或許完畢符。
  • next() 不能失掉帶有空格的字符串。

nextLine():

  • 1、以Enter為完畢符,也就是說 nextLine()辦法前往的是輸出回車之前的一切字符。
  • 2、可以取得空白。

 

輸出之前最好先運用 hasNextXxx() 辦法停止驗證,再運用 nextXxx() 來讀取。

package four;

import java.util.Scanner;

public class ScannerHGDemo {
    public static void main(String[] args) {  
        Scanner scan = new Scanner(System.in);  
      // 從鍵盤接納數據  
        int i = 0 ;  
        float f = 0.0f ;  
        System.out.print("輸出整數:");  
        if(scan.hasNextInt()){                 
      // 判別輸出的能否是整數  
            i = scan.nextInt() ;                
      // 接納整數  
            System.out.println("整數數據:" + i) ;  
        }else{                                 
      // 輸出錯誤的信息  
            System.out.println("輸出的不是整數!") ;  
        }  
        System.out.print("輸出小數:");  
        if(scan.hasNextFloat()){              
      // 判別輸出的能否是小數  
            f = scan.nextFloat() ;             
      // 接納小數  
            System.out.println("小數數據:" + f) ;  
        }else{                                
      // 輸出錯誤的信息  
            System.out.println("輸出的不是小數!") ;  
        }
        
        
        
        Scanner scan1 = new Scanner(System.in);
        System.out.print("輸出個數:"); 
        
        double sum = 0;  
        int m = 0;  
  
        while(scan1.hasNextDouble())  
        {  
            double x = scan1.nextDouble();  
            m = m + 1;  
            sum = sum + x;  
        }  
  
        System.out.println(m+"個數的和為"+sum);  
        System.out.println(m+"個數的均勻值是"+(sum/m));
    }
}


/*輸入後果
輸出整數:1
整數數據:1
輸出小數:1.1
小數數據:1.1
輸出個數:10

1個數的和為10.0
1個數的均勻值是10.0
*/
View Code

 

讀寫文件

一個流被定義為一個數據序列。輸出流用於從源讀取數據,輸入流用於向目的寫數據。

下圖是一個描繪輸出流和輸入流的類層次圖。

 

FileInputStream

該流用於從文件讀取數據,它的對象可以用關鍵字 new 來創立。

有多種結構辦法可用來創立對象。

InputStream f = new FileInputStream("C:/java/hello");

File f = new File("C:/java/hello");
InputStream f = new FileInputStream(f);

創立了InputStream對象,就可以運用上面的辦法來讀取流或許停止其他的流操作:

序號辦法及描繪 1 public void close() throws IOException{}
封閉此文件輸出流並釋放與此流有關的一切零碎資源。拋出IOException異常。 2 protected void finalize()throws IOException {}
這個辦法肅清與該文件的銜接。確保在不再援用文件輸出流時調用其 close 辦法。拋出IOException異常。 3 public int read(int r)throws IOException{}
這個辦法從 InputStream 對象讀取指定字節的數據。前往為整數值。前往下一字節數據,假如曾經到開頭則前往-1。 4 public int read(byte[] r) throws IOException{}
這個辦法從輸出流讀取r.length長度的字節。前往讀取的字節數。假如是文件開頭則前往-1。 5 public int available() throws IOException{}
前往下一次對此輸出流調用的辦法可以不受阻塞地從此輸出流讀取的字節數。前往一個整數值。

 

FileOutputStream

該類用來創立一個文件並向文件中寫數據。

假如該流在翻開文件停止輸入前,目的文件不存在,那麼該流會創立該文件。

OutputStream f = new FileOutputStream("C:/java/hello")

File f = new File("C:/java/hello");
OutputStream f = new FileOutputStream(f);

創立OutputStream 對象完成後,就可以運用上面的辦法來寫入流或許停止其他的流操作:

序號辦法及描繪 1 public void close() throws IOException{}
封閉此文件輸出流並釋放與此流有關的一切零碎資源。拋出IOException異常。 2 protected void finalize()throws IOException {}
這個辦法肅清與該文件的銜接。確保在不再援用文件輸出流時調用其 close 辦法。拋出IOException異常。 3 public void write(int w)throws IOException{}
這個辦法把指定的字節寫到輸入流中。 4 public void write(byte[] w)
把指定數組中w.length長度的字節寫到OutputStream中。

 

 實例
package four;

import java.io.*;


public class myFileInputStream {
    public static void main(String[] args){
        try{
            
            byte bWrite [] = {11,22,33,55,66};
            OutputStream os = new FileOutputStream("F:\\sql_text\\department.txt");
            for(int x=0;x<bWrite.length;x++){
                os.write(bWrite[x]);
            }
            os.close();
            
            
            InputStream is = new FileInputStream("F:\\sql_text\\department.txt");
            int size = is.available();
            for(int i=0;i<size;i++){
                System.out.print(is.read());
            }
            is.close();
            
        } catch(IOException e){
            System.out.println("IOException..");
        }
        
    }
}
FileInputStream & FileOutputStream

 下面的順序首先創立文件test.txt,並把給定的數字以二進制方式寫進該文件,同時輸入到控制台上。

以上代碼由於是二進制寫入,能夠存在亂碼,你可以運用以下代碼實例來處理亂碼問題:

package four;

import java.io.*;

public class fileStreamTest2{
  public static void main(String[] args) throws IOException {
    
    File f = new File("F:\\sql_text\\department.txt");
    FileOutputStream fop = new FileOutputStream(f);
    // 構建FileOutputStream對象,文件不存在會自動新建
    
    OutputStreamWriter writer = new OutputStreamWriter(fop, "UTF-8");
    // 構建OutputStreamWriter對象,參數可以指定編碼,默許為操作零碎默許編碼,windows上是gbk
    
    writer.append("中文輸出");
    // 寫入到緩沖區
    
    writer.append("\r\n");
    //換行
    
    writer.append("English");
    // 刷新緩存沖,寫入到文件,假如上面曾經沒有寫入的內容了,直接close也會寫入
    
    writer.close();
    //封閉寫入流,同時會把緩沖區內容寫入文件,所以下面的正文掉
    
    fop.close();
    // 封閉輸入流,釋放零碎資源
 
    FileInputStream fip = new FileInputStream(f);
    // 構建FileInputStream對象
    
    InputStreamReader reader = new InputStreamReader(fip, "UTF-8");
    // 構建InputStreamReader對象,編碼與寫入相反
 
    StringBuffer sb = new StringBuffer();
    while (reader.ready()) {
      sb.append((char) reader.read());
      // 轉成char加到StringBuffer對象中
    }
    System.out.println(sb.toString());
    reader.close();
    // 封閉讀取流
    
    fip.close();
    // 封閉輸出流,釋放零碎資源
 
  }
}
FileInputStream & FileOutputStream

  

二、Java 異常處置

要了解Java異常處置是如何任務的,你需求掌握以下三品種型的異常:

  • 反省性異常:最具代表的反省性異常是用戶錯誤或問題惹起的異常,這是順序員無法預見的。例如要翻開一個不存在文件時,一個異常就發作了,這些異常在編譯時不能被復雜地疏忽。
  • 運轉時異常: 運轉時異常是能夠被順序員防止的異常。與反省性異常相反,運轉時異常可以在編譯時被疏忽。
  • 錯誤: 錯誤不是異常,而是脫離順序員控制的問題。錯誤在代碼中通常被疏忽。例如,當棧溢出時,一個錯誤就發作了,它們在編譯也反省不到的。
Exception 類的層次

一切的異常類是從 java.lang.Exception 類承繼的子類。

Exception 類是 Throwable 類的子類。除了Exception類外,Throwable還有一個子類Error 。

Java 順序通常不捕捉錯誤。錯誤普通發作在嚴重毛病時,它們在Java順序處置的范圍之外。

Error 用來指示運轉時環境發作的錯誤。

例如,JVM 內存溢出。普通地,順序不會從錯誤中恢復。

異常類有兩個次要的子類:IOException 類和 RuntimeException 類。

 

 

 

Java 內置異常類

Java 言語定義了一些異常類在 java.lang 規范包中。

規范運轉時異常類的子類是最罕見的異常類。由於 java.lang 包是默許加載到一切的 Java 順序的,所以大局部從運轉時異常類承繼而來的異常都可以直接運用。

Java 依據各個類庫也定義了一些其他的異常,上面的表中列出了 Java 的非反省性異常。

異常描繪 ArithmeticException 當呈現異常的運算條件時,拋出此異常。例如,一個整數"除以零"時,拋出此類的一個實例。 ArrayIndexOutOfBoundsException 用合法索引訪問數組時拋出的異常。假如索引為負或大於等於數組大小,則該索引為合法索引。 ArrayStoreException 試圖將錯誤類型的對象存儲到一個對象數組時拋出的異常。 ClassCastException 當試圖將對象強迫轉換為不是實例的子類時,拋出該異常。 IllegalArgumentException 拋出的異常標明向辦法傳遞了一個不合法或不正確的參數。 IllegalMonitorStateException 拋出的異常標明某一線程曾經試圖等候對象的監視器,或許試圖告訴其他正在等候對象的監視器而自身沒有指定監視器的線程。 IllegalStateException 在合法或不適當的時間調用辦法時發生的信號。換句話說,即 Java 環境或 Java 使用順序沒有處於懇求操作所要求的適當形態下。 IllegalThreadStateException 線程沒有處於懇求操作所要求的適當形態時拋出的異常。 IndexOutOfBoundsException 指示某排序索引(例如對數組、字符串或向量的排序)超出范圍時拋出。 NegativeArraySizeException 假如使用順序試圖創立大小為負的數組,則拋出該異常。 NullPointerException 當使用順序試圖在需求對象的中央運用 null 時,拋出該異常 NumberFormatException 當使用順序試圖將字符串轉換成一種數值類型,但該字符串不能轉換為適當格式時,拋出該異常。 SecurityException 由平安管理器拋出的異常,指示存在平安進犯。 StringIndexOutOfBoundsException 此異常由 String 辦法拋出,指示索引或許為負,或許超出字符串的大小。 UnsupportedOperationException 當不支持懇求的操作時,拋出該異常。

 

上面的表中列出了 Java 定義在 java.lang 包中的反省性異常類。

異常描繪 ClassNotFoundException 使用順序試圖加載類時,找不到相應的類,拋出該異常。 CloneNotSupportedException 當調用 Object 類中的 clone 辦法克隆對象,但該對象的類無法完成 Cloneable 接口時,拋出該異常。 IllegalAccessException 回絕訪問一個類的時分,拋出該異常。 InstantiationException 當試圖運用 Class 類中的 newInstance 辦法創立一個類的實例,而指定的類對象由於是一個接口或是一個籠統類而無法實例化時,拋出該異常。 InterruptedException 一個線程被另一個線程中綴,拋出該異常。 NoSuchFieldException 懇求的變量不存在 NoSuchMethodException 懇求的辦法不存在

 

異常辦法

上面的列表是 Throwable 類的次要辦法:

 

序號辦法及闡明 1 public String getMessage()
前往關於發作的異常的詳細信息。這個音訊在Throwable 類的結構函數中初始化了。 2 public Throwable getCause()
前往一個Throwable 對象代表異常緣由。 3 public String toString()
運用getMessage()的後果前往類的串級名字。 4 public void printStackTrace()
打印toString()後果和棧層次到System.err,即錯誤輸入流。 5 public StackTraceElement [] getStackTrace()
前往一個包括堆棧層次的數組。下標為0的元素代表棧頂,最後一個元素代表辦法調用堆棧的棧底。 6 public Throwable fillInStackTrace()
用以後的調用棧層次填充Throwable 對象棧層次,添加到棧層次任何先前信息中。

 

捕捉異常

運用 try 和 catch 關鍵字可以捕捉異常。try/catch 代碼塊放在異常能夠發作的中央。

try/catch代碼塊中的代碼稱為維護代碼,運用 try/catch 的語法如下:

try
{
   // 順序代碼
}catch(ExceptionName e1)
{
   //Catch 塊
}
  多重捕捉塊

一個 try 代碼塊前面跟隨多個 catch 代碼塊的狀況就叫多重捕捉。

 

finally關鍵字

finally 關鍵字用來創立在 try 代碼塊前面執行的代碼塊。

無論能否發作異常,finally 代碼塊中的代碼總會被執行。

在 finally 代碼塊中,可以運轉清算類型等收尾善後性質的語句。

try{
  // 順序代碼
}catch(異常類型1 異常的變量名1){
  // 順序代碼
}catch(異常類型2 異常的變量名2){
  // 順序代碼
}finally{
  // 順序代碼
}
finally

 

實例
//ExcepTest.java

package five;

import java.*;

public class ExcepTest {
    public static void main(String args[]){
        try{
            int a[] = new int[2];
            System.out.printf("Access element three :%s", a[3]);
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.printf("Exception thrown : %s", e);
        } finally{
            System.out.println("Finally.");
        }
    }
}
// Exception thrown : java.lang.ArrayIndexOutOfBoundsException: 3Finally.

 

throws/throw 關鍵字:

假如一個辦法沒有捕捉一個反省性異常,那麼該辦法必需運用 throws 關鍵字來聲明。throws 關鍵字放在辦法簽名的尾部。

也可以運用 throw 關鍵字拋出一個異常,無論它是新實例化的還是剛捕捉到的。

//testthrow.java

package five;

import java.io.*;
import java.rmi.RemoteException;

import javax.naming.InsufficientResourcesException;

public class testthrow {
    
    public void deposit (double amount) throws RemoteException {
        throw new RemoteException();
    }
    
    public void withdraw (double amount) 
            throws RemoteException, InsufficientResourcesException{
        // 多個異常
    }
}

 

聲明自定義異常

在 Java 中你可以自定義異常。編寫自己的異常類時需求記住上面的幾點。

  • 一切異常都必需是 Throwable 的子類。
  • 假如希望寫一個反省性異常類,則需求承繼 Exception 類。
  • 假如你想寫一個運轉時異常類,那麼需求承繼 RuntimeException 類。

可以像上面這樣定義自己的異常類:

class MyException extends Exception{
}

 

實例
//MyException.java

package five;

public class MyException extends Exception {
    
    private double amont;
    
    public MyException(double amount){
        this.amont = amount;
    }
    
    public double getAmount (){
        return amont;
    }
}
MyException.java
//CheckingAccount.java

package five;

public class CheckingAccount {
    
    public double balance;
    private int number;
    
    public CheckingAccount(int number){
        this.number = number;
    }
    
    public void deposit(double amount){
        balance += amount;
    }
    
    public void withdraw(double amount) 
            throws MyException{
        if (amount <= balance){
            balance -= amount;
        } else {
            double needs = amount - balance;
            throw new MyException(needs);
        }
    }
    
    public double getBalance(){
        return balance;
    }
    
    public int getNumber(){
        return number;
    }

}
CheckingAccount.java
package five;

public class BankDemo {
    public static void main(String[] args){
        CheckingAccount c = new CheckingAccount(99);
        c.deposit(66);
        try{
            c.withdraw(10);
            System.out.println("10");
            c.withdraw(88);
        } catch (MyException e) {
            System.out.println("error Myerror " + e);
            System.out.println("error Myerror " + e.getAmount());
            e.printStackTrace();
        }
    };
}

/*
 * 10
error Myerror five.MyException
error Myerror 32.0
five.MyException
    at five.CheckingAccount.withdraw(CheckingAccount.java:22)
    at five.BankDemo.main(BankDemo.java:10)
*/
BankDemo.java

 

三、java 序列化

Java 提供了一種對象序列化的機制,該機制中,一個對象可以被表示為一個字節序列,該字節序列包括該對象的數據、有關對象的類型的信息和存儲在對象中數據的類型。

將序列化對象寫入文件之後,可以從文件中讀取出來,並且對它停止反序列化,也就是說,對象的類型信息、對象的數據,還有對象中的數據類型可以用來在內存中新建對象。

整個進程都是 Java 虛擬機(JVM)獨立的,也就是說,在一個平台上序列化的對象可以在另一個完全不同的平台上反序列化該對象。

類 ObjectInputStream 和 ObjectOutputStream 是高層次的數據流,它們包括序列化和反序列化對象的辦法。

ObjectOutputStream 類包括很多寫辦法來寫各種數據類型,但是一個特別的辦法例外:

public final void writeObject(Object x) throws IOException

下面的辦法序列化一個對象,並將它發送到輸入流。類似的 ObjectInputStream 類包括如下反序列化一個對象的辦法:

public final Object readObject() throws IOException, 
                                 ClassNotFoundException

該辦法從流中取出下一個對象,並將對象反序列化。它的前往值為Object,因而,你需求將它轉換成適宜的數據類型。

為了演示序列化在Java中是怎樣任務的,我將運用Employee類,假定我們定義了如下的Employee類,該類完成了Serializable 接口。

// Employee.java

public class Employee implements java.io.Serializable
{
   public String name;
   public String address;
   public transient int SSN;
   public int number;
   public void mailCheck()
   {
      System.out.println("Mailing a check to " + name
                           + " " + address);
   }
}

請留意,一個類的對象要想序列化成功,必需滿足兩個條件:

該類必需完成 java.io.Serializable 對象。

該類的一切屬性必需是可序列化的。假如有一個屬性不是可序列化的,則該屬性必需注明是長久的。

假如你想知道一個 Java 規范類能否是可序列化的,請檢查該類的文檔。檢驗一個類的實例能否能序列化非常復雜, 只需求檢查該類有沒有完成 java.io.Serializable接口。

 

實例 序列化對象

ObjectOutputStream 類用來序列化一個對象,如下的 SerializeDemo 例子實例化了一個 Employee 對象,並將該對象序列化到一個文件中。

該順序執行後,就創立了一個名為 employee.ser 文件。該順序沒有任何輸入,但是你可以經過代碼研讀來了解順序的作用。

留意: 當序列化一個對象到文件時, 依照 Java 的規范商定是給文件一個 .ser 擴展名。

//SerializeDemo.java

package five;

import java.io.*;

public class SerializeDemo {
    public static void main(String[] args){
        Employee e = new Employee();
        e.name = "Nick";
        e.address = "Beijing";
        e.SSN = 630571017;
        e.number = 18;
        try {
            FileOutputStream fileOut = new FileOutputStream("F:\\java_project\\employee.ser");
            ObjectOutputStream out = new ObjectOutputStream(fileOut);
            out.writeObject(e);
            out.close();
            fileOut.close();
            System.out.println("enoloyee.ser");
        } catch (Exception e2) {
            e2.printStackTrace();
        }
    }
}

 

反序列化對象

上面的 DeserializeDemo 順序實例了反序列化,/tmp/employee.ser 存儲了 Employee 對象。

//DeserializeDemo.java

package five;

import java.io.*;

public class DeserializeDemo {
    public static void main(String[] args){
        Employee e = null;
        try {
            FileInputStream fileIn = new FileInputStream("F:\\java_project\\employee.ser");
            ObjectInputStream in = new ObjectInputStream(fileIn);
            e = (Employee) in.readObject();
            in.close();
            fileIn.close();
        } catch (IOException i){
            i.printStackTrace();
            return;
        } catch (ClassNotFoundException c) {
            System.out.println("Employee class not found");
            c.printStackTrace();
            return;
        }
        System.out.println("Employee.");
        System.out.println("Name: " + e.name);
        System.out.println("Address: " + e.address);
        System.out.println("SSN: " + e.SSN);
        System.out.println("Number: " + e.number);
    }
}

/*
Employee.
Name: Nick
Address: Beijing
SSN: 0
Number: 18
*/

readObject() 辦法中的 try/catch代碼塊嘗試捕捉 ClassNotFoundException 異常。關於 JVM 可以反序列化對象,它必需是可以找到字節碼的類。假如JVM在反序列化對象的進程中找不到該類,則拋出一個 ClassNotFoundException 異常。

留意,readObject() 辦法的前往值被轉化成 Employee 援用。

當對象被序列化時,屬性 SSN 的值為 630571017,但是由於該屬性是長久的,該值沒有被發送到輸入流。所以反序列化後 Employee 對象的 SSN 屬性為 0。

 

 

四、銜接MySQL

Java 銜接 MySQL 需求驅動包,最新版下載地址為:http://dev.mysql.com/downloads/connector/j/,解壓後失掉jar庫文件,然後在對應的項目中導入該庫文件。

Eclipse中導入內部jar包:

http://jingyan.baidu.com/article/ca41422fc76c4a1eae99ed9f.html

 

//MySQLDemo.java

package six;

import java.sql.*;

public class MySQLDemo {
    
    // JDBC 驅動名及數據庫 URL(留意冒號,少些一個讓我找了10分鐘)
    static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
    static final String DB_URL = "jdbc:mysql://127.0.0.1:3306/test";
    
    // 數據庫的用戶名與密碼,需求依據自己的設置
    static final String USER = "root";
    static final String PASS = "suoning";
    
    public static void main(String[] args){
        Connection conn = null;
        Statement stmt = null;
        try{
            // 注冊 JDBC 驅動
            Class.forName(JDBC_DRIVER);
            
            // 翻開鏈接
            System.out.println("銜接數據庫...");
            conn = DriverManager.getConnection(DB_URL, USER, PASS);
            
            // 執行查詢
            System.out.println("實例化Statement...");
            stmt = conn.createStatement();
            String sql;
            sql = "SELECT * FROM user";
            ResultSet rs = stmt.executeQuery(sql);
            
            // 展開後果集數據庫
            while (rs.next()){
                // 經過字段檢索
                int id = rs.getInt("id");
                String name = rs.getString("name");
                // 輸入數據
                System.out.print(id);
                System.out.print(" ");
                System.out.print(name);
                System.out.println();
            }
            // 完成後封閉
            rs.close();
            stmt.close();
            conn.close();
            
        } catch (SQLException e){
            // 處置 JDBC 錯誤
            e.printStackTrace();
        } catch (Exception e){
            // 處置 Class.forName 錯誤
            e.printStackTrace();
        } finally{
            // 封閉資源
            try{
                if(stmt!=null) stmt.close();
            } catch (SQLException e){
                
            }
            try{
                if(conn!=null) conn.close();
            } catch (SQLException e){
                e.printStackTrace();
            }
        }
        System.out.println("The end.");
    }
}

/*
銜接數據庫...
實例化Statement...
1 nick
2 jenny
3 honey
The end.
*/

 

五、Socket編程 

網絡編程是指編寫運轉在多個設備(計算機)的順序,這些設備都經過網絡銜接起來。

java.net 包中 J2SE 的 API 包括有類和接口,它們提供低層次的通訊細節。你可以直接運用這些類和接口,來專注於處理問題,而不必關注通訊細節。

java.net 包中提供了兩種罕見的網絡協議的支持:

  • TCP:TCP 是傳輸控制協議的縮寫,它保證了兩個使用順序之間的牢靠通訊。通常用於互聯網協議,被稱 TCP / IP。

  • UDP:UDP 是用戶數據報協議的縮寫,一個無銜接的協議。提供了使用順序之間要發送的數據的數據包

 

套接字運用TCP提供了兩台計算機之間的通訊機制。 客戶端順序創立一個套接字,並嘗試銜接服務器的套接字。

當銜接樹立時,服務器會創立一個 Socket 對象。客戶端和服務器如今可以經過對 Socket 對象的寫入和讀取來停止停止通訊。

java.net.Socket 類代表一個套接字,並且 java.net.ServerSocket 類為服務器順序提供了一種來監聽客戶端,並與他們樹立銜接的機制。

以下步驟在兩台計算機之間運用套接字樹立TCP銜接時會呈現:

  • 服務器實例化一個 ServerSocket 對象,表示經過服務器上的端口通訊。

  • 服務器調用 ServerSocket 類的 accept() 辦法,該辦法將不斷等候,直到客戶端銜接到服務器上給定的端口。

  • 服務器正在等候時,一個客戶端實例化一個 Socket 對象,指定服務器稱號和端口號來懇求銜接。

  • Socket 類的結構函數試圖將客戶端銜接到指定的服務器和端口號。假如通訊被樹立,則在客戶端創立一個 Socket 對象可以與服務器停止通訊。

  • 在服務器端,accept() 辦法前往服務器上一個新的 socket 援用,該 socket 銜接到客戶端的 socket。

銜接樹立後,經過運用 I/O 流在停止通訊,每一個socket都有一個輸入流和一個輸出流,客戶端的輸入流銜接到服務器端的輸出流,而客戶端的輸出流銜接到服務器端的輸入流。

TCP 是一個雙向的通訊協議,因而數據可以經過兩個數據流在同一時間發送.以下是一些類提供的一套完好的有用的辦法來完成 socket。

 

ServerSocket 類的辦法

服務器使用順序經過運用 java.net.ServerSocket 類以獲取一個端口,並且偵聽客戶端懇求。

ServerSocket 類有四個結構辦法:

序號 辦法描繪 1 public ServerSocket(int port) throws IOException
創立綁定到特定端口的服務器套接字。 2 public ServerSocket(int port, int backlog) throws IOException
應用指定的 backlog 創立服務器套接字並將其綁定到指定的本地端口號。 3 public ServerSocket(int port, int backlog, InetAddress address) throws IOException
運用指定的端口、偵聽 backlog 和要綁定到的本地 IP 地址創立服務器。 4 public ServerSocket() throws IOException
創立非綁定服務器套接字。

創立非綁定服務器套接字。 假如 ServerSocket 結構辦法沒有拋出異常,就意味著你的使用順序曾經成功綁定到指定的端口,並且偵聽客戶端懇求。

這裡有一些 ServerSocket 類的常用辦法:

序號 辦法描繪 1 public int getLocalPort()
  前往此套接字在其上偵聽的端口。 2 public Socket accept() throws IOException
偵聽並承受到此套接字的銜接。 3 public void setSoTimeout(int timeout)
 經過指定超時值啟用/禁用 SO_TIMEOUT,以毫秒為單位。 4 public void bind(SocketAddress host, int backlog)
將 ServerSocket 綁定到特定地址(IP 地址和端口號)。

 

Socket 類的辦法

java.net.Socket 類代表客戶端和服務器都用來相互溝通的套接字。客戶端要獲取一個 Socket 對象經過實例化 ,而 服務器取得一個 Socket 對象則經過 accept() 辦法的前往值。

Socket 類有五個結構辦法.

序號 辦法描繪 1 public Socket(String host, int port) throws UnknownHostException, IOException.
創立一個流套接字並將其銜接到指定主機上的指定端口號。 2 public Socket(InetAddress host, int port) throws IOException
創立一個流套接字並將其銜接到指定 IP 地址的指定端口號。 3 public Socket(String host, int port, InetAddress localAddress, int localPort) throws IOException.
創立一個套接字並將其銜接到指定近程主機上的指定近程端口。 4 public Socket(InetAddress host, int port, InetAddress localAddress, int localPort) throws IOException.
創立一個套接字並將其銜接到指定近程地址上的指定近程端口。 5 public Socket()
經過零碎默許類型的 SocketImpl 創立未銜接套接字

當 Socket 結構辦法前往,並沒有復雜的實例化了一個 Socket 對象,它實踐上會嘗試銜接到指定的服務器和端口。

上面列出了一些感興味的辦法,留意客戶端和服務器端都有一個 Socket 對象,所以無論客戶端還是服務端都可以調用這些辦法。

序號 辦法描繪 1 public void connect(SocketAddress host, int timeout) throws IOException
將此套接字銜接到服務器,並指定一個超時值。 2 public InetAddress getInetAddress()
 前往套接字銜接的地址。 3 public int getPort()
前往此套接字銜接到的近程端口。 4 public int getLocalPort()
前往此套接字綁定到的本地端口。 5 public SocketAddress getRemoteSocketAddress()
前往此套接字銜接的端點的地址,假如未銜接則前往 null。 6 public InputStream getInputStream() throws IOException
前往此套接字的輸出流。 7 public OutputStream getOutputStream() throws IOException
前往此套接字的輸入流。 8 public void close() throws IOException
封閉此套接字。

 

InetAddress 類的辦法

這個類表示互聯網協議(IP)地址。上面列出了 Socket 編程時比擬有用的辦法:

序號 辦法描繪 1 static InetAddress getByAddress(byte[] addr)
在給定原始 IP 地址的狀況下,前往 InetAddress 對象。 2 static InetAddress getByAddress(String host, byte[] addr)
依據提供的主機名和 IP 地址創立 InetAddress。 3 static InetAddress getByName(String host)
在給定主機名的狀況下確定主機的 IP 地址。 4 String getHostAddress() 
前往 IP 地址字符串(以文本表現方式)。 5 String getHostName() 
 獲取此 IP 地址的主機名。 6 static InetAddress getLocalHost()
前往本地主機。 7 String toString()
將此 IP 地址轉換為 String。

 

 實例 Socket 服務端實例:
//GreetingServer.java

package seven;

import java.net.*;
import java.io.*;

public class GreetingServer extends Thread {
    
    private ServerSocket serverSocket;
    
    public GreetingServer(int port) throws IOException{
        serverSocket = new ServerSocket(port);
        serverSocket.setSoTimeout(9999);
    }
    
    public void run(){
        while(true){
            try{
                System.out.println("Wating for you ..." + serverSocket.getLocalPort());
                Socket server = serverSocket.accept();
                
                System.out.println("connected " + server.getRemoteSocketAddress());
                DataInputStream in = new DataInputStream(server.getInputStream());
                System.out.println(in.readUTF());
                DataOutputStream out = new DataOutputStream(server.getOutputStream());
                out.writeUTF("The end....." + server.getLocalSocketAddress());
                server.close();
            } catch(SocketTimeoutException e){
                System.out.println("Time out error.");
                break;
            } catch(IOException e){
                e.printStackTrace();
                break;
            }
        }
    }
    
    public static void main(String[] args){
        int port = Integer.parseInt(args[0]);
        try {
            Thread t = new GreetingServer(port);
            t.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
}

 

Socket 客戶端實例:
//GreetingClient.java

package seven;

import java.net.*;
import java.io.*;

public class GreetingClient {

    public static void main(String[] args){
        String serverName = args[0];
        int port = Integer.parseInt(args[1]);
        try {
            System.out.println(serverName + " " + port);
            
            Socket client = new Socket(serverName, port);
            System.out.println(client.getRemoteSocketAddress());
            
            OutputStream outToServer = client.getOutputStream();
            DataOutputStream out = new DataOutputStream(outToServer);
            out.writeUTF("S" + client.getLocalSocketAddress());
            
            InputStream inFormServer = client.getInputStream();
            DataInputStream in = new DataInputStream(inFormServer);
            System.out.println("s" + in.readUTF());
            
            client.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
}

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved