洛神賦

          子虛烏有

            BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
            7 Posts :: 10 Stories :: 0 Comments :: 0 Trackbacks

          2010年11月6日 #

          知識點一:分類
                   IO
          中按照數(shù)據(jù)流的方向不同可以分為輸入流和輸出流(以程序的角度來考慮)

                   按照數(shù)據(jù)單位的不同可以分為字節(jié)流和字符流。

                   按照功能的不同可以分為節(jié)點流和處理流。


          知識點二: 四大等級結(jié)構(gòu)

            java語言的i/o庫提供了四大等級結(jié)構(gòu):InputStream,OutputStream,Reader,Writer四個系列的類。InputStream和OutputStream處理8位字節(jié)流數(shù)據(jù), Reader和Writer處理16位的字符流數(shù)據(jù)。InputStream和Reader處理輸入, OutputStream和Writer處理輸出。大家一定要到J2SE文檔中看看這四大等級結(jié)構(gòu)的類繼承體系。

            除了這四大系列類,i/o庫還提供了少數(shù)的輔助類,其中比較重要的是InputStreamReader和OutputStreamWriter。InputStreamReader把InputStream適配為Reader, OutputStreamWriter把OutputStream適配為Writer;這樣就架起了字節(jié)流處理類和字符流處理類間的橋梁。

            您使用I/O庫時,只要按以上的規(guī)則,到相應(yīng)的類體系中尋找您需要的類即可

          下面我就會對I/O 進行不定期更新:

          1 FileOutputStream 文件字節(jié)流

          Public class FileInputStream extends InputStream

            {

            /* File Descriptor - handle to the open file */

            private FileDescriptor fd;

            public FileInputStream(FileDescriptor fdObj)

            {

            SecurityManager security = System.getSecurityManager();

            if (fdObj == null) {

            throw new NullPointerException();

            }

            if (security != null) {

            security.checkRead(fdObj);

            }

            fd = fdObj;

            }

            //其他代碼

            }

            可見,FileInputStream繼承了InputStream,組合了FileDescriptor,采用的是對象Adapter模式。我們學習i/o庫時,主要應(yīng)該掌握這四個對象Adapter模式的適配源: ByteArrayInputStream的適配源是Byte數(shù)組, FileInputStream的適配源是File對象, PipedInputStream的適配源是PipedOutputStream對象, StringBufferInputStream的適配源是String對象



          posted @ 2010-11-13 11:52 洛神賦 閱讀(308) | 評論 (0)編輯 收藏


          線程間通信:一個線程向數(shù)據(jù)存儲空間添加數(shù)據(jù)(唐老鴨),另一個線程從數(shù)據(jù)存儲空間取出數(shù)據(jù)(米琪)。

          程序有兩種以外需要考慮:

          1、      假設(shè)唐老鴨線程剛向數(shù)據(jù)存儲空間添加了一輛車的名字。還沒有加入這輛車的顏色,CPU就切換到了米琪線程,唐老鴨線程將把這輛車的名字和上輛車的顏色聯(lián)系到了一起。

          2 、唐老鴨了若干次的數(shù)據(jù)。米琪才開始取數(shù)據(jù),或者是,米琪取完了一個數(shù)據(jù)后,還沒等到唐老鴨放入新的數(shù)據(jù),又重復(fù)取出已取過的數(shù)據(jù)。

          可能出現(xiàn)的問題:

          1唐老鴨米琪快時,米琪會漏掉一些數(shù)據(jù)沒有取到。

          2、      米琪唐老鴨快時,米琪取相同的數(shù)據(jù)。

          多個線程共享同一資源的時候,必須進行同步,采用同步方法,解決第一個問題。

          線程的等待和喚醒機制:

          wait():告訴當前線程放棄監(jiān)視器并進入睡眠狀態(tài),直到其他線程進入同一監(jiān)視器并調(diào)用notify為止。

          notify():喚醒同一對象監(jiān)視器中調(diào)用wait的第一個線程。

          程序中采用線程的等待和喚醒機制,當發(fā)現(xiàn)米琪沒有取走內(nèi)容時,唐老鴨應(yīng)該等待,當米琪把內(nèi)容取走之后,唐老鴨才可以放。這樣解決了第二個問題。


          代碼如下:


          package Killva.IOchaper4.o3;


          class Animal{
           private String name ="唐老鴨";
           private String  sex= "公";
           private boolean flag=false;
           
           public synchronized void set(String name, String sex){//生產(chǎn)者
            //如果flag的值不是true則要等待
            
            if(!flag){
             //等待
             try{
              wait();
             }catch(Exception e){}
             
            }
            //如果向下繼續(xù)執(zhí)行了,則表示可以設(shè)置, flag =true
            this.name=name;
            this.sex=sex;
            //修改設(shè)置的標志
            flag = false;
            //喚醒其他線程
            notify();
           }
           //設(shè)置一個輸出的方法
           public synchronized void get(){
            //如果flag的值為true的時候,表示要等待
            if(flag){
             try{
              wait();
              
             }catch(Exception e){}
             
            }
            //如果向下執(zhí)行了,就表示允許
            System.out.println(this.name+"-->"+this.sex);
            //改變標簽
            flag =true;
            notify();
           }
          }

          class Pro implements Runnable{
           Animal per =null;
           public Pro(Animal p){
            this.per=p;
            
           }
           public void run() {
            int i =0;
            
            while (true){
             
             if(i==0){
              per.set("米琪", "母");
              i=1;
              
             }else{
              per.set("唐老鴨", "公");
              i=0;
             }
            }
           }
          }

          class Cus implements Runnable{
           Animal per =null;
           public Cus(Animal p){
            this.per=p;
           }
           public void run() {
            while(true){
               per.get();
            }
           }
          }


          public class Demo01 {
           //主方法
           public static void main(String[] args){
            Animal per =new Animal();
            Pro p =new Pro(per);
            Cus c =new Cus(per);
            
            new Thread(p).start();
            new Thread(c).start();
            
           }

          }

          運行結(jié)果:




          感謝閱讀 !!!歡迎交流!!!    QQ:237333696
          posted @ 2010-11-13 11:12 洛神賦 閱讀(923) | 評論 (0)編輯 收藏

                   所謂socket通常也稱作"套接字",用于描述IP地址和端口,是一個通信鏈的句柄。應(yīng)用程序通常通過"套接字"向網(wǎng)絡(luò)發(fā)出請求或者應(yīng)答網(wǎng)絡(luò)請求。Socket和ServerSocket類庫位于java.net包中。ServerSocket用于服務(wù)器端,Socket是建立網(wǎng)絡(luò)連接時使用的。在連接成功時,應(yīng)用程序兩端都會產(chǎn)生一個Socket實例,操作這個實例,完成所需的會話。對于一個網(wǎng)絡(luò)連接來說,套接字是平等的,并沒有差別,不因為在服務(wù)器端或在客戶端而產(chǎn)生不同級別。不管是Socket還是ServerSocket它們的工作都是通過SocketImpl類及其子類完成的。
          下面是我忍為比較重要的API:
                  1、. Accept方法用于產(chǎn)生"阻塞",直到接受到一個連接,并且返回一個客戶端的Socket對象實例。"阻塞"是一個術(shù)語,它使程序運行暫時"停留"在這個地方,直到一個會話產(chǎn)生,然后程序繼續(xù);通常"阻塞"是由循環(huán)產(chǎn)生的。

            2、. getInputStream方法獲得網(wǎng)絡(luò)連接輸入,同時返回一個InputStream對象實例,。

            3、. getOutputStream方法連接的另一端將得到輸入,同時返回一個OutputStream對象實例。

            注意:其中g(shù)etInputStream和getOutputStream方法均會產(chǎn)生一個IOException,它必須被捕獲,因為它們返回的流對象,通常都會被另一個流對象使用。

            寫代碼時一般先寫server端.
          //Server

          package Killva.NetWorkchaper1.o3;

          import java.io.DataOutputStream;
          import java.io.IOException;
          import java.net.ServerSocket;
          import java.net.Socket;

          public class TestTCPServer {
           public static void main(String args[])throws IOException{
            ServerSocket ss =new ServerSocket(9999);
            while(true){
             System.out.println("--------服務(wù)端已近啟動------------");
                Socket s =ss.accept();
               
                DataOutputStream dos =new DataOutputStream(s.getOutputStream());
               
                System.out.println("客戶端["+s.getInetAddress().getHostAddress()+
                               "  :"+s.getPort()+
                               "]已近鏈接!");
                dos.writeUTF("服務(wù)器端寫入客戶端的數(shù)據(jù):客戶端("+
                         s.getInetAddress().getHostAddress()+
                          "  :"+s.getPort()+
                                  "]已經(jīng)鏈接上服務(wù)器端["+
                                  s.getLocalAddress().getHostName()+
                                  ":"+s.getLocalPort()+
                                  "]!");
               
                dos.flush();
                dos.close();
                s.close();
               
               
            }
           }
           

          }



          Client端

          package Killva.NetWorkchaper1.o3;

          import java.io.DataInputStream;
          import java.io.IOException;
          import java.net.Socket;


          public class TestTCPCLient {
           public static void main(String[] args) throws IOException{
            System.out.println("-------------client端-----------");
            for(long i=0;i<10;i++){
             Socket s =new Socket("192.168.1.*",9999);//IP是用你所在的局域網(wǎng)來測試
             
             DataInputStream dis = new DataInputStream(s.getInputStream());
             System.out.println(""+dis.readUTF());
             dis.close();
             s.close();
            }
           }
          }


          運行結(jié)果真確時服務(wù)器端和客戶端能連接

          感謝閱讀!!!!



          posted @ 2010-11-13 09:51 洛神賦 閱讀(479) | 評論 (0)編輯 收藏

          創(chuàng)建線程有兩種方法:繼承Thread類和實現(xiàn)Runnable接口。
           
          方法一:繼承 Thread 類,覆蓋方法 run(),我們在創(chuàng)建的 Thread 類的子類中重寫 run() ,加入線程所要執(zhí)行的代碼即可。

          a.每個線程都是通過某個特定Thread對象所對應(yīng)的方法run()l來完成其操作的,方法run()成為線程體。

          b.如果想要啟動多線程,則肯定調(diào)用start()方法,start方法可以調(diào)用被子類覆寫過的run方法

          c.不過這種這種實現(xiàn)方式會受到單繼承的局限

          下面是一個例子:
          public class MyThread extends Thread {
          int count= 1, number;
          public MyThread(int num) {
          number = num;
          System.out.println("創(chuàng)建線程 " + number);
          }
          public void run() {
          while(true) {
          System.out.println("線程 " + number + ":計數(shù) " + count);
          if(++count== 6) return;
          }
          }
          public static void main(String args[]) {
          for(int i = 0; i < 5; i++) new MyThread(i+1).start();
          }
          }
           
          方法二:實現(xiàn) Runnable 接口
            Runnable 接口只有一個方法 run(),我們聲明自己的類實現(xiàn) Runnable 接口并提供這一方法,將我們的線程代碼寫入其中,就完成了這一部分的任務(wù)。
          但是 Runnable 接口并沒有任何對線程的支持,我們還必須創(chuàng)建 Thread 類的實例,這一點通過 Thread 類的構(gòu)造函數(shù)public Thread(Runnable target);來實現(xiàn)。

          該實現(xiàn)方式有以下好處:

               適合多個相干同程序代碼的線程去處理同一資源的情況。

               可以避免由于Java單繼承特性帶來的局限。

               有利于程序的健壯性,代碼能夠被多個線程共享。

          下面是一個例子:
          public class MyThread implements Runnable {
          int count= 1, number;
          public MyThread(int num) {
          number = num;
          System.out.println("創(chuàng)建線程 " + number);
          }
          public void run() {
          while(true) {
          System.out.println("線程 " + number + ":計數(shù) " + count);
          if(++count== 6) return;
          } 
          }
          public static void main(String args[]) {
          for(int i = 0; i < 5; i++) new Thread(new MyThread(i+1)).start();
          }
          }
            兩種方法各有千秋,可以靈活運用。





          posted @ 2010-11-08 11:56 洛神賦 閱讀(265) | 評論 (0)編輯 收藏

          Java把內(nèi)存劃分成兩種:一種是棧內(nèi)存,一種是堆內(nèi)存。
              在函數(shù)中定義的一些基本類型的變量和對象的引用變量都在函數(shù)的棧內(nèi)存中分配。
              當在一段代碼塊定義一個變量時,Java就在棧中為這個變量分配內(nèi)存空間,當超過變量的作用域后,Java會自動釋放掉為該變量所分配的內(nèi)存空間,該內(nèi)存空間可以立即被另作他用。
              堆內(nèi)存用來存放由new建立的對象和數(shù)組。
              在堆中分配的內(nèi)存,由Java虛擬機的自動垃圾回收器來管理。
              在堆中產(chǎn)生了一個數(shù)組或?qū)ο蠛螅€可以在棧中定義一個特殊的變量,讓棧中這個變量的取值等于數(shù)組或?qū)ο笤诙褍?nèi)存中的首地址,棧中的這個變量就成了數(shù)組或?qū)ο蟮囊米兞俊?
              引用變量就相當于是為數(shù)組或?qū)ο笃鸬囊粋€名稱,以后就可以在程序中運用棧中的引用變量來訪問堆中的數(shù)組或?qū)ο蟆?
              具體的說:
              棧與堆都是Java用來在Ram中存放數(shù)據(jù)的地點。與C++不同,Java自動管理棧和堆,程序員不能直接地配置棧或堆。
              Java的堆是一個運行時數(shù)據(jù)區(qū),類的(對象從中分配空間。這些對象通過new、newarray、anewarray和multianewarray等 指令建立,它們不須要程序代碼來顯式的釋放。堆是由垃圾回收來負責的,堆的優(yōu)勢是可以動態(tài)地分配內(nèi)存大小,生存期也不必事先告訴編譯器,因為它是在運行時 動態(tài)分配內(nèi)存的,Java的垃圾收集器會自動收走這些不再運用的數(shù)據(jù)。但缺點是,由于要在運行時動態(tài)分配內(nèi)存,存取速度較慢。
              棧的優(yōu)勢是,存取速度比堆要快,僅次于寄存器,棧數(shù)據(jù)可以共享。但缺點是,存在棧中的數(shù)據(jù)大小與生存期必須是確定的,缺乏靈活性。棧中主要存放一些基本 類型的變量(,int, short, long, byte, float, double, boolean, char)和對象句柄。
              棧有一個很主要的特殊性,就是存在棧中的數(shù)據(jù)可以共享。假設(shè)我們同時定義:
              int a = 3;
              int b = 3;
              編譯器先處理int a = 3;首先它會在棧中建立一個變量為a的引用,然后查找棧中能不能有3這個值,如果沒找到,就將3存放進來,然后將a指向3。接著處理int b = 3;在建立完b的引用變量后,因為在棧中已經(jīng)有3這個值,便將b直接指向3。這樣,就出現(xiàn)了a與b同時均指向3的情況。這時,如果再令a=4;那么編譯器 會重新搜索棧中能不能有4值,如果沒有,則將4存放進來,并令a指向4;如果已經(jīng)有了,則直接將a指向這個地址。因此a值的改動不會影響到b的值。要留心這 種數(shù)據(jù)的共享與兩個對象的引用同時指向一個對象的這種共享是不同的,因為這種情況a的修改并不會影響到b, 它是由編譯器完成的,它有利于節(jié)省空間。而一個對象引用變量修改了這個對象的內(nèi)部狀態(tài),會影響到另一個對象引用變量。

           

          String是一個特殊的包裝類數(shù)據(jù)。可以用:
              String str = new String("abc");
              String str = "abc";
              兩種的形式來建立,第一種是用new()來新建對象的,它會在存放于堆中。每調(diào)用一次就會建立一個新的對象。
              而第二種是先在棧中建立一個對String類的對象引用變量str,然后查找棧中有沒有存放"abc",如果沒有,則將"abc"存放進棧,并令str指向“abc”,如果已經(jīng)有“abc” 則直接令str指向“abc”。
              比較類里面的數(shù)值能不能相等時,用equals()要領(lǐng);當測試兩個包裝類的引用能不能指向同一個對象時,用==,下面用例子說明上面的理論。
              String str1 = "abc";
              String str2 = "abc";
              System.out.println(str1==str2); //true可以看出str1和str2是指向同一個對象的。
              String str1 =new String ("abc");
              String str2 =new String ("abc");
              System.out.println(str1==str2); // false用new的方式是生成不同的對象。每一次生成一個。
              因此用第二種方式建立多個“abc”字符串,在內(nèi)存中其實只存在一個對象而已. 這種寫法有利與節(jié)省內(nèi)存空間. 同時它可以在一定程度上提高程序的運行速度,因為JVM會自動根據(jù)棧中數(shù)據(jù)的實際情況來決定能不能有必要建立新對象。而對于String str = new String("abc");的代碼,則一概在堆中建立新對象,而不管其字符串值能不能相等,能不能有必要建立新對象,從而加重了程序的負擔。
              另一方面, 要留心 : 我們在運用諸如String str = "abc";的格式定義類時,總是想當然地認為,建立了String類的對象str。擔心陷阱!對象可能并沒有被建立!而可能只是指向一個先前已經(jīng)建立的 對象。只有通過new()要領(lǐng)才能保證每次都建立一個新的對象。 由于String類的immutable性質(zhì),當String變量須要經(jīng)常變換其值時,應(yīng)該考慮運用 StringBuffer類,以提高程序效率。
              java中內(nèi)存分配策略及堆和棧的比較
              2.1 內(nèi)存分配策略按照編譯原理的觀點,程序運行時的內(nèi)存分配有三種策略,分別是靜態(tài)的,棧式的,和堆式的.靜態(tài)存儲分配是指在編譯時就能確定每個數(shù)據(jù)目標在運行時刻的存儲空間需求,因而在編譯時就可以給他們分配固定的內(nèi)存空間.這種分配策略要求程序代碼中不允 許有可變數(shù)據(jù)結(jié)構(gòu)(比如可變數(shù)組)的存在,也不允許有嵌套或者遞歸的結(jié)構(gòu)出現(xiàn),因為它們都會導(dǎo)致編譯程序不能計算準確的存儲空間需求.棧式存儲分配也可稱為動態(tài)存儲分配,是由一個類似于堆棧的運行棧來實現(xiàn)的.和靜態(tài)存儲分配相反,在棧式存儲方案中,程序?qū)?shù)據(jù)區(qū)的需求在編譯時是完全未知 的,只有到運行的時候才能夠知道,但是規(guī)定在運行中進入一個程序模塊時,必須知道該程序模塊所需的數(shù)據(jù)區(qū)大小才能夠為其分配內(nèi)存.和我們在數(shù)據(jù)結(jié)構(gòu)所熟知 的棧一樣,棧式存儲分配按照先進后出的原則執(zhí)行 分配。

          靜態(tài)存儲分配要求在編譯時能知道所有變量的存儲要求,棧式存儲分配要求在流程的入口處必須知道所有的存儲要求,而堆式存儲分配則專門負責在編譯時或運行時 模塊入口處都不能確定存儲要求的數(shù)據(jù)結(jié)構(gòu)的內(nèi)存分配,比如可變長度串和對象實例.堆由大片的可運用 塊或空閑塊組成,堆中的內(nèi)存可以按照任意順序分配和釋 放.
              2.2 堆和棧的比較
              上面的定義從編譯原理的教材中總結(jié)而來,除靜態(tài)存儲分配之外,都顯得很呆板和難以理解,下面撇開靜態(tài)存儲分配,集中比較堆和棧:從堆和棧的功能和作用來通俗的比較,堆主要用來存放對象的,棧主要是用來執(zhí)行程序的.而這種不同又主要是由于堆和棧的特點決定的:在編程中,例如C/C++中,所有的要領(lǐng)調(diào)用都是通過棧來執(zhí)行 的,所有的局部變量,形式參數(shù)都是從棧中分配內(nèi)存空間的。實際上也不是什么分配,只是從棧頂 向上用就行,就好像工廠中的傳送帶(conveyor belt)一樣,Stack Pointer會自動指引你到放東西的位置,你所要做的只是把東西放下來就行.退出函數(shù)的時候,修改棧指針就可以把棧中的內(nèi)容銷毀.這樣的模式速度最快, 當然要用來運行程序了.須要留心的是,在分配的時候,比如為一個即將要調(diào)用的程序模塊分配數(shù)據(jù)區(qū)時,應(yīng)事先知道這個數(shù)據(jù)區(qū)的大小,也就說是雖然分配是在程 序運行時執(zhí)行 的,但是分配的大小多少是確定的,不變的,而這個"大小多少"是在編譯時確定的,不是在運行時.堆是使用程序在運行的時候請求操作系統(tǒng)分配給自己內(nèi)存,由于從操作系統(tǒng)管理的內(nèi)存分配,所以在分配和銷毀時都要占用時間,因此用堆的效率非常低.但是堆的 優(yōu)點在于,編譯器不必知道要從堆里分配多少存儲空間,也不必知道存儲的數(shù)據(jù)要在堆里停留多長的時間,因此,用堆保存數(shù)據(jù)時會得到更大的靈活性。事實上,面 向?qū)ο蟮亩鄳B(tài)性,堆內(nèi)存分配是必不可少的,因為多態(tài)變量所需的存儲空間只有在運行時建立了對象之后才能確定.在C++中,要求建立一個對象時,只需用 new命令編制有關(guān)的代碼即可。執(zhí)行這些代碼時,會在堆里自動執(zhí)行 數(shù)據(jù)的保存.當然,為達到這種靈活性,必然會付出一定的代價:在堆里分配存儲空間時會花 掉更長的時間!這也正是導(dǎo)致我們剛才所說的效率低的原由 ,看來列寧同志說的好,人的優(yōu)點往往也是人的缺點,人的缺點往往也是人的優(yōu)點.
              2.3 JVM中的堆和棧JVM是基于堆棧的虛擬機.JVM為每個新建立的線程都分配一個堆棧.也就是說,對于一個Java程序來說,它的運行就是通過對堆棧的操作來完成的。堆棧以幀為單位保存線程的狀態(tài)。JVM對堆棧只執(zhí)行 兩種操作:以幀為單位的壓棧和出棧操作。
              我們知道,某個線程正在執(zhí)行的要領(lǐng)稱為此線程的當前要領(lǐng) .我們可能不知道,當前要領(lǐng)運用的幀稱為當前幀。當線程激活一個Java要領(lǐng) ,JVM就會在線程的 Java堆棧里新壓入一個幀。這個幀自然成為了當前幀.在此要領(lǐng)執(zhí)行期間,這個幀將用來保存參數(shù),局部變量,中間計算流程和其他數(shù)據(jù).這個幀在這里和編譯 原理中的活動紀錄的概念是差不多的.從Java的這種分配機制來看,堆棧又可以這樣理解:堆棧(Stack)是操作系統(tǒng)在建立某個進程時或者線程(在支持多線程的操作系統(tǒng)中是線程)為這個線程建立的存儲區(qū)域,該區(qū)域具有先進后出的特征。
          每一個Java使用都唯一對應(yīng)一個JVM實例,每一個實例唯一對應(yīng)一個堆。使用程序在運行中所建立的所有類實例或數(shù)組都放在這個堆中,并由使用所有的線程 共享.跟C/C++不同,Java中分配堆內(nèi)存是自動原始化的。Java中所有對象的存儲空間都是在堆中分配的,但是這個對象的引用卻是在堆棧中分配,也 就是說在建立一個對象時從兩個地點都分配內(nèi)存,在堆中分配的內(nèi)存實際建立這個對象,而在堆棧中分配的內(nèi)存只是一個指向這個堆對象的指針(引用)而已。



          posted @ 2010-11-06 18:14 洛神賦 閱讀(284) | 評論 (0)編輯 收藏

          要求:
                      1、完成一個對水果倉庫管理的簡單系.。
                      2、完成,增加、查詢、修改簡單的操作。
          分析:
                      1、首先我們要有進行分成分析  表層----操作層----底層;
                      2、表層有什么 :可供操作的選項即(增、查、改);
                      3、操作層有什么:完成不同的操作(讀文件和寫文件);
                      4、底層有什么:完成數(shù)據(jù)的寫出和讀入;
          步驟:
          先完成如下javaproject的創(chuàng)建:

          //下面為每個類中的具體內(nèi)容(按我做改程序的順須寫的)
          //Fruit

          package VO;

          import java.io.Serializable;

          @SuppressWarnings("serial")
          public class Fruit implements Serializable {
          //屬性
           private String name;
           private String area;
           private float   kg;
           //構(gòu)造方法
           public Fruit(){}
           public Fruit(String name,String area,float kg){
            this.name =name;
            this.area =area;
            this.kg =kg; 
           }
           
           
           public String getName() {
            return name;
           }
           public void setName(String name) {
            this.name = name;
           }
           public String getArea() {
            return area;
           }
           public void setArea(String area) {
            this.area = area;
           }
           public float getKg() {
            return kg;
           }
           public void setKg(float kg) {
            this.kg = kg;
           }

           public String toString (){
            return "水果名:"+this.name +"  源產(chǎn)地:"+this.area+"  現(xiàn)重量:"+this.kg ;
           }

          }

          //主方法

          package Main;

          import Menu.Menu;

          public class Main {
           //主方法
           public static void main(String[] args){
            System.out.println("簡單的水果倉庫管理系統(tǒng)");
            //調(diào)用Menu方法
            new Menu();
           }
          }

          //Menu

          package Menu;

          import OP.FruitOperate;
          import Util.InputDate;

          public class Menu {
           InputDate input= null;
           public Menu(){
            this.input=new InputDate();
            //循環(huán)出現(xiàn)菜單
            while (true){
             this.show();
            }
           }
           //需要定義的菜單內(nèi)容
           private void show() {
            System.out.println("\t\t\t1、增加水果庫存");   
                  System.out.println("\t\t\t2、瀏覽庫存信息");   
                  System.out.println("\t\t\t3、修改庫存信息");   
                  System.out.println("\t\t\t4、注銷管理系統(tǒng)");   
                  System.out.print("\n\n請選擇您要使用的操作:");   
                  int temp = input.getInt();   
                  switch(temp){   
                  case 1:{  // 增加水果庫存
                          new FruitOperate().add(); //業(yè)務(wù)處理層  
                          break;   
                  }   
                  case 2:{ // 瀏覽庫存信息
                          new FruitOperate().show();   
                          break;   
                  }   
                  case 3:{ // 修改庫存信息
                          new FruitOperate().update();   
                          break;   
                  }   
                  case 4:{ //注銷管理系統(tǒng)
                          System.out.println("注銷中******************");   
                          System.out.println("注銷成功!");   
                          System.exit(1);   
                  }   
                  default:{    //錯誤信息提示
                          System.out.println("請選擇正確的操作范圍如下:");   
                          break;   
                  }   
           
                  }

           }
          }



          //對度入數(shù)據(jù)的相關(guān)操作

          package Util;

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

          public class InputDate {
           
            private BufferedReader buf =null;   
               public InputDate(){   
                       buf = new BufferedReader(new InputStreamReader(System.in));   
               };   
               public String getString(){   
                       String str = null;   
                       try {   
                               str = buf.readLine();   
                       } catch (IOException e) {}   
                       return str;   
               }   
           
            public int getInt(){   
                   int temp = 0;   
                   //如果輸入的不是數(shù)字,告訴用戶輸入錯了~   
                   //可以使用正則驗證   
                   String str = null;   
                   boolean flag = true;   
                   while(flag){   
                           //輸入數(shù)據(jù)   
                           str = this.getString();   
                           if (!(str.matches("\\d+"))){   
                                   //如果輸入的不是一個數(shù)字,則必須重新輸入   
                                   System.out.print("輸入的內(nèi)容必須是上面操作代號的范圍,請重新輸入:");   
                           }else{   
                                   //輸入的是一個正確的數(shù)字,則可以進行轉(zhuǎn)換   
                                   temp = Integer.parseInt(str);   
                                   //表示退出循環(huán)   
                                   flag = false;   
                           }   
                   }   
                   return temp;   
           }
           public float getFloat() {
            
              
                  float f = 0.0f;   
                  //如果輸入的不是數(shù)字,提示告訴用戶輸入錯了~   
                  //可以使用正則驗證   
                  String str = null;   
                  boolean flag = true;   
                  while(flag){   
                          //輸入數(shù)據(jù)   
                          str = this.getString();   
                          if (!(str.matches("\\d+?.\\d{1,2}"))){   
                                  //如果輸入的不是一個數(shù)字,則必須重新輸入   
                                  System.out.print("輸入的內(nèi)容必須是小數(shù)(小數(shù)點后兩位),請重新輸入:");   
                          }else{   
                                  //輸入的是一個正確的數(shù)字,則可以進行轉(zhuǎn)換   
                                  f = Float.parseFloat(str);   
                                  //表示退出循環(huán)   
                                  flag = false;   
                          }   
                  }   
                  return f;   

          }
           
          }

          ///實現(xiàn)管理的方法類

          package OP;

          import Util.FileOperate;
          import Util.InputDate;
          import VO.Fruit;

          public class FruitOperate {
             private InputDate input = null;   
                public FruitOperate(){   
                        this.input = new InputDate();   
                }   
                //完成具體的Fruit對象操作   
                public void add(){   
                        //要使用輸入數(shù)據(jù)的類   
                        String name = null;   
                        String area = null;   
                        float kg = 0.0f;   
                        System.out.print("輸入水果名:");   
                        name = this.input.getString();   
                        System.out.print("輸入源產(chǎn)地:");   
                        area = this.input.getString();                                
                        System.out.print("輸入入庫量:");
                        kg = this.input.getFloat();
                        //生成Fruit對象,把對象保存在文件中   
                        Fruit f = new Fruit(name,area,kg);   
                                  
                        try{   
                                new FileOperate().save(f);    //io操作層
                                System.out.println("數(shù)據(jù)保存成功!");   
                        }catch(Exception e){   
                                System.out.println("數(shù)據(jù)保存失敗!");   
                        }   
                }   
                public void show(){   
                        //從文件中把內(nèi)容讀進來   
                 Fruit f = null;   
                        try{   
                                f = (Fruit) new FileOperate().read();   
                        }catch(Exception e){   
                                System.out.println("內(nèi)容顯示失敗,請確定數(shù)據(jù)是否存在!");   
                        }   
                        if(f != null){   
                                System.out.println(f);   
                        }   
                }   
                public void update(){   
                        //先將之前的信息查出來   
                 Fruit f = null;   
                        try{   
                                f = (Fruit) new FileOperate().read();   
                        }catch(Exception e){   
                                System.out.println("內(nèi)容顯示失敗,請確定數(shù)據(jù)是否存在!");   
                        }   
                        if(f != null){   
                                String name = null;   
                                String area = null;   
                                float kg =0.0f;   
                                System.out.print("請輸入新的水果名(原水果名:"+f.getName()+")");   
                                name = this.input.getString();   
                                System.out.print("請輸入新的源產(chǎn)地(原源產(chǎn)地:"+f.getArea()+")");   
                                area = this.input.getString();   
                                System.out.print("請輸入新的庫總量(原庫總量:"+f.getKg()+")");   
                                kg = this.input.getFloat(); 
                               
                                //信息重新設(shè)置   
                                f.setName(name);   
                                f.setArea(area);   
                                f.setKg(kg);   
                                try{   
                                        new FileOperate().save(f);   
                                        System.out.println("數(shù)據(jù)更新成功!");   
                                }catch(Exception e){   
                                        System.out.println("數(shù)據(jù)更新失敗!");   
                                }   
                        }   
                }   

          }

          //底層操作  文件的讀入和讀出

          package Util;

          import java.io.File;
          import java.io.FileInputStream;
          import java.io.FileOutputStream;
          import java.io.ObjectInputStream;
          import java.io.ObjectOutputStream;

          public class FileOperate {
           public static final String FILENAME = "E:\\fruit.txt";   
              //把對象保存在文件之中   
              public void save(Object obj){   
                      ObjectOutputStream out = null;   
                      try {   
                              out = new ObjectOutputStream(new FileOutputStream(new File(FILENAME)));   
                              //寫入對象   
                              out.writeObject(obj);   
                      }catch(Exception e){   
                              try {   
                                      throw e;   
                              } catch (Exception e1) {}   
                      }finally {   
                              try {   
                                      out.close();   
                              }catch(Exception e){}   
                      }   
              }   
             
              //把對象從文件之中讀出來   
              public Object read() throws Exception{   
                      Object obj = null;   
                      ObjectInputStream input =null;   
                      try {   
                              input = new ObjectInputStream(new FileInputStream(new File(FILENAME)));   
                              obj = input.readObject();   
                      } catch (Exception e) {   
                              throw e;   
                      }finally{   
                              try{   
                                      input.close();                                
                              }catch(Exception e){}   
                      }   
                      return obj;   
              }   

          }

          運行結(jié)果如下:





          這篇文章只是一個原理  ,感謝閱讀  希望能夠提供寶貴意見!QQ:237333696


















          posted @ 2010-11-06 16:51 洛神賦 閱讀(1529) | 評論 (0)編輯 收藏

          主站蜘蛛池模板: 筠连县| 新河县| 义乌市| 金昌市| 潼南县| 舞阳县| 托克逊县| 方城县| 洛南县| 卢氏县| 水富县| 南汇区| 阜阳市| 莱阳市| 卢湾区| 卫辉市| 宁津县| 宜川县| 佛坪县| 广元市| 罗源县| 庆云县| 临桂县| 石台县| 收藏| 南川市| 漳州市| 凉山| 新安县| 探索| 瑞安市| 习水县| 台北市| 清水河县| 汕尾市| 青龙| 荃湾区| 大埔区| 尚志市| 鹤山市| 当雄县|