目錄html
第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)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鏈接釋放——瀏覽器解釋文件,並顯示。
問題1解決方案:下載和安裝Android Studio
問題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
代碼行數(新增/累積) | 博客量(新增/累積) | 學習時間(新增/累積) | 重要成長 | |
---|---|---|---|---|
目標 | 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 |