18.JAVA中的File和IO

[size=large]File类:
不管是文件还是目录,在Java中都是以File的实例来表示,如下示例是指定查询某个目录下的所有文件与目录名称。File类是文件的抽象代表,若要作文件输出/输入,必须配合其他相关类来使用。[/size]
import java.io.*;  
import java.util.*;

public class FileDemo
{
public void readFile(String filename){
try
{
File file = new File(filename);
if(file.isFile()) //是否为文件
{
System.out.println( "文件");
System.out.print(file.canRead()?"可读":"不可读");
System.out.print(file.canWrite()?"可写":"不可写");
System.out.println(file.length()+"字节");
}
else {
//列出所有文件及目录
File[] files = file.listFiles();
ArrayList<File> fileList = new ArrayList<File>();
for(int i=0;i<files.length;i++)
{
//先列出目录
if(files[i].isDirectory())
{
//是否为目录
System.out.println("["+files[i].getPath()+"]");
this.readFile(files[i]+"");
}
else
{
//文件先存入fileList,待会再列出
fileList.add(files[i]);
}
}
//列出文件
for(File f : fileList)
{
System.out.println(f.toString());
}
System.out.println();
}
}
catch(ArrayIndexOutOfBoundsException e)
{
System.out.println("using: java FileDemo pathname");
}
}
public static void main(String[] args)
{
FileDemo fm=new FileDemo();
fm.readFile("C:\\Users\\zzhblh\\Desktop\\aaa");
}
}



[size=large]Java 流在处理上分为字符流和字节流。

[color=orange]( 一 )以字节为导向的 stream------InputStream/OutputStream [/color]
InputStream 和 OutputStream 是两个 abstact 类,对于字节为导向的 stream 都扩展这两个基类 [/size]
[img]http://dl.iteye.com/upload/attachment/0066/6510/2fc91e1c-8382-3000-bd63-3251d58a39a0.png[/img]

[img]http://dl.iteye.com/upload/attachment/0066/6514/2245174e-b0bd-3600-a10a-e53a06e750ea.png[/img]


[size=large] [color=orange]( 二 )以字符为导向的 stream Reader/Writer [/color]
以 Unicode 字符为导向的 stream ,表示以 Unicode 字符为单位从 stream 中读取或往 stream 中写入信息。 Reader/Writer 为 abstact 类 [/size]
[img]http://dl.iteye.com/upload/attachment/0066/6520/d01945e3-c4a3-3a4b-8fe0-71bb2f908414.png[/img]

[img]http://dl.iteye.com/upload/attachment/0066/6522/86e3e9be-cc6f-3815-a663-ba11bc0daa26.png[/img]


[size=large] [color=orange](三)Java IO 的一般使用原则 :[/color]
一、按数据来源(去向)分类:
1 、是文件: FileInputStream, FileOutputStream, ( 字节流 )FileReader, FileWriter( 字符 )
2 、是 byte[] : ByteArrayInputStream, ByteArrayOutputStream( 字节流 )
3 、是 Char[]: CharArrayReader, CharArrayWriter( 字符流 )
4 、是 String: StringBufferInputStream, StringBufferOuputStream ( 字节流 )StringReader, StringWriter( 字符流 )
5 、网络数据流: InputStream, OutputStream,( 字节流 ) Reader, Writer( 字符流 )
二、按是否格式化输出分:
1 、要格式化输出: PrintStream, PrintWriter
三、按是否要缓冲分:
1 、要缓冲: BufferedInputStream, BufferedOutputStream,( 字节流 ) BufferedReader, BufferedWriter( 字符流 )
四、按数据格式分:
1 、二进制格式(只要不能确定是纯文本的) : InputStream, OutputStream 及其所有带 Stream 结束的子类
2 、纯文本格式(含纯英文与汉字或其他编码方式); Reader, Writer 及其所有带 Reader, Writer 的子类
五、按输入输出分:
1 、输入: Reader, InputStream 类型的子类
2 、输出: Writer, OutputStream 类型的子类
六、特殊需要:
1 、从 Stream 到 Reader,Writer 的转换类: InputStreamReader, OutputStreamWriter
2 、对象输入输出: ObjectInputStream, ObjectOutputStream
3 、进程间通信: PipeInputStream, PipeOutputStream, PipeReader, PipeWriter
4 、合并输入: SequenceInputStream
5 、更特殊的需要: PushbackInputStream, PushbackReader, LineNumberInputStream, LineNumberReader[/size]


