java中的IO流和多線程

 1.如何用file操做目錄和文件?java

java對待目錄和文件統一使用file來表示,在建立file對象時,使用isDictionaryisFile方法進行判斷數組

 1 package test;
 2 
 3 import java.io.File;
 4 
 5 import java.io.IOException;
 6 
 7 public class FileTest {
 8 
 9 public static void main(String[] args) {
10 
11 // TODO Auto-generated method stub
12 
13 File file1 = new File("E:/a.txt");
14 
15 if (!file1.exists()) {
16 
17 try {
18 
19 file1.createNewFile();
20 
21 } catch (IOException e) {
22 
23 // TODO Auto-generated catch block
24 
25 e.printStackTrace();
26 
27 System.out.println("建立文件失敗!");
28 
29 }
30 
31 }
32 
33 // 建立一個目錄
34 
35 File dir = new File("E:/testxjq");
36 
37 // 判斷是否爲目錄
38 
39 if (dir.isDirectory()) {
40 
41 // 獲得全部的文件
42 
43 String[] files = dir.list();
44 
45 for (String fileName : files) {
46 
47 // 用目錄和文件名生成File對象
48 
49 File f = new File(dir.getPath() + File.separator + fileName);
50 
51 // 對生成的File對象進行分類打印
52 
53 if (f.isFile()) {
54 
55 System.out.println("文件爲:" + f.getName());
56 
57 } else if (f.isDirectory()) {
58 
59 System.out.println("目錄爲:" + f.getName());
60 
61 }else{
62 
63 System.out.println("null");
64 
65 }
66 
67 }
68 
69 }
70 
71 else{
72 
73 System.out.println("dsddssf");
74 
75 }
76 
77 }
78 
79 }

 

總結:FIle類的經常使用方法:多線程

(1)構造方法:傳遞字符串形式的文件路徑的方式來建立file對象,file並不會檢查該目錄或者文件是否已經存在。併發

(2)IsDirectoryisFile方法用於判斷File對象所表明的是目錄仍是普通的文件。app

(3)createNewFile方法,採用file對象所存儲的路徑和文件名進行建立。dom

(4)List方法,用於目錄,獲得目錄下全部的文件名,類型爲字符串數組jvm

(5)getName():獲得文件名,不包含他的路徑。ide

(6)Delete,刪除文件測試

2.寫一個複製文件的程序?this

 1 package test;
 2 
 3 import java.io.FileInputStream;
 4 
 5 import java.io.FileOutputStream;
 6 
 7 import java.io.IOException;
 8 
 9 public class FileCopy {
10 
11  
12 
13 public static void main(String[] args) throws IOException {
14 
15 // TODO Auto-generated method stub
16 
17 //生成的輸入文件的輸入流對象
18 
19 FileInputStream fin = new FileInputStream("e:/a.txt");
20 
21 //生成輸出文件的輸出流對象
22 
23 FileOutputStream fout = new FileOutputStream("e:/b.txt");
24 
25 //定義一個暫存數據的數組
26 
27 byte[] buff = new byte[256];
28 
29 //每次讀取數據的長度
30 
31 int len = 0;
32 
33 while((len=fin.read(buff))>0){
34 
35 fout.write(buff, 0, len);
36 
37 }
38 
39 fin.close();
40 
41 fout.close();
42 
43 }
44 
45  
46 
47 }

 

 

3.如何使用隨機存取文件RandomAccessfile類?

 1 package test;
 2 
 3 import java.io.IOException;
 4 
 5 import java.io.RandomAccessFile;
 6 
 7 public class RanAccessFile {
 8 
 9  
10 
11 public static void main(String[] args) throws IOException {
12 
13 // TODO Auto-generated method stub
14 
15 //建立隨機讀取文件對象
16 
17 RandomAccessFile file = new RandomAccessFile("E:/a.txt","rw");
18 
19 //遍歷file字節數據
20 
21 for(int i = 0;i<file.length();i++){
22 
23 //從內存中讀取的都爲二進制,將二進制轉換爲字節,字節轉爲字符
24 
25 byte b  = (byte)file.read();
26 
27 char c  = (char)b;
28 
29 //若是對應的字符爲a
30 
31 if(c=='a'){
32 
33 //指針回退原位置
34 
35 file.seek(i);
36 
37 //重寫該位置的數據
38 
39 file.write('c');
40 
41 }
42 
43 }
44 
45 file.close();
46 
47 System.out.println("ok");
48 
49 }
50 
51 }

 

