20189230楊 2018-2019-2 《移動平臺開發實踐》第5周學習總結

學習《Java和Android開發學習指南(第二版)》第1六、1九、20、22章——

第16章輸入/輸出
1.I/O操做的例子包括:
(1)建立和刪除文件。
(2)從一個文件或網絡套接字讀取內容,或向其寫入內容。
(3)把對象序列化(或保存)到持久存儲中,而且獲取保存的對象。
16.1文件系統和路徑
1.文件系統能夠包含三種類型的對象:文件、目錄(也叫做文件夾)和符號連接。
2.文件系統中的一個對象,能夠經過路徑來惟一地標識。路徑能夠是絕對的或者相對的。絕對路徑擁有指向文件系統中的一個對象的全部信息,相對路徑並無所須要的全部信息。在Java中,一個文件或路徑是由一個java.io.File對象來表示的。
16.2 文件和目錄的處理和操做
1.Files類中的read和write方法只是適用於比較小的文件。對於中等大小和較大的文件來講,使用流來代替。
16.3 輸入、輸出流
1.Java I/O流將Java代碼和一個「數據水池」鏈接起來。這個「數據水池」叫作池,它多是一個文件、一個網絡套接字或者內存。
16.4 讀二進制數據
1.當可用的字節數比數組的大小要小時,可使用重載的read方法返回讀取的字節數。
2.代碼清單16.1 使用InputStream的compareFiles方法java

package app16;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class InputStreamDemo1{
    public boolean compareFiles(Path path1,Path path2)
            throws NoSuchFileException{
        if(Files.notExists(path1)){
            throw new NoSuchFileException(path1.toString());
        }
        if(Files.notExists(path2)){
            throw new NoSuchFileException(path2.toString());
        }
        try{
            if(Files.size(path1)!=Files.size(path2)){
                return false;
            }
        }catch(IOException e){
            e.printStackTrace();
        }
        try(InputStream inputStream1=Files.newInputStream(
                path1,StandardOpenOption.READ);
            InputStream inputStream2=Files.newInputStream(
                    path2,StandardOpenOption.READ)){
            int i1,i2;
            do{
                i1=inputStream1.read();
                i2=inputStream2.read();
                if(i1!=i2){
                    return false;
                }
            }while(i1!=-1);
            return true;
        }catch(IOException e){
            return false;
        }
    }
    public static void main(String[] args){
        Path path1=Paths.get("C:\\Users\\yangxiaopang\\Desktop\\py4e\\ex_02_03\\code3\\addtwo.py");
        Path path2=Paths.get("C:\\Users\\yangxiaopang\\Desktop\\py4e\\ex_02_03\\code3\\addtwo.py");
        InputStreamDemo1 test=new InputStreamDemo1();
        try{
            if(test.compareFiles(path1,path2)){
                System.out.println("Files are identical");
            }else{
                System.out.println("Files are not identical");
            }
        }catch(NoSuchFileException e){
            e.printStackTrace();
        }
        try{
            System.out.println(Files.isSameFile(path1,path2));
        }catch(IOException e){
            e.printStackTrace();
        }
    }
}

16.5 寫二進制數據
1.代碼清單16.2 OutputStreamDemo1類android

package app16;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class OutputStreamDemo1{
    public void copyFiles(Path originPath,Path destinationPath)
            throws IOException{
        if(Files.notExists(originPath)
                ||Files.exists(destinationPath)){
            throw new IOException(
                    "Origin file must exist and"+
                            "Destination file must not exist");
        }
        byte[] readData=new byte[1024];
        try(InputStream inputStream=
                    Files.newInputStream(originPath,
                            StandardOpenOption.READ);
            OutputStream outputStream=
                    Files.newOutputStream(destinationPath,
                            StandardOpenOption.CREATE)){
            int i=inputStream.read(readData);
            while(i!=-1){
                outputStream.write(readData,0,i);
                i=inputStream.read(readData);
            }
        }catch(IOException e){
            throw e;
        }
    }
    public static void main(String[] args){
        OutputStreamDemo1 test=new OutputStreamDemo1();
        Path origin=Paths.get("C:\\Users\\yangxiaopang\\Desktop\\py4e\\ex_02_03\\code3\\Origin.py");
        Path destination=Paths.get("C:\\Users\\yangxiaopang\\Desktop\\py4e\\ex_02_03\\code3\\Destination.py");
        try{
            test.copyFiles(origin,destination);
            System.out.println("Copied Successfully");
        }catch(IOException e){
            e.printStackTrace();
        }
    }
}

16.6.2 OutputStreamWriter
1.寫入到一個OutputStreamWriter的字符,使用一個指定的字符集編碼爲字節。
2.代碼清單16.3 使用OutputStreamWritergit

package app16;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class OutputStreamWriterDemo1{
    public static void main(String[] args){
        char[] chars=new char[2];
        chars[0]='\u4F60';//representing 你
        chars[1]='\u597D';//representing 我
        Path path=Paths.get("C:\\Users\\yangxiaopang\\Desktop\\py4e\\ex_02_03\\code3\\Origin.py");
        Charset chineseSimplifiedCharset=
                Charset.forName("GB2312");
        try(OutputStream outputStream=
                    Files.newOutputStream(path,
                            StandardOpenOption.CREATE);
            OutputStreamWriter writer=new OutputStreamWriter(
                    outputStream,chineseSimplifiedCharset)){

            writer.write(chars);
        }catch(IOException e){
            e.printStackTrace();
        }
    }
}

