BufferedReader的小例子
注意: BufferedReader只能接受字符流的缓冲区,因为每一个中文需要占据两个字节,所以需要将System.in这个字节输入流变为字符输入流,采用:
1 BufferedReader buf = new BufferedReader(
2 new InputStreamReader(System.in));
下面给一个实例:
3 import java.io.BufferedReader;
4 import java.io.IOException;
5 import java.io.InputStreamReader;
6
7 /**
8 * 使用缓冲区从键盘上读入内容
9 * */
10 public class BufferedReaderDemo{
11 public static void main(String[] args){
12 BufferedReader buf = new BufferedReader(
13 new InputStreamReader(System.in));
14 String str = null;
15 System.out.println("请输入内容");
16 try{
17 str = buf.readLine();
18 }catch(IOException e){
19 e.printStackTrace();
20 }
21 System.out.println("你输入的内容是:" + str);
22 }
23 }
运行结果:
请输入内容
dasdas
你输入的内容是:dasdas
Scanner类
其实我们比较常用的是采用Scanner类来进行数据输入,下面来给一个Scanner的例子吧
24 import java.util.Scanner;
25
26 /**
27 * Scanner的小例子,从键盘读数据
28 * */
29 public class ScannerDemo{
30 public static void main(String[] args){
31 Scanner sca = new Scanner(System.in);
32 // 读一个整数
33 int temp = sca.nextInt();
34 System.out.println(temp);
35 //读取浮点数
36 float flo=sca.nextFloat();
37 System.out.println(flo);
38 //读取字符
39 //...等等的,都是一些太基础的,就不师范了。
40 }
41 }
其实Scanner可以接受任何的输入流
下面给一个使用Scanner类从文件中读出内容
42 import java.io.File;
43 import java.io.FileNotFoundException;
44 import java.util.Scanner;
45
46 /**
47 * Scanner的小例子,从文件中读内容
48 * */
49 public class ScannerDemo{
50 public static void main(String[] args){
51
52 File file = new File("d:" + File.separator + "hello.txt");
53 Scanner sca = null;
54 try{
55 sca = new Scanner(file);
56 }catch(FileNotFoundException e){
57 e.printStackTrace();
58 }
59 String str = sca.next();
60 System.out.println("从文件中读取的内容是:" + str);
61 }
62 }
【运行结果】:
从文件中读取的内容是:这些文件中的内容哦!
数据操作流DataOutputStream、DataInputStream类
63 import java.io.DataOutputStream;
64 import java.io.File;
65 import java.io.FileOutputStream;
66 import java.io.IOException;
67
68 public class DataOutputStreamDemo{
69 public static void main(String[] args) throws IOException{
70 File file = new File("d:" + File.separator + "hello.txt");
71 char[] ch = { 'A', 'B', 'C' };
72 DataOutputStream out = null;
73 out = new DataOutputStream(new FileOutputStream(file));
74 for(char temp : ch){
75 out.writeChar(temp);
76 }
77 out.close();
78 }
79 }
A B C
现在我们在上面例子的基础上,使用DataInputStream读出内容
80 import java.io.DataInputStream;
81 import java.io.File;
82 import java.io.FileInputStream;
83 import java.io.IOException;
84
85 public class DataOutputStreamDemo{
86 public static void main(String[] args) throws IOException{
87 File file = new File("d:" + File.separator + "hello.txt");
88 DataInputStream input = new DataInputStream(new FileInputStream(file));
89 char[] ch = new char[10];
90 int count = 0;
91 char temp;
92 while((temp = input.readChar()) != 'C'){
93 ch[count++] = temp;
94 }
95 System.out.println(ch);
96 }
97 }
【运行结果】:
AB
合并流 SequenceInputStream
SequenceInputStream主要用来将2个流合并在一起,比如将两个txt中的内容合并为另外一个txt。下面给出一个实例:
98 import java.io.File;
99 import java.io.FileInputStream;
100 import java.io.FileOutputStream;
101 import java.io.IOException;
102 import java.io.InputStream;
103 import java.io.OutputStream;
104 import java.io.SequenceInputStream;
105
106 /**
107 * 将两个文本文件合并为另外一个文本文件
108 * */
109 public class SequenceInputStreamDemo{
110 public static void main(String[] args) throws IOException{
111 File file1 = new File("d:" + File.separator + "hello1.txt");
112 File file2 = new File("d:" + File.separator + "hello2.txt");
113 File file3 = new File("d:" + File.separator + "hello.txt");
114 InputStream input1 = new FileInputStream(file1);
115 InputStream input2 = new FileInputStream(file2);
116 OutputStream output = new FileOutputStream(file3);
117 // 合并流
118 SequenceInputStream sis = new SequenceInputStream(input1, input2);
119 int temp = 0;
120 while((temp = sis.read()) != -1){
121 output.write(temp);
122 }
123 input1.close();
124 input2.close();
125 output.close();
126 sis.close();
127 }
128 }
【运行结果】
结果会在hello.txt文件中包含hello1.txt和hello2.txt文件中的内容。
文件压缩 ZipOutputStream类
先举一个压缩单个文件的例子吧:
129 import java.io.File;
130 import java.io.FileInputStream;
131 import java.io.FileOutputStream;
132 import java.io.IOException;
133 import java.io.InputStream;
134 import java.util.zip.ZipEntry;
135 import java.util.zip.ZipOutputStream;
136
137 public class ZipOutputStreamDemo1{
138 public static void main(String[] args) throws IOException{
139 File file = new File("d:" + File.separator + "hello.txt");
140 File zipFile = new File("d:" + File.separator + "hello.zip");
141 InputStream input = new FileInputStream(file);
142 ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(
143 zipFile));
144 zipOut.putNextEntry(new ZipEntry(file.getName()));
145 // 设置注释
146 zipOut.setComment("hello");
147 int temp = 0;
148 while((temp = input.read()) != -1){
149 zipOut.write(temp);
150 }
151 input.close();
152 zipOut.close();
153 }
154 }
【运行结果】
运行结果之前,我创建了一个hello.txt的文件,原本大小56个字节,但是压缩之后产生hello.zip之后,居然变成了175个字节,有点搞不懂。
不过结果肯定是正确的,我只是提出我的一个疑问而已。
上面的这个例子测试的是压缩单个文件,下面的们来看看如何压缩多个文件。
155 import java.io.File;
156 import java.io.FileInputStream;
157 import java.io.FileOutputStream;
158 import java.io.IOException;
159 import java.io.InputStream;
160 import java.util.zip.ZipEntry;
161 import java.util.zip.ZipOutputStream;
162
163 /**
164 * 一次性压缩多个文件
165 * */
166 public class ZipOutputStreamDemo2{
167 public static void main(String[] args) throws IOException{
168 // 要被压缩的文件夹
169 File file = new File("d:" + File.separator + "temp");
170 File zipFile = new File("d:" + File.separator + "zipFile.zip");
171 InputStream input = null;
172 ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(
173 zipFile));
174 zipOut.setComment("hello");
175 if(file.isDirectory()){
176 File[] files = file.listFiles();
177 for(int i = 0; i < files.length; ++i){
178 input = new FileInputStream(files[i]);
179 zipOut.putNextEntry(new ZipEntry(file.getName()
180 + File.separator + files[i].getName()));
181 int temp = 0;
182 while((temp = input.read()) != -1){
183 zipOut.write(temp);
184 }
185 input.close();
186 }
187 }
188 zipOut.close();
189 }
190 }
【运行结果】
先看看要被压缩的文件吧:
接下来看看压缩之后的:
大家自然想到,既然能压缩,自然能解压缩,在谈解压缩之前,我们会用到一个ZipFile类,先给一个这个例子吧。java中的每一个压缩文件都是可以使用ZipFile来进行表示的
191 import java.io.File;
192 import java.io.IOException;
193 import java.util.zip.ZipFile;
194
195 /**
196 * ZipFile演示
197 * */
198 public class ZipFileDemo{
199 public static void main(String[] args) throws IOException{
200 File file = new File("d:" + File.separator + "hello.zip");
201 ZipFile zipFile = new ZipFile(file);
202 System.out.println("压缩文件的名称为:" + zipFile.getName());
203 }
204 }
【运行结果】:
压缩文件的名称为:d:\hello.zip
现在我们呢是时候来看看如何加压缩文件了,和之前一样,先让我们来解压单个压缩文件(也就是压缩文件中只有一个文件的情况),我们采用前面的例子产生的压缩文件hello.zip
205 import java.io.File;
206 import java.io.FileOutputStream;
207 import java.io.IOException;
208 import java.io.InputStream;
209 import java.io.OutputStream;
210 import java.util.zip.ZipEntry;
211 import java.util.zip.ZipFile;
212
213 /**
214 * 解压缩文件(压缩文件中只有一个文件的情况)
215 * */
216 public class ZipFileDemo2{
217 public static void main(String[] args) throws IOException{
218 File file = new File("d:" + File.separator + "hello.zip");
219 File outFile = new File("d:" + File.separator + "unZipFile.txt");
220 ZipFile zipFile = new ZipFile(file);
221 ZipEntry entry = zipFile.getEntry("hello.txt");
222 InputStream input = zipFile.getInputStream(entry);
223 OutputStream output = new FileOutputStream(outFile);
224 int temp = 0;
225 while((temp = input.read()) != -1){
226 output.write(temp);
227 }
228 input.close();
229 output.close();
230 }
231 }
【运行结果】:
解压缩之前:
这个压缩文件还是175字节
解压之后产生:
又回到了56字节,表示郁闷。
现在让我们来解压一个压缩文件中包含多个文件的情况吧
ZipInputStream类
当我们需要解压缩多个文件的时候,ZipEntry就无法使用了,如果想操作更加复杂的压缩文件,我们就必须使用ZipInputStream类
232 import java.io.File;
233 import java.io.FileInputStream;
234 import java.io.FileOutputStream;
235 import java.io.IOException;
236 import java.io.InputStream;
237 import java.io.OutputStream;
238 import java.util.zip.ZipEntry;
239 import java.util.zip.ZipFile;
240 import java.util.zip.ZipInputStream;
241
242 /**
243 * 解压缩一个压缩文件中包含多个文件的情况
244 * */
245 public class ZipFileDemo3{
246 public static void main(String[] args) throws IOException{
247 File file = new File("d:" + File.separator + "zipFile.zip");
248 File outFile = null;
249 ZipFile zipFile = new ZipFile(file);
250 ZipInputStream zipInput = new ZipInputStream(new FileInputStream(file));
251 ZipEntry entry = null;
252 InputStream input = null;
253 OutputStream output = null;
254 while((entry = zipInput.getNextEntry()) != null){
255 System.out.println("解压缩" + entry.getName() + "文件");
256 outFile = new File("d:" + File.separator + entry.getName());
257 if(!outFile.getParentFile().exists()){
258 outFile.getParentFile().mkdir();
259 }
260 if(!outFile.exists()){
261 outFile.createNewFile();
262 }
263 input = zipFile.getInputStream(entry);
264 output = new FileOutputStream(outFile);
265 int temp = 0;
266 while((temp = input.read()) != -1){
267 output.write(temp);
268 }
269 input.close();
270 output.close();
271 }
272 }
273 }
【运行结果】:
被解压的文件:
解压之后再D盘下会出现一个temp文件夹,里面内容:
PushBackInputStream回退流
274 import java.io.ByteArrayInputStream;
275 import java.io.IOException;
276 import java.io.PushbackInputStream;
277
278 /**
279 * 回退流操作
280 * */
281 public class PushBackInputStreamDemo{
282 public static void main(String[] args) throws IOException{
283 String str = "hello,rollenholt";
284 PushbackInputStream push = null;
285 ByteArrayInputStream bat = null;
286 bat = new ByteArrayInputStream(str.getBytes());
287 push = new PushbackInputStream(bat);
288 int temp = 0;
289 while((temp = push.read()) != -1){
290 if(temp == ','){
291 push.unread(temp);
292 temp = push.read();
293 System.out.print("(回退" + (char) temp + ") ");
294 }else{
295 System.out.print((char) temp);
296 }
297 }
298 }
299 }
【运行结果】:
hello(回退,) rollenholt
300 /**
301 * 取得本地的默认编码
302 * */
303 public class CharSetDemo{
304 public static void main(String[] args){
305 System.out.println("系统默认编码为:" + System.getProperty("file.encoding"));
306 }
307 }
【运行结果】:
系统默认编码为:GBK
乱码的产生:
308 import java.io.File;
309 import java.io.FileOutputStream;
310 import java.io.IOException;
311 import java.io.OutputStream;
312
313 /**
314 * 乱码的产生
315 * */
316 public class CharSetDemo2{
317 public static void main(String[] args) throws IOException{
318 File file = new File("d:" + File.separator + "hello.txt");
319 OutputStream out = new FileOutputStream(file);
320 byte[] bytes = "你好".getBytes("ISO8859-1");
321 out.write(bytes);
322 out.close();
323 }
324 }
【运行结果】:
??
一般情况下产生乱码,都是由于编码不一致的问题。
对象的序列化
对象序列化就是把一个对象变为二进制数据流的一种方法。
一个类要想被序列化,就行必须实现java.io.Serializable接口。虽然这个接口中没有任何方法,就如同之前的cloneable接口一样。实现了这个接口之后,就表示这个类具有被序列化的能力。
先让我们实现一个具有序列化能力的类吧:
325 import java.io.*;
326 /**
327 * 实现具有序列化能力的类
328 * */
329 public class SerializableDemo implements Serializable{
330 public SerializableDemo(){
331
332 }
333 public SerializableDemo(String name, int age){
334 this.name=name;
335 this.age=age;
336 }
337 @Override
338 public String toString(){
339 return "姓名:"+name+" 年龄:"+age;
340 }
341 private String name;
342 private int age;
343 }
这个类就具有实现序列化能力,
在继续将序列化之前,先将一下ObjectInputStream和ObjectOutputStream这两个类
先给一个ObjectOutputStream的例子吧:
344 import java.io.Serializable;
345 import java.io.File;
346 import java.io.FileOutputStream;
347 import java.io.IOException;
348 import java.io.ObjectOutputStream;
349
350 /**
351 * 实现具有序列化能力的类
352 * */
353 public class Person implements Serializable{
354 public Person(){
355
356 }
357
358 public Person(String name, int age){
359 this.name = name;
360 this.age = age;
361 }
362
363 @Override
364 public String toString(){
365 return "姓名:" + name + " 年龄:" + age;
366 }
367
368 private String name;
369 private int age;
370 }
371 /**
372 * 示范ObjectOutputStream
373 * */
374 public class ObjectOutputStreamDemo{
375 public static void main(String[] args) throws IOException{
376 File file = new File("d:" + File.separator + "hello.txt");
377 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
378 file));
379 oos.writeObject(new Person("rollen", 20));
380 oos.close();
381 }
382 }
【运行结果】:
当我们查看产生的hello.txt的时候,看到的是乱码,呵呵。因为是二进制文件。
虽然我们不能直接查看里面的内容,但是我们可以使用ObjectInputStream类查看:
383 import java.io.File;
384 import java.io.FileInputStream;
385 import java.io.ObjectInputStream;
386
387 /**
388 * ObjectInputStream示范
389 * */
390 public class ObjectInputStreamDemo{
391 public static void main(String[] args) throws Exception{
392 File file = new File("d:" + File.separator + "hello.txt");
393 ObjectInputStream input = new ObjectInputStream(new FileInputStream(
394 file));
395 Object obj = input.readObject();
396 input.close();
397 System.out.println(obj);
398 }
399 }
【运行结果】
姓名:rollen 年龄:20
到底序列化什么内容呢?
其实只有属性会被序列化。
Externalizable接口
被Serializable接口声明的类的对象的属性都将被序列化,但是如果想自定义序列化的内容的时候,就需要实现Externalizable接口。
当一个类要使用Externalizable这个接口的时候,这个类中必须要有一个无参的构造函数,如果没有的话,在构造的时候会产生异常,这是因为在反序列话的时候会默认调用无参的构造函数。
现在我们来演示一下序列化和反序列话:
400 package IO;
401
402 import java.io.Externalizable;
403 import java.io.File;
404 import java.io.FileInputStream;
405 import java.io.FileOutputStream;
406 import java.io.IOException;
407 import java.io.ObjectInput;
408 import java.io.ObjectInputStream;
409 import java.io.ObjectOutput;
410 import java.io.ObjectOutputStream;
411
412 /**
413 * 序列化和反序列化的操作
414 * */
415 public class ExternalizableDemo{
416 public static void main(String[] args) throws Exception{
417 ser(); // 序列化
418 dser(); // 反序列话
419 }
420
421 public static void ser() throws Exception{
422 File file = new File("d:" + File.separator + "hello.txt");
423 ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(
424 file));
425 out.writeObject(new Person("rollen", 20));
426 out.close();
427 }
428
429 public static void dser() throws Exception{
430 File file = new File("d:" + File.separator + "hello.txt");
431 ObjectInputStream input = new ObjectInputStream(new FileInputStream(
432 file));
433 Object obj = input.readObject();
434 input.close();
435 System.out.println(obj);
436 }
437 }
438
439 class Person implements Externalizable{
440 public Person(){
441
442 }
443
444 public Person(String name, int age){
445 this.name = name;
446 this.age = age;
447 }
448
449 @Override
450 public String toString(){
451 return "姓名:" + name + " 年龄:" + age;
452 }
453
454 // 复写这个方法,根据需要可以保存的属性或者具体内容,在序列化的时候使用
455 @Override
456 public void writeExternal(ObjectOutput out) throws IOException{
457 out.writeObject(this.name);
458 out.writeInt(age);
459 }
460
461 // 复写这个方法,根据需要读取内容 反序列话的时候需要
462 @Override
463 public void readExternal(ObjectInput in) throws IOException,
464 ClassNotFoundException{
465 this.name = (String) in.readObject();
466 this.age = in.readInt();
467 }
468
469 private String name;
470 private int age;
471 }
【运行结果】:
姓名:rollen 年龄:20
本例中,我们将全部的属性都保留了下来,
Serializable接口实现的操作其实是吧一个对象中的全部属性进行序列化,当然也可以使用我们上使用是Externalizable接口以实现部分属性的序列化,但是这样的操作比较麻烦,
当我们使用Serializable接口实现序列化操作的时候,如果一个对象的某一个属性不想被序列化保存下来,那么我们可以使用transient关键字进行说明:
下面举一个例子:
472 package IO;
473
474 import java.io.File;
475 import java.io.FileInputStream;
476 import java.io.FileOutputStream;
477 import java.io.ObjectInputStream;
478 import java.io.ObjectOutputStream;
479 import java.io.Serializable;
480
481 /**
482 * 序列化和反序列化的操作
483 * */
484 public class serDemo{
485 public static void main(String[] args) throws Exception{
486 ser(); // 序列化
487 dser(); // 反序列话
488 }
489
490 public static void ser() throws Exception{
491 File file = new File("d:" + File.separator + "hello.txt");
492 ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(
493 file));
494 out.writeObject(new Person1("rollen", 20));
495 out.close();
496 }
497
498 public static void dser() throws Exception{
499 File file = new File("d:" + File.separator + "hello.txt");
500 ObjectInputStream input = new ObjectInputStream(new FileInputStream(
501 file));
502 Object obj = input.readObject();
503 input.close();
504 System.out.println(obj);
505 }
506 }
507
508 class Person1 implements Serializable{
509 public Person1(){
510
511 }
512
513 public Person1(String name, int age){
514 this.name = name;
515 this.age = age;
516 }
517
518 @Override
519 public String toString(){
520 return "姓名:" + name + " 年龄:" + age;
521 }
522
523 // 注意这里
524 private transient String name;
525 private int age;
526 }
【运行结果】:
姓名:null 年龄:20
最后在给一个序列化一组对象的例子吧:
527 import java.io.File;
528 import java.io.FileInputStream;
529 import java.io.FileOutputStream;
530 import java.io.ObjectInputStream;
531 import java.io.ObjectOutputStream;
532 import java.io.Serializable;
533
534 /**
535 * 序列化一组对象
536 * */
537 public class SerDemo1{
538 public static void main(String[] args) throws Exception{
539 Student[] stu = { new Student("hello", 20), new Student("world", 30),
540 new Student("rollen", 40) };
541 ser(stu);
542 Object[] obj = dser();
543 for(int i = 0; i < obj.length; ++i){
544 Student s = (Student) obj[i];
545 System.out.println(s);
546 }
547 }
548
549 // 序列化
550 public static void ser(Object[] obj) throws Exception{
551 File file = new File("d:" + File.separator + "hello.txt");
552 ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(
553 file));
554 out.writeObject(obj);
555 out.close();
556 }
557
558 // 反序列化
559 public static Object[] dser() throws Exception{
560 File file = new File("d:" + File.separator + "hello.txt");
561 ObjectInputStream input = new ObjectInputStream(new FileInputStream(
562 file));
563 Object[] obj = (Object[]) input.readObject();
564 input.close();
565 return obj;
566 }
567 }
568
569 class Student implements Serializable{
570 public Student(){
571
572 }
573
574 public Student(String name, int age){
575 this.name = name;
576 this.age = age;
577 }
578
579 @Override
580 public String toString(){
581 return "姓名: " + name + " 年龄:" + age;
582 }
583
584 private String name;
585 private int age;
586 }
【运行结果】:
姓名: hello 年龄:20
姓名: world 年龄:30
姓名: rollen 年龄:40