總結:length方法獲取文件的內容長度

seek方法隨機達到任何須要存取數據的地方

read方法獲取當前位置的數據,write方法寫入數據

close方法關閉文件的打開。

 

 

4.字節流的處理方式?

計算機內部處理數據老是以一個byte爲基本單位,字節流 就是每次讀取的單位爲byte,字節流是全部的流的基礎,也是其餘高級流 的前提。

java中的基礎字節輸入流和輸出流類別:

inputStreamoutputStream

以及:

FileInputStreamFileOutputStream

ObjectInputStream ObjectOutputStream

BufferedInputStreamBufferedOutputStream

也主要經過readwrite方法把byte數組中的數據寫入和讀出。

5.字符流的處理方式?

字符流是由字節流包裝而來的,輸入和輸出流的格式爲

StringReader StringWriter

BufferedReader BufferedWriter:有特殊具有的ReadLine()方法

一個例子:

 1 package test;
 2 
 3 import java.io.BufferedReader;
 4 
 5 import java.io.FileInputStream;
 6 
 7 import java.io.IOException;
 8 
 9 import java.io.InputStream;
10 
11 import java.io.InputStreamReader;
12 
13 /*
14 
15  * 按行讀取文件而且打印
16 
17  * */
18 
19 public class ReaderTest {
20 
21 public static void main(String[] args) throws IOException {
22 
23 // TODO Auto-generated method stub
24 
25 //根據文件獲得一個輸入流
26 
27 InputStream in = new FileInputStream("E:/a.txt");
28 
29 //獲得inputStreamReader對象
30 
31 InputStreamReader isr = new InputStreamReader(in,"GBK");
32 
33 //根據輸入流建立Reader對象
34 
35 BufferedReader br = new BufferedReader(isr);
36 
37 //建立StringBuffer對象臨時保存字符內容
38 
39 StringBuffer sb = new StringBuffer();
40 
41 String str = null;
42 
43  
44 
45 while((str = br.readLine())!=null){
46 
47 sb.append(str);
48 
49 }
50 
51 System.out.println("content:"+sb);
52 
53 br.close();
54 
55 isr.close();
56 
57 in.close();
58 
59 }
60 
61 }

 

6.什麼是序列化?

java對象內村中的數據採編成一串二進制數據,把這些數據存放在能夠持久的數據存儲設備,當須要還原數據時,經過反序列化,把對象從新還原到內存中。

java.io.Serializable接口是進行序列化的類的標誌性接口,本省沒有任何須要實現的抽象的方法,告訴jvm該類的對象能夠進行序列化,序列化idserialVersionUID變量提供。

serialVersionUID用來辨別類,若是在在反序列的時候,兩個類的類名是相同的,就經過該id來進行辨別。