16.6.3 PrintWriter程序員

package app16;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class PrintWriterDemo1{
    public static void main(String[] args){
        Path path=Paths.get("C:\\Users\\yangxiaopang\\Desktop\\py4e\\ex_02_03\\code3\\Origin.py");
        Charset usAsciiCharset=Charset.forName("US-ASCII");
        try(BufferedWriter bufferedWriter=
                    Files.newBufferedWriter(path,usAsciiCharset,
                            StandardOpenOption.CREATE);
            PrintWriter printWriter=
                    new PrintWriter(bufferedWriter)){
            printWriter.println("PrintWriter is easy to use.");
            printWriter.println(1234);
        }catch(IOException e){
            e.printStackTrace();
        }
    }
}

16.7.3 BufferedReader
1.有兩點好處:
(1)包裝另外一個Reader,而且提供一個緩存,這將會廣泛提升性能。
(2)提供另外一個readLine方法來讀取一行文本。web

package app16;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class PrintStreamDemo1{
    public static void main(String[] args){
        Path debugFile=Paths.get("C:\\Users\\yangxiaopang\\Desktop\\py4e\\ex_02_03\\code3\\Origin.py");
        try(OutputStream outputStream=Files.newOutputStream(
            debugFile,StandardOpenOption.CREATE,
            StandardOpenOption.APPEND);
            PrintStream printStream=new PrintStream(outputStream,
            true)){
             System.setOut(printStream);
             System.out.println("To file");
            }catch(IOException e){
                     e.printStackTrace();
                 }
    }
}

16.9 隨機訪問文件
1.代碼清單16.8 隨機訪問文件算法

package app16;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class SeekableByteChannelDemo1{
    public static void main(String[] args){
        ByteBuffer buffer=ByteBuffer.allocate(12);
        System.out.println(buffer.position());
        buffer.putInt(10);
        System.out.println(buffer.position());
        buffer.putLong(1234567890L);
        System.out.println(buffer.position());
        buffer.rewind();
        System.out.println(buffer.getInt());
        System.out.println(buffer.getLong());
        buffer.rewind();
        System.out.println(buffer.position());

        Path path=Paths.get("C:\\Users\\yangxiaopang\\Desktop\\py4e\\ex_02_03\\code3\\Origin.py");
        System.out.println("-----------------");
        try(SeekableByteChannel byteChannel=
                    Files.newByteChannel(path,
                            StandardOpenOption.CREATE,
                            StandardOpenOption.READ,
                            StandardOpenOption.WRITE);){
            System.out.println(byteChannel.position());
            byteChannel.write(buffer);
            System.out.println(byteChannel.position());


            //read file
            ByteBuffer buffer3=ByteBuffer.allocate(40);
            byteChannel.position(0);
            byteChannel.read(buffer3);
            buffer3.rewind();
            System.out.println("get int:"+buffer3.getInt());
            System.out.println("gey long:"+buffer3.getLong());
            System.out.println(buffer3.getChar());
        }catch(IOException e){
            e.printStackTrace();
        }
    }
}

16.10 對象序列化
1.有時咱們須要將對象持久化到一個永久性存儲中,以便之後可以保持並獲取對象的狀態。對象序列化是一種基於後進先出的方法。當序列化多個基本類型/對象的時候,先序列化的對象最後必須解序列化。
2.代碼清單16.9 Customer類數據庫

package app16;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class ObjectSerializationDemo1{
    public static void main(String[] args){
        Path path=Paths.get("C:\\Users\\yangxiaopang\\Desktop\\py4e\\ex_02_03\\code3\\Origin.py");
        Customer customer=new Customer(1,"Joe Blog",
                 "12 West Cost");
        try(OutputStream outputStream=
            Files.newOutputStream(path,
                StandardOpenOption.CREATE);
            ObjectOutputStream oos=new
                ObjectOutputStream(outputStream)){
    //write first object
    oos.writeObject(customer);
    //write second object
    oos.writeObject("Customer info");
                }catch(IOException e){
                System.out.println("IOException");
                }
            //Deserialize
        try(InputStream inputStream=Files.newInputStream(path,
            StandardOpenOption.READ);
            ObjectInputStream ois=new
                ObjectInputStream(inputStream)){
                //read first object
             Customer customer2=(Customer)ois.readObject();
             System.out.println("First Object:");
             System.out.println(customer2.id);
             System.out.println(customer.name);
             System.out.println(customer.address);

            //read second Object
            System.out.println();
            System.out.println("Second object:");
            String info=(String) ois.readObject();
            System.out.println(info);
                }catch(ClassNotFoundException ex){//readObject still throws this exception
                        System.out.print("ClassNotFound"+ex.getMessage());                
                }catch(IOException ex2){
                    System.out.print("IOException"+ex2.getMessage());
                }
    }
}

代碼清單16.10 對象序列化示例編程