[size=large][color=blue]DataInputStream 和 DataOutputStream :[/color]
DataInputStream、DataOutputStream可提供一些對Java基本資料型態寫入的方法,像是讀寫int、double、 boolean等的方法,由於Java的資料型態大小是規定好的,在寫入或讀出這些基本資料型態時,就不用擔心不同平台間資料大小不同的問題。[/size]
1.package ysu.hxy;  
2.
3.import java.io.*;
4.
5.public class DataStreamDemo
6.{
7. public static void main(String[] args)
8. {
9. Member[] members = {new Member("Justin",90),
10. new Member("momor",95),
11. new Member("Bush",88)};
12. try
13. {
14. DataOutputStream dataOutputStream = new DataOutputStream(new FileOutputStream(args[0]));
15.
16. for(Member member:members)
17. {
18. //写入UTF字符串
19. dataOutputStream.writeUTF(member.getName());
20. //写入int数据
21. dataOutputStream.writeInt(member.getAge());
22. }
23.
24. //所有数据至目的地
25. dataOutputStream.flush();
26. //关闭流
27. dataOutputStream.close();
28.
29. DataInputStream dataInputStream = new DataInputStream(new FileInputStream(args[0]));
30.
31. //读出数据并还原为对象
32. for(int i=0;i<members.length;i++)
33. {
34. //读出UTF字符串
35. String name = dataInputStream.readUTF();
36. //读出int数据
37. int score = dataInputStream.readInt();
38. members[i] = new Member(name,score);
39. }
40.
41. //关闭流
42. dataInputStream.close();
43.
44. //显示还原后的数据
45. for(Member member : members)
46. {
47. System.out.printf("%s\t%d%n",member.getName(),member.getAge());
48. }
49. }
50. catch(IOException e)
51. {
52. e.printStackTrace();
53. }
54. }
55.}

[size=large]在从文件读出数据时,不用费心地自行判断读入字符串时或读入int类型时何时将停止,使用对应的readUTF()和readInt()方法就可以正确地读入完整的类型数据。[/size]


[size=large][color=blue]BufferedInputStream和BufferedOutputStream :[/color]
1. java.io.BufferedInputStream与java.io.BufferedOutputStream可以为InputStream,OutputStream类增加缓冲区功能。构建BufferedInputStream实例时,需要给定一个InputStream类型的实例,实现BufferedInputStream时,实际上最后是实现InputStream实例。同样,构建BufferedOutputStream时,也需要给定一个OutputStream实例,实现BufferedOutputStream时,实际上最后是实现OutputStream实例。

2. BufferedInputStream的数据成员buf是一个位数组,默认为2048字节。当读取数据来源时,例如文件,BufferedInputStream会尽量将buf填满。当使用read()方法时,实际上是先读取buf中的数据,而不是直接对数据来源作读取。当buf中的数据不足时,BufferedInputStream才会再实现给定的InputStream对象的read()方法,从指定的装置中提取数据。

3. BufferedOutputStream的数据成员buf也是一个位数组,默认为512字节。当使用write()方法写入数据时实际上会先将数据写到buf中,当buf已满时才会实现给定的OutputStream对象的write()方法,将buf数据写到目的地,而不是每次都对目的地作写入的动作。[/size]
1.package ysu.hxy;  
2.
3.import java.io.*;
4.
5.public class BufferedStreamDemo
6.{
7. public static void main(String[] args)
8. {
9. try
10. {
11. byte[] data = new byte[1];
12.
13. File srcFile = new File(args[0]);
14. File desFile = new File(args[1]);
15.
16. BufferedInputStream bufferedInputStream =
17. new BufferedInputStream(new FileInputStream(srcFile));
18.
19. BufferedOutputStream bufferedOutputStream =
20. new BufferedOutputStream(new FileOutputStream(desFile));
21.
22. System.out.println("复制文件:"+srcFile.length()+"字节");
23.
24. while(bufferedInputStream.read(data)!=-1)
25. {
26. bufferedOutputStream.write(data);
27. }
28.
29. //将缓冲区中的数据全部写出
30. bufferedOutputStream.flush();
31.
32. //关闭流
33. bufferedInputStream.close();
34. bufferedOutputStream.close();
35.
36. System.out.println("复制完成");
37. }
38. catch(ArrayIndexOutOfBoundsException e)
39. {
40. System.out.println("using:java UseFileStream src des");
41. e.printStackTrace();
42. }
43. catch(IOException e)
44. {
45. e.printStackTrace();
46. }
47. }
48.};