一個實現序列化和反序列化的例子:

  1 package test;
  2 
  3 import java.io.FileInputStream;
  4 
  5 import java.io.FileNotFoundException;
  6 
  7 import java.io.FileOutputStream;
  8 
  9 import java.io.IOException;
 10 
 11 import java.io.ObjectInputStream;
 12 
 13 import java.io.ObjectOutputStream;
 14 
 15 import java.io.Serializable;
 16 
 17  
 18 
 19 class Person implements Serializable{
 20 
 21 public String getName() {
 22 
 23 return name;
 24 
 25 }
 26 
 27 public void setName(String name) {
 28 
 29 this.name = name;
 30 
 31 }
 32 
 33 public int getAge() {
 34 
 35 return age;
 36 
 37 }
 38 
 39 public void setAge(int age) {
 40 
 41 this.age = age;
 42 
 43 }
 44 
 45 //序列化id
 46 
 47 private static final long serialVersionUID = 1L;
 48 
 49 private String name;
 50 
 51 private int age;
 52 
 53 }
 54 
 55 public class SerialTest {
 56 
 57 public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
 58 
 59 // TODO Auto-generated method stub
 60 
 61 Person stu = new Person();
 62 
 63  
 64 
 65 stu.setAge(20);
 66 
 67 stu.setName("admin");
 68 
 69 //建立對象的輸出流,將對象輸出到磁盤
 70 
 71 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("e:/a.dat"));
 72 
 73 //開始寫對象
 74 
 75 oos.writeObject(stu);
 76 
 77 oos.close();
 78 
 79 //建立對象的輸入流
 80 
 81 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("e:/a.dat"));
 82 
 83 //從磁盤中讀取對象,再轉換成一個實體
 84 
 85 Person p = (Person)ois.readObject();
 86 
 87 //輸出
 88 
 89 System.out.println(p.getAge());
 90 
 91 System.out.println(p.getName());
 92 
 93 }
 94 
 95 }
 96 
 97 結果:
 98 
 99 20
100 
101 admin

7.什麼是多線程?

進程是整個程序或者部分程序的動態執行,線程是一組指令的集合,能夠在程序中單獨的運行。多線程是這樣的一種機制,容許在程序中併發執行多個指令流,每一個指令流都被稱爲一個線程,彼此間相互獨立。

好處:

<1>使用線程能夠把佔據長時間的程序中的任務放到後臺去處理。

<2>加快程序的運行速度

<3>在等待的任務下,線程能夠去釋放一些資源,如佔用的內存。

8.進程和線程的區別?

<1>線程的劃分尺度小於進程,線程屬於某個進程

<2>進程是程序的一種動態形式,是CPU,內存等資源佔用的基本單位,線程不能夠獨立擁有這些資源。

<3>線程之間共享一塊內存區域,通訊比較方便。

<4>進程在執行的過程當中,會包含比較固定的入口,執行的順序和出口,線程的這些過程會被應用程序所控制。

9.如何讓一個類成爲線程類?

方法一:實現java.lang.Runable接口

方法二:繼承自java.lang.Thread

本質上,Thread以及實現了Runable接口,你在繼承Thread類的時候,已經實現了Runable接口,只是Thread類還提供了額外的方法。

 1 package test;
 2 
 3 public class RunTest implements Runnable {
 4 
 5 @Override
 6 
 7 public void run() {
 8 
 9 // TODO Auto-generated method stub
10 
11 System.out.println("thread running");
12 
13 }
14 
15 }
16 
17  
18 
19 package test;
20 
21 public class RunTest extends Thread {
22 
23 @Override
24 
25 public void run() {
26 
27 // TODO Auto-generated method stub
28 
29 System.out.println("thread running");
30 
31 }
32 
33 }

 

10.Runnable接口和Thread類的區別?

<1>若是線程類繼承了Thread類那麼久不能夠再繼承其餘的類,而Runnable接口是能夠的,由於Java支持單繼承。

<2>若是要使用不少的線程的方法,使用Thread更方便。

<3>實現Runnable接口的線程類的多個線程,能夠更方便地訪問同一個變量。

 

11.如何去啓動一個線程?

針對繼承自Thread類和實現了Runnable接口:

 1 package test;
 2 
 3 class ThreadTest extends Thread{
 4 
 5 public void run(){
 6 
 7 System.out.println("實現了Thread類");
 8 
 9 }
10 
11 }
12 
13 class RunnableTest implements Runnable{
14 
15 public void run(){
16 
17 System.out.println("實現了runnable接口");
18 
19 }
20 
21 }
22 
23  
24 
25 public class ThreadStartTest {
26 
27 public static void main(String[] args) {
28 
29 //直接繼承了Thread ,建立一個Thread的實例
30 
31 ThreadTest t1 = new ThreadTest();
32 
33 //t1啓動
34 
35 t1.start();
36 
37 //若是是實現了接口的線程類,須要用對象的實例做爲Thread類構造方法的參數
38 
39 Thread t2 = new Thread(new RunnableTest());
40 
41 t2.start();
42 
43 }
44 
45 }

 