package app16;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class ObjectSerializationDemo1{
    public static void main(String[] args){
        Path path=Paths.get("C:\\Users\\yangxiaopang\\Desktop\\py4e\\ex_02_03\\code3\\Origin.py");
        Customer customer=new Customer(1,"Joe Blog",
                "12 West Cost");
        try(OutputStream outputStream=
                    Files.newOutputStream(path,
                            StandardOpenOption.CREATE);
            ObjectOutputStream oos=new
                    ObjectOutputStream(outputStream)){
            //write first object
            oos.writeObject(customer);
            //write second object
            oos.writeObject("Customer info");
        }catch(IOException e){
            System.out.println("IOException");
        }
        //Deserialize
        try(InputStream inputStream=Files.newInputStream(path,
                StandardOpenOption.READ);
            ObjectInputStream ois=new
                    ObjectInputStream(inputStream)){
            //read first object
            Customer customer2=(Customer)ois.readObject();
            System.out.println("First Object:");
            System.out.println(customer2.id);
            System.out.println(customer.name);
            System.out.println(customer.address);

            //read second Object
            System.out.println();
            System.out.println("Second object:");
            String info=(String) ois.readObject();
            System.out.println(info);
        }catch(ClassNotFoundException ex){//readObject still throws this exception
            System.out.print("ClassNotFound"+ex.getMessage());
        }catch(IOException ex2){
            System.out.print("IOException"+ex2.getMessage());
        }
    }
}

16.11 本章小結
輸入/輸出操做在整個java.io包的成員中都獲得了支持。能夠經過流來讀取和寫入數據,而數據分爲二進制數據和文本兩種。此外,Java支持經過Serializable接口以及ObjectInputStream和ObjectOutputStream類進行對象序列化。數組

第19章線程
19.1 Java線程簡介
線程是一個基本的處理單元操做系統分配處理時間就是按照線程來進行的,在一個進程中,能夠有多個線程執行代碼。線程有時候也叫作一個輕量級的進程,或者叫作一個執行環境。線程要消費資源。
19.2 建立一個線程
建立一個線程的方法有兩種。
1.擴展java.lang.Thread類。
2.實現java.lang.Runnable接口。
19.2.1 擴展線程
1.代碼清單19.1 一個簡單的多線程程序

package app19;
public class ThreadDemo1 extends Thread{
    public void run(){
        for (int i=1;i<=10;i++){
            System.out.println(i);
            try{
                sleep(1000);
            }catch(InterruptedException e){
            }
        }
    }
    public static void main(String[] args){
        (new ThreadDemo1()).start();
    }
}

2.代碼清單19.2 使用擴展了Thread的另外一個類

package app19;
class MyThread extends Thread{
    public void run(){
        for(int i=1;i<=10;i++){
            System.out.println(i);
            try{
                sleep(1000);
            }catch(InterruptedException e){
            }
        }
    }
}
public class ThreadDemo2{
    public static void main(String[] args){
        MyThread thread=new MyThread();
        thread.start();
    }
}

19.2.2 實現Runnable
1.代碼清單19.3 使用Runnable

package app19;
public class RunnableDemo1 implements Runnable{
    public void run(){
        for(int i=1;i<10;i++){
            System.out.println(i);
            try{
                Thread.sleep(1000);
            }catch(InterruptedException e){
            }
        }
    }
public static void main(String[] args){
    RunnableDemo1 demo=new RunnableDemo1();
    Thread thread=new Thread(demo);
    thread.start();
}
}

19.3 使用多線程
1.代碼清單19.4 使用兩個線程

package app19;
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class ThreadDemo3 extends JFrame{
    JLabel countUpLabel=new JLabel("Count Up");
    JLabel countDownLabel=new JLabel("Count Down");

    class CountUpThread extends Thread{
        public void run(){
            int count=1000;
            while(true){
                try{
                    sleep(100);
                }catch(InterruptedException e){
                }
                if(count==0)
                    count=1000;
                countUpLabel.setText(Integer.toString(count--));
            }
        }
    }
    class countDownThread extends Thread{
        public void run(){
            int count=0;
            while(true){
                try{
                    sleep(50);
                }catch(InterruptedException e){
                }
                if(count==1000)
                count=0;
                countDownLabel.setText(Integer.toString(count++));
            }
        }
    }
    public ThreadDemo3(String title){
        super(title);
        init();
    }
private void init(){
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.getContentPane().setLayout(new FlowLayout());
    this.add(countUpLabel);
    this.add(countDownLabel);
    this.pack();
    this.setVisible(true);
    new CountUpThread().start();
    new countDownThread().start();
}
public static void constructGUI(){
    JFrame.setDefaultLookAndFeelDecorated(true);
    ThreadDemo3 frame=new ThreadDemo3("Thread Demo 3");
    
}
public static void main(String[] args){
javax.swing.SwingUtilities.invokeLater(new Runnable(){
    public void run(){
    constructGUI();
    }
});
}
}

19.4 線程優先級
1.代碼清單19.5 測試線程優先級