[size=large]为了确保缓冲区中的数据一定被写出至目的地,建议最后执行flush()将缓冲区中的数据全部写出目的流中。[/size]

[size=large][color=blue]FileInputStream和FileOutputStream:[/color]
java.io.FileInputStream是InputStream的子类。从开头File名称上就可以知道,FileInputStream与从指定的文件中读取数据至目的地有关。而java.io.FileOutputStream是OutputStream的子类,顾名思义,FileOutputStream主要与从来源地写入数据至指定的文件中有关。
当建立一个FileInputStream或FileOutputStream的实例时,必须指定文件位置及文件名称,实例被建立时文件的流就会开启;而不使用流时,必须关闭文件流,以释放与流相依的系统资源,完成文件读/写的动作。
FileInputStream可以使用read()方法一次读入一个字节,并以int类型返回,或者是使用read()方法时读入至一个byte数组,byte数组的元素有多少个,就读入多少个字节。在将整个文件读取完成或写入完毕的过程中,这么一个byte数组通常被当作缓冲区,因为这么一个byte数组通常扮演承接数据的中间角色。[/size]
import java.io.*;
public class FileStreamDemo {
public static void main(String[] args) {
try {byte[] buffer = new byte[1024];
// 来源文件
FileInputStream fileInputStream =
new FileInputStream(new File(args[0]));
// 目的文件
FileOutputStream fileOutputStream =
new FileOutputStream(new File(args[1]));


// available()可取得未读取的数据长度
System.out.println("复制文件:" +
fileInputStream.available() + "字节");


while(true) {
if(fileInputStream.available() < 1024) {
// 剩余的数据比1024字节少
// 一位一位读出再写入目的文件
int remain = -1;
while((remain = fileInputStream.read())
!= -1) {
fileOutputStream.write(remain);
}
break;
}
else {
// 从来源文件读取数据至缓冲区
fileInputStream.read(buffer);
// 将数组数据写入目的文件
fileOutputStream.write(buffer);
}
}
// 关闭流
fileInputStream.close();
fileOutputStream.close();


System.out.println("复制完成");
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println(
"using: java FileStreamDemo src des");
e.printStackTrace();
}
catch(IOException e) {
e.printStackTrace();
}
}
}

[size=large]程序中示范了两个read()方法,一个方法可以读入指定长度的数据至数组,另一个方法一次可以读入一个字节。每次读取之后,读取的光标都会往前进,如果读不到数据则返回-1,使用available()方法获得还有多少字节可以读取。除了使用File来建立FileInputStream、FileOutputStream的实例之外,也可以直接使用字符串指定路径来建立。[/size]
// 来源文件
FileInputStream fileInputStream =new FileInputStream(args[0]);
// 目的文件
FileOutputStream fileOutputStream =new FileOutputStream(args[1]);

[size=large]FileOutputStream默认会以新建文件的方式来开启流。如果指定的文件名称已经存在,则原文件会被覆盖;如果想以附加的模式来写入文件,则可以在构建FileOutputStream实例时指定为附加模式。例如:[/size]
FileOutputStream fileOutputStream =
new FileOutputStream(args[1], true);

[size=large]构建方法的第二个append参数如果设置为true,在开启流时如果文件不存在则会新建一个文件,如果文件存在就直接开启流,并将写入的数据附加至文件末端。[/size]


[size=large][color=blue]ObjectInputStream和ObjectOutputStream :[/color]
. 在Java程序执行过程中,很多数据都是以对象的方式存在于内存中。有时会希望直接将内存中的对象存储至文件,而不是仅存储对象中的某些基本类型成员信息,而在下一次程序运行时,希望能从文件中读出数据并还原为对象。这时可以利用java.io.ObjectInputStream和java.io.ObjectOutputStream类来进行这项工作。