12.如何使用sychronized使得線程同步?

工做原理:每一個對象都有一個線程鎖,sychronized可使用任何一個對象的線程鎖來鎖住一段代碼,任何想要進入該段代碼的線程必須在解鎖後才能夠繼續進行,不然就進入等待狀態。其中就進入等待的狀態。

 1 package test;
 2 
 3 class Test extends Thread{
 4 
 5 public static int index;
 6 
 7     //定義一個對象用於控制線程同步
 8 
 9 public static Object obj = new Object();
10 
11 public void run(){
12 
13 synchronized (obj) {
14 
15 for(int i =0;i<10;i++){
16 
17 System.out.println(index++);
18 
19 }
20 
21 }//end of synchronized
22 
23 }
24 
25 }
26 
27  
28 
29 public class MyThread {
30 
31 public static void main(String[] args) {
32 
33 // TODO Auto-generated method stub
34 
35 new Test().start();
36 
37 new Test().start();
38 
39 new Test().start();
40 
41 }
42 
43 }

13.如何使用線程池?

組成部分:

完成一個任務的一個或者多個線程;

用於調度管理的管理線程;

要求執行的任務隊列;

目的:爲了最大程度的複用對象,最大程度的利用線程。

14.反射的理解?

反射提供了一種動態的功能,主要經過反射相關的API,就能夠知道一個陌生的java類的全部的信息,包括屬性、方法、構造器,這些元素徹底能夠在運行時動態的建立或者調用,沒必要再JVM運行時就進行肯定。利用的是該類造成的java.lang.Class類的實例。

javaclass類來表明全部的類,方便開發者掌控類的信息,若是獲得了一個類的屬性,方法等信息,就能夠利用這個class建立實例,調用任何的方法,訪問任何的屬性,這就是反射的主要用處。

反射機制的API,主要集中在java.lang.reflect包下。

15.class類的的含義和做用是什麼?

第一步:一個類會在何時被加載到JVM中呢?

<1>經過new關鍵字,使用該類的對象

Student stu = new Student()

<2>訪問該類的靜態的成員

Student.age;

<3>使用class.forName()方法進行加載

class.forName(「com.test.Student」);

第二布:如何獲得一個類的class對象?

<1>Class.forName()方法

 

<2>訪問類的class屬性

 

<3>建立對象,調用對象的getClass()方法。

 

16.如何操做類的成員變量?field

反射式能夠獲取到類的對象,那就能夠經過對象去獲取成員變量。

方法:getDeclareField()方法或者getDeclareFields()方法獲取。

一個例子:

 1 package test;
 2 
 3 import java.lang.reflect.Field;
 4 
 5 //測試類
 6 
 7 class Teacher{
 8 
 9 public Teacher(String name, int age) {
10 
11 super();
12 
13 this.name = name;
14 
15 this.age = age;
16 
17 }
18 
19 //經過反射將會訪問到的屬性
20 
21 String name;
22 
23 int age;
24 
25 }
26 
27 public class FieldTest {
28 
29 public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
30 
31 Teacher t1 = new Teacher("admin",23);
32 
33 Teacher t2 = new Teacher("王老師",52);
34 
35 System.out.println(compare(t1,t2).name+"'s age is bigger!");
36 
37 }
38 
39 //利用反射機制定義一個通用的比較的方法
40 
41 @SuppressWarnings("unused")
42 
43 private static Teacher compare(Teacher tea1,Teacher tea2) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException{
44 
45 //第一個策略:經過對象的getClass()方法獲得類的class對象
46 
47 Field field  = tea1.getClass().getDeclaredField("age");
48 
49 //第二個策略:經過類的class的靜態屬性獲得類的class對象
50 
51 field = Teacher.class.getDeclaredField("age");
52 
53 //得到兩個對象的age值
54 
55 int val1 = (int) field.get(tea1);
56 
57 int val2  = (int) field.get(tea2);
58 
59 //進行比較
60 
61 if(val1>val2){
62 
63 return tea1;
64 
65 }else{
66 
67 return tea2;
68 
69 }
70 
71 }//end of compare
72 
73 }