package app19;
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class ThreadPriorityDemo extends JFrame{
    JLabel counter1Label=new JLabel("Priority 10");
    JLabel counter2Label=new JLabel("Priority 1");
    class CounterThread extends Thread{
        JLabel counterLabel;
        public CounterThread(JLabel counterLabel){
            super();
            this.counterLabel=counterLabel;
        }
        public void run(){
            int count=0;
            while(true){
                try{
                    sleep(1);
                }catch(InterruptedException e){
                }
                if(count==50000)
                    count=0;
                counterLabel.setText(Integer.toString(count++));
            }
        }
    }
    public ThreadPriorityDemo(String title){
        super(title);
        init();
    }
    private void init(){
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLayout(new FlowLayout());
        this.add(counter1Label);
        this.add(counter2Label);
        this.pack();
        this.setVisible(true);
        CounterThread thread1=new CounterThread(counter1Label);
        thread1.setPriority(10);
        CounterThread thread2=new CounterThread(counter2Label);
        thread2.setPriority(1);
        thread2.start();
        thread1.start();
    }
    private static void constructGUI(){
        JFrame.setDefaultLookAndFeelDecorated(true);
        ThreadPriorityDemo frame=new ThreadPriorityDemo(
                "Thread Priority Demo");
    }
    public static void main(String[] args){
        javax.swing.SwingUtilities.invokeLater(new Runnable(){
            public void run(){
                constructGUI();
            }
        });
    }
}

19.5 中止線程
1.代碼清單19.6 中止一個線程

package app19;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class StopThreadDemo extends JFrame{
    JLabel counterLabel=new JLabel("Counter");
    JButton startButton=new JButton("Start");
    JButton stopButton=new JButton("Stop");
    CounterThread thread=null;
    boolean stopped=false;
    int count=1;
    class CounterThread extends Thread{
        public void run(){
            while(!stopped){
                try{
                    sleep(10);
                }catch(InterruptedException e){
                }
                if(count==1000){
                    count=1;
                }
                counterLabel.setText(Integer.toString(count++));
            }
        }
    }
    public StopThreadDemo(String title){
        super(title);
        init();
    }
    private void init(){
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.getContentPane().setLayout(new FlowLayout());
        this.stopButton.setEnabled(false);
        startButton.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                StopThreadDemo.this.startButton.setEnabled(true);
                StopThreadDemo.this.stopButton.setEnabled(false);
                stopThread();
            }
        });
        this.getContentPane().add(counterLabel);
        this.getContentPane().add(startButton);
        this.getContentPane().add(stopButton);
        this.pack();
        this.setVisible(true);
    }
    public synchronized void startThread(){
        stopped=false;
        thread=new CounterThread();
        thread.start();
    }
    public synchronized void stopThread(){
        stopped=true;
    }
    private static void constructGUI(){
        JFrame.setDefaultLookAndFeelDecorated(true);
        StopThreadDemo frame=new StopThreadDemo(
                "Stop Thread Demo");
    }
    public static void main(String[] args){
        javax.swing.SwingUtilities.invokeLater(new Runnable(){
            public void run(){
                constructGUI();
            }
        });
    }
}

19.7 可見性
1.代碼清單19.10 Consistent類

package app19;
public class Consistent{
    static boolean started=false;

    public synchronized static void setStarted(){
        started=true;
    }

    public synchronized static boolean getStarted(){
        return started;
    }

    public static void main(String[] args){
        Thread thread1=new Thread(new Runnable(){
            public void run(){
                try{
                    Thread.sleep(3000);
                }catch(InterruptedException e){
                }
                setStarted();
                System.out.println("started set to true");
            }
        });
        thread1.start();
        while(!getStarted()){
            //wait until started
        }
        System.out.println("Wait 3 seconds and exit");
    }
}

19.8 線程協調
1.代碼清單19.12 DeliveryNoteHolder類

package app19;
public class DeliveryNoteHolder{
    private String deliveryNote;
    private boolean available=false;

    public synchronized String get(){
        while(available==false){
            try{
                wait();
            }catch(InterruptedException e){}
        }
        available=false;
        System.out.println(System.currentTimeMillis()
            +":got"+deliveryNote);
        notifyAll();
        return deliveryNote;
    }
    public synchronized void put(String deliveryNote){
        while(available==true){
            try{
                wait();
            }catch (InterruptedException e){}
        }
        this.deliveryNote=deliveryNote;
        available=true;
        System.out.println(System.currentTimeMillis()+
        ":Put"+deliveryNote);
        notifyAll();
    }
}

2.代碼清單19.13 DispatcherThread類

package app19;
public class DispatcherThread extends Thread{
    private DeliveryNoteHolder deliveryNoteHolder;

    String[] deliveryNotes={"XY23.1234 Arnie Rd.",
            "XY24.3330 Quebec St.",
            "XY25.909 Swenson Ave.",
            "XY26.4830 Davidson Blvd.",
            "XY27.9900 Old York Dr."};
    public DispatcherThread(DeliveryNoteHolder holder){
        deliveryNoteHolder=holder;
    }
    public void run(){
        for(int i=0;i<deliveryNotes.length;i++){
            String deliveryNote=deliveryNotes[i];
            deliveryNoteHolder.put(deliveryNote);
            try{
                sleep(100);
            }catch(InterruptedException e){
            }
        }
    }
}