2. 如果要存储对象,定义该对象的类必须实现java.io.Serializable接口,这是一个标志接口,没有规范任何必须实现的方法,仅仅代表该对象是可序列化的(Serializable)。为了说明如何直接存储对象,先来实现一个User类。[/size]
1.package ysu.hxy;  
2.
3.import java.io.*;
4.import java.util.*;
5.
6.public class ObjectStreamDemo
7.{
8. public static void main(String[] args)
9. {
10. User[] users = {new User("cater",101),new User("justin",102)};
11. //写入新文件
12. writeObjectsToFile(users,args[0]);
13.
14. try
15. {
16. //读取文件数据
17. users = readObjectsFromFile(args[0]);
18. //显示读回的对象
19. for(User user : users)
20. {
21. System.out.printf("%s\t%d%n",user.getName(),user.getNumber());
22. }
23. System.out.println();
24.
25. users = new User[2];
26. users[0] = new User("momor",103);
27. users[1] = new User("becky",104);
28.
29. //附加新对象至文件
30. appendObjectsToFile(users,args[0]);
31.
32. //读取文件数据
33. users = readObjectsFromFile(args[0]);
34. //显示读回的对象
35. for(User user : users)
36. {
37. System.out.printf("%s\t%d%n",user.getName(),user.getNumber());
38. }
39. }
40. catch(ArrayIndexOutOfBoundsException e)
41. {
42. System.out.println("没有指定文件名");
43. }
44. catch(FileNotFoundException e)
45. {
46. e.printStackTrace();
47. }
48. }
49.
50. //将指定的对象写入至指定的文件
51. public static void writeObjectsToFile(Object[] objs,String filename)
52. {
53. File file = new File(filename);
54.
55. try
56. {
57. ObjectOutputStream objOutputStream =
58. new ObjectOutputStream(new FileOutputStream(file));
59.
60. for(Object obj : objs)
61. {
62. //将对象写入文件
63. objOutputStream.writeObject(obj);
64. }
65.
66. //关闭流
67. objOutputStream.close();
68. }
69. catch(IOException e)
70. {
71. e.printStackTrace();
72. }
73. }
74.
75. //将指定文件中的对象数据读回
76. public static User[] readObjectsFromFile(String filename) throws FileNotFoundException
77. {
78. File file = new File(filename);
79.
80. //如果文件不存在就抛出异常
81. if(!file.exists())
82. throw new FileNotFoundException();
83.
84. //使用List先存储读回的对象
85. List<User> list = new ArrayList<User>();
86.
87. try
88. {
89. FileInputStream fileInputStream = new FileInputStream(file);
90. ObjectInputStream objInputStream = new ObjectInputStream(fileInputStream);
91.
92. while(fileInputStream.available()>0)
93. {
94. list.add((User)objInputStream.readObject());
95. }
96. objInputStream.close();
97. }
98. catch(ClassNotFoundException e)
99. {
100. e.printStackTrace();
101. }
102. catch(IOException e)
103. {
104. e.printStackTrace();
105. }
106.
107. User[] users = new User[list.size()];
108. return list.toArray(users);
109. }
110.
111. //将对象附加至指定的文件之后
112. public static void appendObjectsToFile(Object[] objs,String filename) throws FileNotFoundException
113. {
114. File file = new File(filename);
115.
116. //如果文件不存在,则抛出异常
117. if(!file.exists())
118. throw new FileNotFoundException();
119.
120. try
121. {
122. //附加模式
123. ObjectOutputStream objOutputStream =
124. new ObjectOutputStream(new FileOutputStream(file,true))
125. {
126. //如果要附加对象至文件后,必须重新定义这个方法
127. protected void writeStreamHeader() throws IOException{}
128. };
129.
130. for(Object obj : objs)
131. {
132. //将对象写入文件
133. objOutputStream.writeObject(obj);
134. }
135. objOutputStream.close();
136. }
137. catch(IOException e)
138. {
139. e.printStackTrace();
140. }
141. }
142.}