17.如何經過反射操做類的方法?Method?

 1 package test;
 2 
 3 import java.lang.reflect.InvocationTargetException;
 4 
 5 import java.lang.reflect.Method;
 6 
 7  
 8 
 9 class MethodTestClass {
10 
11 public void m1() {
12 
13 System.out.println("m1 is called!");
14 
15 }
16 
17  
18 
19 public void m2() {
20 
21 System.out.println("m2 is called");
22 
23 }
24 
25 }
26 
27  
28 
29 public class CallMethodTest {
30 
31  
32 
33 public static void main(String[] args)
34 
35 throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
36 
37 // TODO Auto-generated method stub
38 
39 args = new String[] { "m1" };
40 
41 // 獲得方法名
42 
43 String methodName = args[0];
44 
45 if (methodName != null) {
46 
47 // 獲得class實例
48 
49 Class<MethodTestClass> clazz = MethodTestClass.class;
50 
51 // 經過該實例去獲得方法
52 
53 Method m = clazz.getDeclaredMethod(methodName);
54 
55 // 經過方法,若是方法不爲空,就建立對應類的實例
56 
57 if (m != null) {
58 
59 MethodTestClass obj = clazz.newInstance();
60 
61 // 經過m調用喚醒的方法,去喚醒這個對象
62 
63 m.invoke(obj);
64 
65 }
66 
67 }
68 
69 }
70 
71 }
72 
73  
74 
75  

18.如利用反射去實例化一個類?

兩種狀況:

<1>默認的無參數的額構造方法:

Class類的newInstance()方法

<2>對於有參數的構造方法:

先獲取一個constructor實例,再用newInsatnce()方法建立對象。

一個例子:

  1 package test;
  3 import java.lang.reflect.Constructor;
  5 import java.lang.reflect.InvocationTargetException;
  9 class people{
 11 public String getName() {
 13 return name;
 15 }
 17 public void setName(String name) {
 18 
 19 this.name = name;
 20 
 21 }
 22 
 23 public int getAge() {
 25 return age;
 27 }
 28 
 29 public void setAge(int age) {
 31 this.age = age;
 33 }
 34 
 35 @Override
 36 
 37 public String toString() {
 38 
 39 return "people [name=" + name + ", age=" + age + "]";
 40 
 41 }
 42 
 43 public people() {
 45 super();
 46 
 47 // TODO Auto-generated constructor stub
 48 
 49 }
 50 
 51 public people(String name, int age) {
 52 
 53 super();
 54 
 55 this.name = name;
 56 
 57 this.age = age;
 58 
 59 }
 60 
 61 private String name;
 62 
 63 private int age;
 64 
 65 }
 66 
 67  
 68 
 69 public class NewInstanceTest {
 70 
 71  
 72 
 73 public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
 74 
 75 // TODO Auto-generated method stub   
 76 
 77 //step1:獲取Class對象
 78 
 79     Class<people> clazz =   people.class;
 80 
 81     //step2:途徑一:使用無參數的構造方法
 82 
 83     //class對象直接獲取實例
 84 
 85 people obj = clazz.newInstance();
 86 
 87 System.out.println("第一個對象:"+obj);
 88 
 89  
 90 
 91  
 92 
 93 obj.setName("xsxs");
 94 
 95 obj.setAge(50);
 96 
 97 System.out.println("使用get/set方法後的名字:"+obj.getName());
 98 
 99 System.out.println("使用get/set方法後的年齡:"+obj.getAge());
100 
101  
102 
103  
104 
105 //step3:途徑二:使用帶參數的構造方法
106 
107 //爲構造器注入對應的值
108 
109 Constructor<people> con = clazz.getConstructor(String.class,int.class);
110 
111 obj = con.newInstance("admin",30);
112 
113 System.out.println("第二個對象:"+obj);
114 
115 }
116 
117 }

 