3.代碼清單19.14 DriverThread類

package app19;
public class DriverThread extends Thread{
    DeliveryNoteHolder deliveryNoteHolder;
    boolean stopped=false;
    String driverName;

    public DriverThread(DeliveryNoteHolder holder,String
            driverName){
        deliveryNoteHolder=holder;
        this.driverName=driverName;
    }
    public void run(){
        while(!stopped){
            String deliveryNote=deliveryNoteHolder.get();
            try{
                sleep(300);
            }catch(InterruptedException e){
            }
        }
    }
}

4.代碼清單19.15 ThreadCoordinationDemo類

package app19;
public class ThreadCoordinationDemo{
    public static void main(String[] args){
        DeliveryNoteHolder c=new DeliveryNoteHolder();
        DispatcherThread dispatcherThread=
            new DispatcherThread(c);
        DriverThread driverThread1=new DriverThread(c,"Eddie");
        dispatcherThread.start();
        driverThread1.start();
    }
}

19.9 使用定時器
1.代碼清單19.16 使用Timer

package app19;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;

public class TimerDemo extends JFrame{
    String[] questions={"What is the largest mammal?",
    "Who is the current prime minister of Japan?",
    "Who invented the Internet?",
    "What is the smallest country in the world?",
    "What is the biggest city in America?",
    "Finished.Please remain seated"};;

JLabel questionLabel=new JLabel("Click Start to begin");
JTextField answer=new JTextField();
JButton startButton=new JComboBox();
JComboBox answerBox=new JComboBox();
int counter=0;
Timer timer=new Timer();
public TimerDemo(String title){
    super(title);
    init();
}
private void init(){
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.getContentPane().setLayout(new BorderLayout());
    this.getContentPane().add(questionLabel,BorderLayout.WEST);
    questionLabel.setPreferredSize(new Dimension(300,15));
    answer.setPreferredSize(new Dimension(100,15));
    this.getContentPane().add(answer.BorderLayout.CENTER);
    this.getContentPane().add(startButton,BorderLayout.EAST);
    startButton.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e){
             ((JButton) e.getSource()).setEnabled(false);
             timer.schedule(
                 new DisplayQuestionTask(),0,10*1000);
        }
    });
    this.getContentPane().add(answerBox,BorderLayout.SOUTH);
    this.startButton.setFocusable(true);
    this.pack();
    this.setVisible(true);
}
private String getNextQuestion(){
    return questions[counter++];
}
private static void constructGUI(){
    JFrame.setDefaultLookAndFeelDecorated(true);
    TimerDemo frame=new TimerDemo("Timer Demo");
}
public static void main(String[] args){
    javax.swing.SwingUtilities.invokeLater(new Runnable(){
        public void run(){
            constructGUI();
        }
    });
}
class DisplayQuestionTask extends TimerTask{
    public void run(){
    Toolkit.getDefaultToolkit().beep();
    if(counter>0){
        answerBox.addItem(answer.getText());
        answer.setText("");
    }
    String NextQuestion=getNextQuestion();
    questionLabel.setText(nextQuestion);
    if(counter==questions.length){
        timer.cancel();
    }
    }
}
}

第20章併發工具
20.2 Executor和ExecutorService
1.代碼清單20.2 ImageSearcher類

package app20.imagesearcher;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;

public class ImageSearcher extends JFrame
        implements ActionListener{
    public static final int MAX_RESULT=300;
    JButton searchButton=new JButton("Search");
    DefaultListModel listModel;
    JList imageList;
    Executor executor=Executors.newFixedThreadPool(10);
    AtomicInteger fileCounter=new AtomicInteger(1);

    public ImageSearcher(String title){
        super(title);
        init();
    }
    private void init(){
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLayout(new BorderLayout());
        this.add(searchButton,BorderLayout.NORTH);
        listModel=new DefaultListModel();
        imageList=new JList(listModel);
        this.add(new JScrollPane(imageList),BorderLayout.CENTER);
        this.pack();
        this.setSize(800,650);
        searchButton.addActionListener(this);
        this.setVisible(true);
        //center frame
        this.setLocationRelativeTo(null);
    }
    private static void constructGUI(){
        JFrame.setDefaultLookAndFeelDecorated(true);
        ImageSearcher frame=new ImageSearcher("Image Searcher");
    }
    public void actionPerformed(ActionEvent e){
        Iterable<Path>roots=
                FileSystems.getDefault().getRootDirectories();
        for(Path root:roots){
            executor.execute(new ImageSearcherTask(root,executor,
                    listModel,fileCounter));
        }
    }
    public static void main(String[] args){
        javax.swing.SwingUtilities.invokeLater(new Runnable(){
            public void run(){
                constructGUI();
            }
        });
    }
}

2.代碼清單20.3 ImageSearchTask類

package app20.imagesearcher;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger;
import javax.swing.DefaultListModel;
import javax.swing.SwingUtilities;

public class ImageSearcherTask implements Runnable{
    private Path searchDir;
    private Executor executor;
    private DefaultListModel listModel;
    private AtomicInteger fileCounter;