[size=large]注意,在试图将对象附加至一个先前已写入对象的文件时,由于ObjectOutputStream在写入数据时,还会加上一个特别的流头(Stream Header),所以在读取文件时会检查这个流头。如果一个文件中被多次附加对象,那么该文件中会有多个流头,这样读取检查时就会发现不一致,这会丢出java.io.StreamCorruptedException异常。为了解决这个问题,可以重新定义ObjectOutputStream的writeStreamHeader()方法,这样的话如果是以附加方式来写入对象,就不再重复写入流头:
ObjectOutputStream objOutputStream (new FileOutputStream(file,true))
{
protected void writeStreamHeader() throws IOException{}
}; [/size]


[size=large][color=blue]InputStreamReader 和 OutputStreamReader : [/color]
1. 若想对InputStream和OutputStream进行字符处理,可以使用java.io.InputStreamWriter和java.io.OuputStreamReader为其加上字符处理的功能,它们分别为Writer和Reader类的子类。比如当我们要显示纯文本文件的内容时,不用再费心地自行判断字符编码(比如我们前面的例子里需要自行的判断是ASCII英文字母还是BIG5中文字),只要将InputStream、OutputStream的实例作为构建InputStreamReader、OutputStreamReader时的变量,就可以操作InputStreamReader和OutputStreamWriter来进行文本文件的读取,让它们帮我们做字符判断与转换的动作。
为了达到更高效率,考虑用 BufferedReader 封装 InputStreamReader ,
BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); [/size]
1.package ysu.hxy;  
2.import java.io.*;
3.
4.public class StreamReaderWriterDemo
5.{
6. public static void main(String[] args)
7. {
8. try
9. {
10. File file = new File(args[0]);
11.
12. FileInputStream fileInputStream = new FileInputStream(file);
13.
14. //为FileInputStream加上字符处理功能
15. InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
16.
17. FileOutputStream fileOutputStream = new FileOutputStream("backup_"+args[0]);
18. //为FileOutputStream加上字条处理功能
19. OutputStreamWriter outputStreamWriter= new OutputStreamWriter(fileOutputStream);
20.
21. int ch = 0;
22. //以字符方式显示文件内容
23. while((ch = inputStreamReader.read()) != -1)
24. {
25. System.out.print((char) ch);
26. outputStreamWriter.write(ch);
27. }
28.
29. System.out.println();
30.
31. inputStreamReader.close();
32. outputStreamWriter.close();
33. }
34. catch(ArrayIndexOutOfBoundsException e)
35. {
36. System.out.println("没有指定文件");
37. }
38. catch(IOException e)
39. {
40. e.printStackTrace();
41. }
42. }
43.}

[size=large]运行结果:D:\hxy>java ysu.hxy.StreamReaderWriterDemo test.txt
a这b是c一d个e测f试z

并且会在当前目录下创建另一个文件:backup_test.txt,内容与test.txt相同。

2. InputStreamReader和OutputStreamWriter可以分别以任何InputStream、OutputStream子类的实例作为构建对象时的变量。InputStreamReader和OutputStreamWriter在存取时以系统的默认字符编码来进行字符转换,也可以自行指定字符编码。如以下语句将指定读取文件时的字符编码为BIG5:

InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream,"BIG5");[/size]


[size=large][color=blue]FileReader和FileWriter:[/color]
1. 如果想要存取的是一个文本文件,可以直接使用FileReader和FileWriter类,它们分别继承自InputStreamReader和OutputStreamReader。可以直接指定文件名称或File对象来打开指定的文本文件,并读入流转换后的字符,字符的转换会根据系统默认的编码(如果需要指定编码,则还是使用InputStreamReader和OutputStreamReader).

2. FileReader和FileWriter的使用很简单。下面举个例子。在Linux下编写的文本文件,其断行字符是\n,而在Windows下编写的文本文件其断行是\r和\n两个连接字符。如果在Windows下使用记事本打开一个Linux下编写的文本文件,其在显示上并不会有断行的效果,且\n字符会被用一个黑色方块来显示。下面的示例可以读入Linux下编写的文本文件,再写入另一个文件。在读取过程中若遇到\n字符,就取代为\r和\n两个连接字符,这样新的文件在Windows的记事本程序中,就可以有断行显示的效果。[/size]
1.package ysu.hxy;  
2.import java.util.*;
3.import java.io.*;
4.
5.public class FileReaderWriterDemo
6.{
7. public static void main(String[] args)
8. {
9. try
10. {
11. FileReader fileReader = new FileReader(args[0]);
12. FileWriter fileWriter = new FileWriter(args[0]+".txt");
13.
14. int in = 0;
15. char[] wlnChar = {'\r','\n'};
16. while((in = fileReader.read())!=-1)
17. {
18. if(in == '\n')
19. {
20. //写入"\r\n"
21. fileWriter.write(wlnChar);
22. }
23. else
24. {
25. fileWriter.write(in);
26. }
27. }
28. fileReader.close();
29. fileWriter.close();
30. }
31. catch(ArrayIndexOutOfBoundsException e)
32. {
33. System.out.println("请指定文件!");
34. }
35. catch(IOException e)
36. {
37. e.printStackTrace();
38. }
39. }
40.}