19.如何利用反射來訪問私有的成員?

 1 package test;
 2 
 3 import java.lang.reflect.Field;
 4 
 5 class PrivateTestClass{
 6 
 7 //定義構造方法
 8 
 9 public PrivateTestClass(String field) {
10 
11 super();
12 
13 this.field = field;
14 
15 }
16 
17 private String field;//定義一個私有的屬性
18 
19 }
20 
21 public class PrivateTest {
22 
23 public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
24 
25 // TODO Auto-generated method stub
26 
27 //建立測試類的實例
28 
29 PrivateTestClass ptc = new PrivateTestClass("hello");
30 
31 //經過該實例獲得Class對象
32 
33 Class clazz = ptc.getClass();
34 
35 //經過對象調用方法獲得字段字段
36 
37 Field myprivatefield = clazz.getDeclaredField("field");
38 
39 //設置訪問屬性爲true
40 
41 myprivatefield.setAccessible(true);
42 
43 //get方法返回該Field對象所表明的特定的值
44 
45 System.out.println(myprivatefield.get(ptc));
46 
47 }
48 
49 }

 

20.如何經過反射來覆蓋數據對象的toString()方法?

產生的背景:

若是在一個類中要改變屬性名稱,新增屬性,去掉屬性,則在toString方法中也會從新再加入或者刪除某些屬性。

  1 package test;
  2 import java.lang.reflect.Field;
  3 class DataObject{
  4 public String getName() {
  5 
  6 return name;
  7 
  8 }
  9 
 10 public void setName(String name) {
 11 
 12 this.name = name;
 13 
 14 }
 15 
 16 public int getAge() {
 17 
 18 return age;
 19 
 20 }
 21 
 22 public void setAge(int age) {
 23 
 24 this.age = age;
 25 
 26 }
 27 
 28 public DataObject() {
 29 
 30 super();
 31 
 32 // TODO Auto-generated constructor stub
 33 
 34 }
 35 
 36 public DataObject(String name, int age) {
 37 
 38 super();
 39 
 40 this.name = name;
 41 
 42 this.age = age;
 43 
 44 }
 45 
 46 //爲該類定義了倆個屬性
 47 
 48 private String name;
 49 
 50 private int age;
 51 
 52 //在類中實現本身的ToString方法
 53 
 54 public String toString(){
 55 
 56 //定義一個StringBuffer用於進行拼接
 57 
 58 StringBuffer sb = new StringBuffer();
 59 
 60 //經過反射獲得全部成員變量的fields
 61 
 62 Field[] fields = this.getClass().getDeclaredFields();
 63 
 64 //遍歷集合
 65 
 66 for(Field f:fields){
 67 
 68 //獲得一個變量的名
 69 
 70 sb.append(f.getName());
 71 
 72 //拼接上==
 73 
 74 sb.append("=");
 75 
 76 //獲得變量的值
 77 
 78 try {
 79 
 80 sb.append(f.get(this));
 81 
 82 } catch (IllegalArgumentException e) {
 83 
 84 // TODO Auto-generated catch block
 85 
 86 e.printStackTrace();
 87 
 88 } catch (IllegalAccessException e) {
 89 
 90 // TODO Auto-generated catch block
 91 
 92 e.printStackTrace();
 93 
 94 }
 95 
 96 //每次拼接完一個變量,換行處理/空格處理
 97 
 98 sb.append(" ");
 99 
100 }
101 
102 //返回拼接後的字符串
103 
104 return sb.toString();
105 
106 }//end of toString()
107 
108 }
109 
110 public class DataObjectTest {
111 public static void main(String[] args) throws InstantiationException, IllegalAccessException {
112 
113 // TODO Auto-generated method stub
114 
115 //利用動態代理去實例化一個類
116 
117 DataObject obj = new DataObject();
118 
119     @SuppressWarnings("unchecked")
120 
121 Class<DataObject> clazz  = (Class<DataObject>) obj.getClass();
122 
123     DataObject my  =  clazz.newInstance();
124 
125     //利用屬性方法爲屬性賦值
126 
127     my.setAge(100);
128 
129     my.setName("dddddd");
130 
131     //輸出打印時,調用了自定義toString方法
132 
133 System.out.println(my);
134 
135 }
136 }
相關文章
相關標籤/搜索