    public  ImageSearcherTask(Path searchDir,Executor executor,DefaultListModel listModel,
                              AtomicInteger fileCounter){
        this.searchDir=searchDir;
        this.executor=executor;
        this.listModel=listModel;
        this.fileCounter=fileCounter;
    }
    @Override
    public void run(){
        if(fileCounter.get()>ImageSearcher.MAX_RESULT){
            return;
        }
        try(DirectoryStream<Path>children=
                    Files.newDirectoryStream(searchDir)){
            for(final Path child:children){
                if(Files.isDirectory(child)){
                    executor.execute(new ImageSearcherTask(child,
                            executor,listModel,fileCounter));
                }else if(Files.isRegularFile(child)){
                    String name=child.getFileName()
                            .toString().toLowerCase();
                    if(name.endsWith(".jpg")){
                        final int fileNumber=
                                fileCounter.getAndIncrement();
                        if(fileNumber>ImageSearcher.MAX_RESULT){
                            break;
                        }
                        SwingUtilities.invokeLater(new Runnable(){
                            public void run(){
                                listModel.addElement(fileNumber+
                                        ":"+child);
                            }
                        });
                    }
                }
            }
        }catch(IOException e){
            System.out.println(e.getMessage());
        }
    }
}

20.3 Callable和Future
1.代碼清單20.4 FileCountTask類

package app20.filecounter;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;

public class FileCountTask implements Callable{
    Path dir;
    long fileCount=0L;
    public FileCountTask(Path dir){
        this.dir=dir;
    }
    private void doCount(Path parent){
        if(Files.notExists(parent)){
            return;
        }
        try(DirectoryStream<Path> children=
                    Files.newDirectoryStream(parent)){
            for(Path child:children){
            if(Files.isDirectory(child)){
                doCount(child);
            }else if(Files.isRegularFile(child)){
                fileCount++;
            }
        }
    }catch(IOException e){
        e.printStackTrace();
    }
}
    @Override
    public Long call() throws Exception{
        System.out.println("Start counting"+dir);
        doCount(dir);
        System.out.println("Finished counting"+dir);
        return fileCount;
    }
}

2.代碼清單20.5 FileCounter類

package app20.filecounter;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class FileCounter{
    public static void main(String[] args){
        Path[] dirs={
                Paths.get("C:\\Users\\yangxiaopang\\Desktop\\py4e\\ex_02_03"),
                Paths.get("C:\\Users\\yangxiaopang\\Desktop\\py4e")
        };
        ExecutorService executorService=
                Executors.newFixedThreadPool(dirs.length);

        Future<Long>[] results=new Future[dirs.length];
        for(int i=0;i<dirs.length;i++){
            Path dir=dirs[i];
            FileCountTask task=new FileCountTask(dir);
            results[i]=executorService.submit(task);
        }
        //print result
        for(int i=0;i<dirs.length;i++){
            long fileCount=0L;
            try{
                fileCount=results[i].get();
            }catch(InterruptedException | ExecutionException ex){
                ex.printStackTrace();
            }
            System.out.println(dirs[i]+"contains"
                    +fileCount+"files.");
        }
        executorService.shutdownNow();
    }
}

第21章網絡
22.2 超文本傳輸協議(HTTP)
1.HTTP是容許Web服務器和瀏覽器之間經過互聯網發送和接收數據的協議。它是一種請求和響應協議。HTTP使用可靠的TCP鏈接,默認是80端口上的TCP。
2.在HTTP中,老是由客戶端先創建一個鏈接併發送一個HTTP請求,從而發起一次事務。Web服務器老是被動地響應客戶端,或者對客戶端進行一次回調鏈接。
22.2.1 HTTP請求
包含三個部分:方法——統一資源標識符(URI)——協議/版本;請求頭;請求實體。統一資源定位符(URL)其實是一種類型的URI。
22.2.2 HTTP響應
包含三個部分:協議-狀態碼-說明;響應頭;響應實體。
22.3.1 解析URL
1.代碼清單22.1 解析URL

package app22;
import java.net.URL;

public class URLDemo1{
    public static void main(String[] args)throws Exception{
    URL url=new URL(
    "http://www.yahoo.com:80/en/index.html?name=john#first");
    System.out.println("protocol:"+url.getProtocol());
    System.out.println("port:"+url.getPort());
    System.out.println("host:"+url.getHost());
    System.out.println("path:"+url.getPath());
    System.out.println("file:"+url.getFile());
    System.out.println("query:"+url.getQuery());
    System.out.println("ref:"+url.getRef());
    }
}

22.4.1 讀Web資源
1.代碼清單22.3 讀取一個Web資源的頭部和內容

package app22;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class URLConnectionDemo1{
    public static void main(String[] args){
        try{
            URL url=new URL("http://www.java.com/");
            URLConnection urlConnection=url.openConnection();
            Map<String,List<String>>headers=
                    urlConnection.getHeaderFields();
            Set<Map.Entry<String,List<String>>>entrySet=
                    headers.entrySet();
            for(Map.Entry<String,List<String>>entry:entrySet){
                String headerName=entry.getKey();
                System.out.println("Header Name:"+headerName);
                List<String>headerValues=entry.getValue();
                for(String value:headerValues){
                    System.out.print("Header value:"+value);
                }
                System.out.println();
                System.out.println();
            }
            InputStream inputStream=
                    urlConnection.getInputStream();
            BufferedReader bufferedReader=new BufferedReader(
                    new InputStreamReader(inputStream));
            String line=bufferedReader.readLine();
            while(line!=null){
                System.out.println(line);
                line=bufferedReader.readLine();
            }
            bufferedReader.close();
        }catch(MalformedURLException e){
            e.printStackTrace();
        }catch(IOException e){
            e.printStackTrace();
        }
    }
}