[size=large][color=blue]BufferedReader和BufferedWriter:[/color]
1. java.io.BufferedReader和java.io.BufferedWriter类各拥有8192字符的缓冲区。当BufferedReader在读取文本文件时,会先尽量从文件中读入字符数据并置入缓冲区,而之后若使用read()方法,会先从缓冲区中进行读取。如果缓冲区数据不足,才会再从文件中读取,使用BufferedWriter时,写入的数据并不会先输出到目的地,而是先存储至缓冲区中。如果缓冲区中的数据满了,才会一次对目的地进行写出。

2. 从标准输入流System.in中直接读取使用者输入时,使用者每输入一个字符,System.in就读取一个字符。为了能一次读取一行使用者的输入,使用了BufferedReader来对使用者输入的字符进行缓冲。readLine()方法会在读取到使用者的换行字符时,再一次将整行字符串传入。

3. System.in是一个位流,为了转换为字符流,可使用InputStreamReader为其进行字符转换,然后再使用BufferedReader为其增加缓冲功能。例如:
Java代码
1.BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
下面的示例示范了BufferedReader和BufferedWriter的使用。可以在文字模式下输入字符,程序会将输入的文字存储至指定的文件中,如果要结束程序,输入quit字符串即可。[/size]
1.package ysu.hxy;  
2.import java.util.*;
3.import java.io.*;
4.
5.public class BufferedReaderWriterDemo
6.{
7. public static void main(String[] args)
8. {
9. try
10. {
11. //缓冲System.in输入流
12. //System.in是位流,可以通过InputStreamReader将其转换为字符流
13. BufferedReader bufReader = new BufferedReader(new InputStreamReader(System.in));
14. //缓冲FileWriter
15. BufferedWriter bufWriter = new BufferedWriter(new FileWriter(args[0]));
16.
17. String input = null;
18.
19. //每读一行进行一次写入动作
20. while(!(input = bufReader.readLine()).equals("quit"))
21. {
22. bufWriter.write(input);
23. //newLine()方法写入与操作系统相依的换行字符,依执行环境当时的OS来决定该输出那种换行字符
24. bufWriter.newLine();
25. }
26. bufReader.close();
27. bufWriter.close();
28. }
29. catch(ArrayIndexOutOfBoundsException e)
30. {
31. System.out.println("没有指定文件");
32. }
33. catch(IOException e)
34. {
35. e.printStackTrace();
36. }
37. }
38.}


[size=large][color=blue]StringReader和StringWriter:[/color]
其源为一个字符串的字符流。 [/size]
01.package cn.itcast.stringstream;  
02.import java.io.IOException;
03.import java.io.StringReader;
04.import java.io.StringWriter;
05.public class StringStreamTest {
06. public static void main(String[] args) {
07. String str = "abcdefghijklmn";
08. transform(str);
09. }
10. public static void transform(String str) {
11. StringReader sr = new StringReader(str);
12. StringWriter sw = new StringWriter();
13. char[] chars = new char[1024];
14. try {
15. int len = 0;
16. while ((len = sr.read(chars)) != -1) {//将字符读入数组
17. String strRead = new String(chars, 0, len).toUpperCase();
18. System.out.println(strRead);
19. sw.write(strRead);
20. sw.flush();
21. }
22. sr.close();
23. sw.close();
24. } catch (IOException e) {
25. e.printStackTrace();
26. } finally {
27. sr.close();
28. try {
29. sw.close();
30. } catch (IOException e) {
31. e.printStackTrace();
32. }
33. }
34. }
35.}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值