22.5 java.net.Socket
套接字是一個網絡鏈接的端點。
22.7 一個Web服務器應用程序
22.7.1 HttpServer類
1.代碼清單22.5 HttpServer類

package app22.app22.webserver;
import java.net.Socket;
import java.net.ServerSocket;
import java.net.InetAddress;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;


public class HttpServer {

    // shutdown command
    private static final String SHUTDOWN_COMMAND = "/SHUTDOWN";

    // the shutdown command received
    private boolean shutdown = false;

    public static void main(String[] args) {
        HttpServer server = new HttpServer();
        server.await();
    }

    public void await() {
        ServerSocket serverSocket = null;
        int port = 8080;
        try {
            serverSocket = new ServerSocket(port, 1, InetAddress
                    .getByName("127.0.0.1"));
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
        // Loop waiting for a request
        while (!shutdown) {
            Socket socket = null;
            InputStream input = null;
            OutputStream output = null;
            try {
                socket = serverSocket.accept();
                input = socket.getInputStream();
                output = socket.getOutputStream();
                // create Request object and parse
                Request request = new Request(input);
                request.parse();

                // create Response object
                Response response = new Response(output);
                response.setRequest(request);
                response.sendStaticResource();

                // Close the socket
                socket.close();

                // check if the previous URI is a shutdown command
                shutdown =
                        request.getUri().equals(SHUTDOWN_COMMAND);
            } catch (Exception e) {
                e.printStackTrace();
                continue;
            }
        }
    }
}

22.7.2 Request類
1.代碼清單22.7 Request類

package app22.app22.webserver;
import java.io.InputStream;
import java.io.IOException;

public class Request {
    private InputStream input;
    private String uri;

    public Request(InputStream input) {
        this.input = input;
    }

    public void parse() {
        // Read a set of characters from the socket
        StringBuilder request = new StringBuilder(2048);
        int i;
        byte[] buffer = new byte[2048];
        try {
            i = input.read(buffer);
        } catch (IOException e) {
            e.printStackTrace();
            i = -1;
        }
        for (int j = 0; j < i; j++) {
            request.append((char) buffer[j]);
        }
        System.out.print(request.toString());
        uri = parseUri(request.toString());
    }

    private String parseUri(String requestString) {
        int index1 = requestString.indexOf(' ');
        int index2;
        if (index1 != -1) {
            index2 = requestString.indexOf(' ', index1 + 1);
            if (index2 > index1) {
                return requestString.substring(index1 + 1, index2);
            }
        }
        return null;
    }

    public String getUri() {
        return uri;
    }
}

22.7.3 Response類
1.代碼清單22.10 Response類

package app22.app22.webserver;
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/*
 HTTP Response =
 Status-Line (( general-header | response-header | entity-header ) CRLF)
 CRLF
 [ message-body ]
 Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
 */

public class Response {

    private static final int BUFFER_SIZE = 1024;
    Request request;
    OutputStream output;

    public Response(OutputStream output) {
        this.output = output;
    }

    public void setRequest(Request request) {
        this.request = request;
    }

    public void sendStaticResource() throws IOException {
        byte[] bytes = new byte[BUFFER_SIZE];
        Path path = Paths.get(System.getProperty("user.dir"),
                "webroot", request.getUri());
        System.out.println("path:" + path);
        if (Files.exists(path)) {
            try (InputStream inputStream =
                         Files.newInputStream(path)) {
                int ch = inputStream.read(bytes, 0, BUFFER_SIZE);
                while (ch != -1) {
                    output.write(bytes, 0, ch);
                    ch = inputStream.read(bytes, 0, BUFFER_SIZE);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            // file not found
            String errorMessage = "HTTP/1.1 404 File Not Found\r\n"
                    + "Content-Type: text/html\r\n"
                    + "Content-Length: 23\r\n" + "\r\n"
                    + "<h1>File Not Found</h1>";
            output.write(errorMessage.getBytes());
        }
    }
}

教材學習中的問題和解決過程

  • 問題1:對Java網絡編程部分的內容概念模糊、體系和框架掌握不清、重點不明確。
  • 問題解決方案1:在網上查找相關資料並學習總結:
    Java的網絡編程主要涉及到的內容是Socket編程。簡單地說,Socket,套接字,就是兩臺主機之間邏輯鏈接的端點。TPC/IP協議是傳輸層協議,主要解決數據如何在網絡中傳輸,而HTTP是應用層協議,主要解決如何包裝數據。Socket,本質上就是一組接口,是對TCP/IP協議的封裝和應用(程序員層面上)。
    Socket編程主要涉及到客戶端和服務器端兩個方面,首先是在服務器端建立一個服務器套接字(ServerSocket),並把它附加到一個端口上,服務器從這個端口監聽鏈接。端口號的範圍是0到65536,可是0到1024是爲特權服務保留的端口號,咱們能夠選擇任意一個當前沒有被其餘進程使用的端口。
    客戶端請求與服務器進行鏈接的時候,根據服務器的域名或者IP地址,加上端口號,打開一個套接字。當服務器接受鏈接後,服務器和客戶端之間的通訊就像輸入輸出流同樣進行操做。

(1)HTTPS和HTTP的區別——
HTTPS是以安全爲目標的HTTP通道,簡單講是HTTP的安全版。即HTTP下加入SSL層,HTTPS的安全基礎是SSL,所以加密的詳細內容就須要SSL。它是一個URI scheme(抽象標識符體系),句法類同http:體系。用於安全的HTTP數據傳輸。https:URL代表它使用了HTTP,但HTTPS存在不一樣於HTTP的默認端口及一個加密/身份驗證層(在HTTP與TCP之間)。
超文本傳輸協議HTTP協議被用於在Web瀏覽器和網站服務器之間傳遞信息。HTTP協議以明文方式發送內容,不提供任何方式的數據加密,若是攻擊者截取了Web瀏覽器和網站服務器之間的傳輸報文,就能夠直接讀懂其中的信息,所以HTTP協議不適合傳輸一些敏感信息,好比信用卡號、密碼等。
爲了解決HTTP協議的這一缺陷,須要使用另外一種協議:安全套接字層超文本傳輸協議HTTPS。爲了數據傳輸的安全,HTTPS在HTTP的基礎上加入了SSL協議,SSL依靠證書來驗證服務器的身份,併爲瀏覽器和服務器之間的通訊加密。
HTTPS和HTTP的區別主要爲如下四點:一、https協議須要到ca申請證書,通常免費證書不多,須要交費。二、http是超文本傳輸協議,信息是明文傳輸,https 則是具備安全性的ssl加密傳輸協議。三、http和https使用的是徹底不一樣的鏈接方式,用的端口也不同,前者是80,後者是443。四、http的鏈接很簡單,是無狀態的;HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,比http協議安全。
(2)HTTP請求的GET方法和POST方法的區別——
GET和POST是HTTP請求的兩種方法,主要區別在於GET方法是請求讀取由URL所標誌的信息,POST是給服務器添加信息。
(3)在瀏覽器中輸入網址到顯示出頁面的整個過程——
輸出包含域名的網址——瀏覽器向DNS請求解析域名對應的IP地址——域名系統DNS解析出域名對應的IP地址——瀏覽器與該服務器創建TCP鏈接——瀏覽器發送HTTP請求——服務器經過HTTP響應把頁面文件發送給瀏覽器——TCP鏈接釋放——瀏覽器解釋文件,並顯示。

  • 問題2:數據庫索引是什麼?
  • 問題解決方案2:在網上查找相關資料並學習總結:
    建立數據庫索引能夠大大提升系統的性能:
    (1)經過建立惟一性索引,能夠保證數據庫表中每一行數據的惟一性。
    (2)能夠大大加快數據的檢索速度,這也是建立索引的最主要的緣由。
    (3)能夠加速表和表之間的鏈接,特別是在實現數據的參考完整性方面特別有意義。
    (4)在使用分組和排序 子句進行數據檢索時,一樣能夠顯著減小查詢中分組和排序的時間。
    (5)經過使用索引,能夠在查詢的過程當中,使用優化隱藏器,提升系統的性能。
    增長索引也有許多不利的影響:
    (1)建立索引和維護索引要耗費時間,這種時間隨着數據 量的增長而增長。
    (2)索引須要佔物理空間,除了數據表佔數據空間以外,每個索引還要佔必定的物理空間,若是要創建聚簇索引,那麼須要的空間就會更大。
    (3)當對錶中的數據進行增長、刪除和修改的時候,索引也要動態的維護,這樣就下降了數據的維護速度。

代碼調試中的問題和解決過程

  • 問題1:對Android Studio不夠了解
  • 問題1解決方案:下載和安裝Android Studio

  • 問題2:本週課堂頭腦風暴用java實現DH密鑰交換算法時出現「Unsupported secret key algorithm:AES」錯誤
  • 問題2解決方案:經過排查,發現是JDK版本的緣由,因爲JDK8 update 161以後,DH的密鑰長度至少爲512位,但AES算法密鑰不能達到這樣的長度,因此致使報錯。故打開IDEA的Run-Edit Configurations-在VM options一欄將-Djdk.crypto.KeyAgreement.legacyKDF=true寫入便可。

[代碼託管]

https://gitee.com/EvelynYang/20189230Week5/tree/master/src

statistics.sh腳本運行結果的截圖

學習進度條

代碼行數(新增/累積) 博客量(新增/累積) 學習時間(新增/累積) 重要成長
目標 5000行 30篇 400小時
第一週 200/200 2/2 20/20
第二週 300/500 1/3 18/38
第三週 500/1000 1/4 38/76
第四周 1000/2000 1/5 20/96
第五週 1000/3000 1/6 25/121

參考資料

相關文章
相關標籤/搜索