java中的IO整理

2018/03/09 14:29
阅读数 12

写在前面:本文章基本覆盖了java IO的全部内容,java新IO没有涉及,因为我想和这个分开,以突出那个的重要性,新IO哪一篇文章还没有开始写,估计很快就能和大家见面。照旧,文章依旧以例子为主,因为讲解内容的java书很多了,我觉的学以致用才是真。代码是写出来的,不是看出来的。

最后欢迎大家提出意见和建议。

【案例1】创建一个新文件

1
2
3
4
5
6
7
8
9
10
11
import  java.io.*;
class  hello{
     public  static  void  main(String[] args) {
         File f= new  File( "D:\\hello.txt" );
         try {
             f.createNewFile();
         } catch  (Exception e) {
             e.printStackTrace();
         }
     }
}

 

【运行结果】:

 

程序运行之后,在d盘下会有一个名字为hello.txt的文件。

【案例2】File类的两个常量

1
2
3
4
5
6
7
import  java.io.*;
class  hello{
     public  static  void  main(String[] args) {
         System.out.println(File.separator);
         System.out.println(File.pathSeparator);
     }
}

 

【运行结果】:

\

;

此处多说几句:有些同学可能认为,我直接在windows下使用\进行分割不行吗?当然是可以的。但是在linux下就不是\了。所以,要想使得我们的代码跨平台,更加健壮,所以,大家都采用这两个常量吧,其实也多写不了几行。呵呵、

现在我们使用File类中的常量改写上面的代码:

 

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
import  java.io.*;
class  hello{
     public  static  void  main(String[] args) {
         String fileName= "D:" +File.separator+ "hello.txt" ;
         File f= new  File(fileName);
         try {
             f.createNewFile();
         } catch  (Exception e) {
             e.printStackTrace();
         }
     }
}

 

 

你看,没有多写多少吧,呵呵。所以建议使用File类中的常量。

 

 

 

删除一个文件

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
  * 删除一个文件
  * */
import  java.io.*;
class  hello{
     public  static  void  main(String[] args) {
         String fileName= "D:" +File.separator+ "hello.txt" ;
         File f= new  File(fileName);
         if (f.exists()){
             f.delete();
         } else {
             System.out.println( "文件不存在" );
         }
         
     }
}

 

 

创建一个文件夹

 

 

1
2
3
4
5
6
7
8
9
10
11
/**
  * 创建一个文件夹
  * */
import  java.io.*;
class  hello{
     public  static  void  main(String[] args) {
         String fileName= "D:" +File.separator+ "hello" ;
         File f= new  File(fileName);
         f.mkdir();
     }
}

 

 

【运行结果】:

 

D盘下多了一个hello文件夹

 

 

 

列出指定目录的全部文件(包括隐藏文件):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
  * 使用list列出指定目录的全部文件
  * */
import  java.io.*;
class  hello{
     public  static  void  main(String[] args) {
         String fileName= "D:" +File.separator;
         File f= new  File(fileName);
         String[] str=f.list();
         for  ( int  i =  0 ; i < str.length; i++) {
             System.out.println(str[i]);
         }
     }
}

 

【运行结果】:

 

$RECYCLE.BIN

 

360

 

360Downloads

 

360Rec

 

360SoftMove

 

Config.Msi

 

da

 

Downloads

 

DriversBackup

 

eclipse

 

java web整合开发和项目实战

 

Lenovo

 

MSOCache

 

Program

 

Program Files

 

python

 

RECYGLER.{8F92DA15-A229-A4D5-B5CE-5280C8B89C19}

 

System Volume Information

 

Tomcat6

 

var

 

vod_cache_data

 

新建文件夹

 

(你的运行结果应该和这个不一样的,呵呵)

 

但是使用list返回的是String数组,。而且列出的不是完整路径,如果想列出完整路径的话,需要使用listFiles.他返回的是File的数组

 

列出指定目录的全部文件(包括隐藏文件):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
  * 使用listFiles列出指定目录的全部文件
  * listFiles输出的是完整路径
  * */
import  java.io.*;
class  hello{
     public  static  void  main(String[] args) {
         String fileName= "D:" +File.separator;
         File f= new  File(fileName);
         File[] str=f.listFiles();
         for  ( int  i =  0 ; i < str.length; i++) {
             System.out.println(str[i]);
         }
     }
}

 

 

【运行结果】:

 

D:$RECYCLE.BIN

 

D:\360

 

D:\360Downloads

 

D:\360Rec

 

D:\360SoftMove

 

D:\Config.Msi

 

D:\da

 

D:\Downloads

 

D:\DriversBackup

 

D:\eclipse

 

D:\java web整合开发和项目实战

 

D:\Lenovo

 

D:\MSOCache

 

D:\Program

 

D:\Program Files

 

D:\python

 

D:\RECYGLER.{8F92DA15-A229-A4D5-B5CE-5280C8B89C19}

 

D:\System Volume Information

 

D:\Tomcat6

 

D:\var

 

D:\vod_cache_data

 

D:\新建文件夹

 

通过比较可以指定,使用listFiles更加方便、

 

 

 

判断一个指定的路径是否为目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
  * 使用isDirectory判断一个指定的路径是否为目录
  * */
import  java.io.*;
class  hello{
     public  static  void  main(String[] args) {
         String fileName= "D:" +File.separator;
         File f= new  File(fileName);
         if (f.isDirectory()){
             System.out.println( "YES" );
         } else {
             System.out.println( "NO" );
         }
     }
}

 

【运行结果】:YES

 

 

 

搜索指定目录的全部内容

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
  * 列出指定目录的全部内容
  * */
import  java.io.*;
class  hello{
     public  static  void  main(String[] args) {
         String fileName= "D:" +File.separator;
         File f= new  File(fileName);
         print(f);
     }
     public  static  void  print(File f){
         if (f!= null ){
             if (f.isDirectory()){
                 File[] fileArray=f.listFiles();
                 if (fileArray!= null ){
                     for  ( int  i =  0 ; i < fileArray.length; i++) {
                         //递归调用
                         print(fileArray[i]);
                     }
                 }
             }
             else {
                 System.out.println(f);
             }
         }
     }
}

 

 

【运行结果】:

 

D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\framepages\web4welcome_jsp.java

 

D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\help_005fhome_jsp.class

 

D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\help_005fhome_jsp.java

 

D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\home_jsp.class

 

D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\home_jsp.java

 

D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\index_jsp.class

 

D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\index_jsp.java

 

D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\login_jsp.class

 

D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\login_jsp.java

 

D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\modify_005fuser_005finfo_jsp.class

 

D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\modify_005fuser_005finfo_jsp.java

 

D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\register_005fnotify_jsp.class

 

D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\register_005fnotify_jsp.java

 

D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\sign_005fup_jsp.class

 

D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\sign_005fup_jsp.java

 

D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\transit_jsp.class

 

……

 

 

 

使用RandomAccessFile写入文件

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
  * 使用RandomAccessFile写入文件
  * */
import  java.io.*;
class  hello{
     public  static  void  main(String[] args)  throws  IOException {
         String fileName= "D:" +File.separator+ "hello.txt" ;
         File f= new  File(fileName);
         RandomAccessFile demo= new  RandomAccessFile(f, "rw" );
         demo.writeBytes( "asdsad" );
         demo.writeInt( 12 );
         demo.writeBoolean( true );
         demo.writeChar( 'A' );
         demo.writeFloat( 1 .21f);
         demo.writeDouble( 12.123 );
         demo.close();  
     }
}

 

 

如果你此时打开hello。txt查看的话,会发现那是乱码。

 

 

 

字节流

 

【向文件中写入字符串】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
  * 字节流
  * 向文件中写入字符串
  * */
import  java.io.*;
class  hello{
     public  static  void  main(String[] args)  throws  IOException {
         String fileName= "D:" +File.separator+ "hello.txt" ;
         File f= new  File(fileName);
         OutputStream out = new  FileOutputStream(f);
         String str= "你好" ;
         byte [] b=str.getBytes();
         out.write(b);
         out.close();
     }
}

 

查看hello.txt会看到“你好”

 

当然也可以一个字节一个字节的写。

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
  * 字节流
  * 向文件中一个字节一个字节的写入字符串
  * */
import  java.io.*;
class  hello{
     public  static  void  main(String[] args)  throws  IOException {
         String fileName= "D:" +File.separator+ "hello.txt" ;
         File f= new  File(fileName);
         OutputStream out = new  FileOutputStream(f);
         String str= "你好" ;
         byte [] b=str.getBytes();
         for  ( int  i =  0 ; i < b.length; i++) {
             out.write(b[i]);
         }
         out.close();
     }
}

 

 

结果还是:“你好”

 

 

 

向文件中追加新内容:

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
  * 字节流
  * 向文件中追加新内容:
  * */
import  java.io.*;
class  hello{
     public  static  void  main(String[] args)  throws  IOException {
         String fileName= "D:" +File.separator+ "hello.txt" ;
         File f= new  File(fileName);
         OutputStream out = new  FileOutputStream(f, true );
         String str= "Rollen" ;
         //String str="\r\nRollen";  可以换行
         byte [] b=str.getBytes();
         for  ( int  i =  0 ; i < b.length; i++) {
             out.write(b[i]);
         }
         out.close();
     }
}

 

 

【运行结果】:

 

你好Rollen

 

 

 

【读取文件内容】

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
  * 字节流
  * 读文件内容
  * */
import  java.io.*;
class  hello{
     public  static  void  main(String[] args)  throws  IOException {
         String fileName= "D:" +File.separator+ "hello.txt" ;
         File f= new  File(fileName);
         InputStream in= new  FileInputStream(f);
         byte [] b= new  byte [ 1024 ];
         in.read(b);
         in.close();
         System.out.println( new  String(b));
     }
}

 

 

【运行结果】

 

你好Rollen

 

Rollen_

 

但是这个例子读取出来会有大量的空格,我们可以利用in.read(b);的返回值来设计程序。如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
  * 字节流
  * 读文件内容
  * */
import  java.io.*;
class  hello{
     public  static  void  main(String[] args)  throws  IOException {
         String fileName= "D:" +File.separator+ "hello.txt" ;
         File f= new  File(fileName);
         InputStream in= new  FileInputStream(f);
         byte [] b= new  byte [ 1024 ];
         int  len=in.read(b);
         in.close();
         System.out.println( "读入长度为:" +len);
         System.out.println( new  String(b, 0 ,len));
     }
}

 

【运行结果】:

 

读入长度为:18

 

你好Rollen

 

Rollen

 

 

 

读者观察上面的例子可以看出,我们预先申请了一个指定大小的空间,但是有时候这个空间可能太小,有时候可能太大,我们需要准确的大小,这样节省空间,那么我们可以这样干:

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
  * 字节流
  * 读文件内容,节省空间
  * */
import  java.io.*;
class  hello{
     public  static  void  main(String[] args)  throws  IOException {
         String fileName= "D:" +File.separator+ "hello.txt" ;
         File f= new  File(fileName);
         InputStream in= new  FileInputStream(f);
         byte [] b= new  byte [( int )f.length()];
         in.read(b);
         System.out.println( "文件长度为:" +f.length());
         in.close();
         System.out.println( new  String(b));
     }
}

 

 

文件长度为:18

 

你好Rollen

 

Rollen

 

 

 

将上面的例子改为一个一个读:

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
  * 字节流
  * 读文件内容,节省空间
  * */
import  java.io.*;
class  hello{
     public  static  void  main(String[] args)  throws  IOException {
         String fileName= "D:" +File.separator+ "hello.txt" ;
         File f= new  File(fileName);
         InputStream in= new  FileInputStream(f);
         byte [] b= new  byte [( int )f.length()];
         for  ( int  i =  0 ; i < b.length; i++) {
             b[i]=( byte )in.read();
         }
         in.close();
         System.out.println( new  String(b));
     }
}

 

 

输出的结果和上面的一样。

 

 

 

细心的读者可能会发现,上面的几个例子都是在知道文件的内容多大,然后才展开的,有时候我们不知道文件有多大,这种情况下,我们需要判断是否独到文件的末尾。

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
  * 字节流
  *读文件
  * */
import  java.io.*;
class  hello{
     public  static  void  main(String[] args)  throws  IOException {
         String fileName= "D:" +File.separator+ "hello.txt" ;
         File f= new  File(fileName);
         InputStream in= new  FileInputStream(f);
         byte [] b= new  byte [ 1024 ];
         int  count = 0 ;
         int  temp= 0 ;
         while ((temp=in.read())!=(- 1 )){
             b[count++]=( byte )temp;
         }
         in.close();
         System.out.println( new  String(b));
     }
}

 

 

【运行结果】

 

你好Rollen

 

Rollen_

 

提醒一下,当独到文件末尾的时候会返回-1.正常情况下是不会返回-1的

 

 

 

字符流

 

【向文件中写入数据】

 

现在我们使用字符流

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
  * 字符流
  * 写入数据
  * */
import  java.io.*;
class  hello{
     public  static  void  main(String[] args)  throws  IOException {
         String fileName= "D:" +File.separator+ "hello.txt" ;
         File f= new  File(fileName);
         Writer out = new  FileWriter(f);
         String str= "hello" ;
         out.write(str);
         out.close();
     }
}

 

 

当你打开hello。txt的时候,会看到hello

 

其实这个例子上之前的例子没什么区别,只是你可以直接输入字符串,而不需要你将字符串转化为字节数组。

 

当你如果想问文件中追加内容的时候,可以使用将上面的声明out的哪一行换为:

 

Writer out =new FileWriter(f,true);

 

这样,当你运行程序的时候,会发现文件内容变为:

 

hellohello如果想在文件中换行的话,需要使用“\r\n”

 

比如将str变为String str="\r\nhello";

 

这样文件追加的str的内容就会换行了。

 

 

 

从文件中读内容:

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
  * 字符流
  * 从文件中读出内容
  * */
import  java.io.*;
class  hello{
     public  static  void  main(String[] args)  throws  IOException {
         String fileName= "D:" +File.separator+ "hello.txt" ;
         File f= new  File(fileName);
         char [] ch= new  char [ 100 ];
         Reader read= new  FileReader(f);
         int  count=read.read(ch);
         read.close();
         System.out.println( "读入的长度为:" +count);
         System.out.println( "内容为" + new  String(ch, 0 ,count));
     }
}

 

 

【运行结果】:

 

读入的长度为:17

 

内容为hellohello

 

hello

 

 

 

当然最好采用循环读取的方式,因为我们有时候不知道文件到底有多大。

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
  * 字符流
  * 从文件中读出内容
  * */
import  java.io.*;
class  hello{
     public  static  void  main(String[] args)  throws  IOException {
         String fileName= "D:" +File.separator+ "hello.txt" ;
         File f= new  File(fileName);
         char [] ch= new  char [ 100 ];
         Reader read= new  FileReader(f);
         int  temp= 0 ;
         int  count= 0 ;
         while ((temp=read.read())!=(- 1 )){
             ch[count++]=( char )temp;
         }
         read.close();
         System.out.println( "内容为" + new  String(ch, 0 ,count));
     }
}

 

 

运行结果:

 

内容为hellohello

 

hello

 

 

关于字节流和字符流的区别

 

实际上字节流在操作的时候本身是不会用到缓冲区的,是文件本身的直接操作的,但是字符流在操作的 时候下后是会用到缓冲区的,是通过缓冲区来操作文件的。

 

读者可以试着将上面的字节流和字符流的程序的最后一行关闭文件的代码注释掉,然后运行程序看看。你就会发现使用字节流的话,文件中已经存在内容,但是使用字符流的时候,文件中还是没有内容的,这个时候就要刷新缓冲区。

 

使用字节流好还是字符流好呢?

 

答案是字节流。首先因为硬盘上的所有文件都是以字节的形式进行传输或者保存的,包括图片等内容。但是字符只是在内存中才会形成的,所以在开发中,字节流使用广泛。

 

文件的复制

 

其实DOS下就有一个文件复制功能,比如我们想把d盘下面的hello.txt文件复制到d盘下面的rollen.txt文件中,那么我们就可以使用下面的命令:

 

copy d:\hello.txt d:\rollen.txt

 

 

 

运行之后你会在d盘中看见hello.txt.,并且两个文件的内容是一样的,(这是屁话)

 

 

 

下面我们使用程序来复制文件吧。

 

基本思路还是从一个文件中读入内容,边读边写入另一个文件,就是这么简单。、

 

首先编写下面的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
  * 文件的复制
  * */
import  java.io.*;
class  hello{
     public  static  void  main(String[] args)  throws  IOException {
         if (args.length!= 2 ){
             System.out.println( "命令行参数输入有误,请检查" );
             System.exit( 1 );
         }
         File file1= new  File(args[ 0 ]);
         File file2= new  File(args[ 1 ]);
         
         if (!file1.exists()){
             System.out.println( "被复制的文件不存在" );
             System.exit( 1 );
         }
         InputStream input= new  FileInputStream(file1);
         OutputStream output= new  FileOutputStream(file2);
         if ((input!= null )&&(output!= null )){
             int  temp= 0 ;
             while ((temp=input.read())!=(- 1 )){
                 output.write(temp);
             }
         }
         input.close();
         output.close();
     }
}

 

然后在命令行下面

 

javac hello.java

 

java hello d:\hello.txt d:\rollen.txt

 

现在你就会在d盘看到rollen。txt了,

 

 

 

 

 

 

 

OutputStreramWriter 和InputStreamReader类

 

整个IO类中除了字节流和字符流还包括字节和字符转换流。

 

OutputStreramWriter将输出的字符流转化为字节流

 

InputStreamReader将输入的字节流转换为字符流

 

但是不管如何操作,最后都是以字节的形式保存在文件中的。

 

 

 

将字节输出流转化为字符输出流

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
  * 将字节输出流转化为字符输出流
  * */
import  java.io.*;
class  hello{
     public  static  void  main(String[] args)  throws  IOException {
         String fileName=  "d:" +File.separator+ "hello.txt" ;
         File file= new  File(fileName);
         Writer out= new  OutputStreamWriter( new  FileOutputStream(file));
         out.write( "hello" );
         out.close();
     }
}

 

 

运行结果:文件中内容为:hello

 

将字节输入流变为字符输入流

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
  * 将字节输入流变为字符输入流
  * */
import  java.io.*;
class  hello{
     public  static  void  main(String[] args)  throws  IOException {
         String fileName=  "d:" +File.separator+ "hello.txt" ;
         File file= new  File(fileName);
         Reader read= new  InputStreamReader( new  FileInputStream(file));
         char [] b= new  char [ 100 ];
         int  len=read.read(b);
         System.out.println( new  String(b, 0 ,len));
         read.close();
     }
}

 

 

【运行结果】:hello

 

前面列举的输出输入都是以文件进行的,现在我们以内容为输出输入目的地,使用内存操作流

 

ByteArrayInputStream 主要将内容写入内容

 

ByteArrayOutputStream  主要将内容从内存输出

 

使用内存操作流将一个大写字母转化为小写字母

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
  * 使用内存操作流将一个大写字母转化为小写字母
  * */
import  java.io.*;
class  hello{
     public  static  void  main(String[] args)  throws  IOException {
         String str= "ROLLENHOLT" ;
         ByteArrayInputStream input= new  ByteArrayInputStream(str.getBytes());
         ByteArrayOutputStream output= new  ByteArrayOutputStream();
         int  temp= 0 ;
         while ((temp=input.read())!=- 1 ){
             char  ch=( char )temp;
             output.write(Character.toLowerCase(ch));
         }
         String outStr=output.toString();
         input.close();
         output.close();
         System.out.println(outStr);
     }
}

 

 

【运行结果】:

 

rollenholt

 

内容操作流一般使用来生成一些临时信息采用的,这样可以避免删除的麻烦。

 

管道流

 

管道流主要可以进行两个线程之间的通信。

 

PipedOutputStream 管道输出流

 

PipedInputStream 管道输入流

 

验证管道流
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/**
  * 验证管道流
  * */
import  java.io.*;
 
/**
  * 消息发送类
  * */
class  Send  implements  Runnable{
     private  PipedOutputStream out= null ;
     public  Send() {
         out= new  PipedOutputStream();
     }
     public  PipedOutputStream getOut(){
         return  this .out;
     }
     public  void  run(){
         String message= "hello , Rollen" ;
         try {
             out.write(message.getBytes());
         } catch  (Exception e) {
             e.printStackTrace();
         } try {
             out.close();
         } catch  (Exception e) {
             e.printStackTrace();
         }
     }
}
 
/**
  * 接受消息类
  * */
class  Recive  implements  Runnable{
     private  PipedInputStream input= null ;
     public  Recive(){
         this .input= new  PipedInputStream();
     }
     public  PipedInputStream getInput(){
         return  this .input;
     }
     public  void  run(){
         byte [] b= new  byte [ 1000 ];
         int  len= 0 ;
         try {
             len= this .input.read(b);
         } catch  (Exception e) {
             e.printStackTrace();
         } try {
             input.close();
         } catch  (Exception e) {
             e.printStackTrace();
         }
         System.out.println( "接受的内容为 " +( new  String(b, 0 ,len)));
     }
}
/**
  * 测试类
  * */
class  hello{
     public  static  void  main(String[] args)  throws  IOException {
         Send send= new  Send();
         Recive recive= new  Recive();
         try {
//管道连接
             send.getOut().connect(recive.getInput());
         } catch  (Exception e) {
             e.printStackTrace();
         }
         new  Thread(send).start();
         new  Thread(recive).start();
     }
}

 

【运行结果】:

 

接受的内容为 hello , Rollen

 

打印流

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
  * 使用PrintStream进行输出
  * */
import  java.io.*;
 
class  hello {
     public  static  void  main(String[] args)  throws  IOException {
         PrintStream print =  new  PrintStream( new  FileOutputStream( new  File( "d:"
                 + File.separator +  "hello.txt" )));
         print.println( true );
         print.println( "Rollen" );
         print.close();
     }
}

 

 

【运行结果】:

 

true

 

Rollen

 

当然也可以格式化输出

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
  * 使用PrintStream进行输出
  * 并进行格式化
  * */
import  java.io.*;
class  hello {
     public  static  void  main(String[] args)  throws  IOException {
         PrintStream print =  new  PrintStream( new  FileOutputStream( new  File( "d:"
                 + File.separator +  "hello.txt" )));
         String name= "Rollen" ;
         int  age= 20 ;
         print.printf( "姓名:%s. 年龄:%d." ,name,age);
         print.close();
     }
}

 

 

【运行结果】:

 

姓名:Rollen. 年龄:20.

 

 

 

使用OutputStream向屏幕上输出内容

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
  * 使用OutputStream向屏幕上输出内容
  * */
import  java.io.*;
class  hello {
     public  static  void  main(String[] args)  throws  IOException {
         OutputStream out=System.out;
         try {
             out.write( "hello" .getBytes());
         } catch  (Exception e) {
             e.printStackTrace();
         }
         try {
             out.close();
         } catch  (Exception e) {
             e.printStackTrace();
         }
     }
}

 

 

【运行结果】:

 

hello

 

 

 

输入输出重定向

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import  java.io.File;
import  java.io.FileNotFoundException;
import  java.io.FileOutputStream;
import  java.io.PrintStream;
 
/**
  * 为System.out.println()重定向输出
  * */
public  class  systemDemo{
     public  static  void  main(String[] args){
         // 此刻直接输出到屏幕
         System.out.println( "hello" );
         File file =  new  File( "d:"  + File.separator +  "hello.txt" );
         try {
             System.setOut( new  PrintStream( new  FileOutputStream(file)));
         } catch (FileNotFoundException e){
             e.printStackTrace();
         }
         System.out.println( "这些内容在文件中才能看到哦!" );
     }
}

 

 

【运行结果】:

eclipse的控制台输出的是hello。然后当我们查看d盘下面的hello.txt文件的时候,会在里面看到:这些内容在文件中才能看到哦!

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import  java.io.File;
import  java.io.FileNotFoundException;
import  java.io.FileOutputStream;
import  java.io.PrintStream;
 
/**
  * System.err重定向 这个例子也提示我们可以使用这种方法保存错误信息
  * */
public  class  systemErr{
     public  static  void  main(String[] args){
         File file =  new  File( "d:"  + File.separator +  "hello.txt" );
         System.err.println( "这些在控制台输出" );
         try {
             System.setErr( new  PrintStream( new  FileOutputStream(file)));
         } catch (FileNotFoundException e){
             e.printStackTrace();
         }
         System.err.println( "这些在文件中才能看到哦!" );
     }
}

 

 

【运行结果】:

 

你会在eclipse的控制台看到红色的输出:“这些在控制台输出”,然后在d盘下面的hello.txt中会看到:这些在文件中才能看到哦!

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import  java.io.File;
import  java.io.FileInputStream;
import  java.io.FileNotFoundException;
import  java.io.IOException;
 
/**
  * System.in重定向
  * */
public  class  systemIn{
     public  static  void  main(String[] args){
         File file =  new  File( "d:"  + File.separator +  "hello.txt" );
         if (!file.exists()){
             return ;
         } else {
             try {
                 System.setIn( new  FileInputStream(file));
             } catch (FileNotFoundException e){
                 e.printStackTrace();
             }
             byte [] bytes =  new  byte [ 1024 ];
             int  len =  0 ;
             try {
                 len = System.in.read(bytes);
             } catch (IOException e){
                 e.printStackTrace();
             }
             System.out.println( "读入的内容为:"  new  String(bytes,  0 , len));
         }
     }
}

 

 

【运行结果】:

 

前提是我的d盘下面的hello.txt中的内容是:“这些文件中的内容哦!”,然后运行程序,输出的结果为:读入的内容为:这些文件中的内容哦!

 

 

 

BufferedReader的小例子

 

注意: BufferedReader只能接受字符流的缓冲区,因为每一个中文需要占据两个字节,所以需要将System.in这个字节输入流变为字符输入流,采用:

 

 

BufferedReader buf = new  BufferedReader(
                 new  InputStreamReader(System.in));

 

 

下面给一个实例:

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import  java.io.BufferedReader;
import  java.io.IOException;
import  java.io.InputStreamReader;
 
/**
  * 使用缓冲区从键盘上读入内容
  * */
public  class  BufferedReaderDemo{
     public  static  void  main(String[] args){
         BufferedReader buf =  new  BufferedReader(
                 new  InputStreamReader(System.in));
         String str =  null ;
         System.out.println( "请输入内容" );
         try {
             str = buf.readLine();
         } catch (IOException e){
             e.printStackTrace();
         }
         System.out.println( "你输入的内容是:"  + str);
     }
}

 

 

运行结果:

 

请输入内容

 

dasdas

 

你输入的内容是:dasdas

 

 

 

Scanner类

 

其实我们比较常用的是采用Scanner类来进行数据输入,下面来给一个Scanner的例子吧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import  java.util.Scanner;
 
/**
  * Scanner的小例子,从键盘读数据
  * */
public  class  ScannerDemo{
     public  static  void  main(String[] args){
         Scanner sca =  new  Scanner(System.in);
         // 读一个整数
         int  temp = sca.nextInt();
         System.out.println(temp);
         //读取浮点数
         float  flo=sca.nextFloat();
         System.out.println(flo);
         //读取字符
         //...等等的,都是一些太基础的,就不师范了。
     }
}

 

其实Scanner可以接受任何的输入流

 

下面给一个使用Scanner类从文件中读出内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import  java.io.File;
import  java.io.FileNotFoundException;
import  java.util.Scanner;
 
/**
  * Scanner的小例子,从文件中读内容
  * */
public  class  ScannerDemo{
     public  static  void  main(String[] args){
 
         File file =  new  File( "d:"  + File.separator +  "hello.txt" );
         Scanner sca =  null ;
         try {
             sca =  new  Scanner(file);
         } catch (FileNotFoundException e){
             e.printStackTrace();
         }
         String str = sca.next();
         System.out.println( "从文件中读取的内容是:"  + str);
     }
}

 

【运行结果】:

 

从文件中读取的内容是:这些文件中的内容哦!

 

数据操作流DataOutputStream、DataInputStream类

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import  java.io.DataOutputStream;
import  java.io.File;
import  java.io.FileOutputStream;
import  java.io.IOException;
 
public  class  DataOutputStreamDemo{
     public  static  void  main(String[] args)  throws  IOException{
         File file =  new  File( "d:"  + File.separator +  "hello.txt" );
         char [] ch = {  'A' 'B' 'C'  };
         DataOutputStream out =  null ;
         out =  new  DataOutputStream( new  FileOutputStream(file));
         for ( char  temp : ch){
             out.writeChar(temp);
         }
         out.close();
     }
}

 

 

A B C

 

现在我们在上面例子的基础上,使用DataInputStream读出内容

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import  java.io.DataInputStream;
import  java.io.File;
import  java.io.FileInputStream;
import  java.io.IOException;
 
public  class  DataOutputStreamDemo{
     public  static  void  main(String[] args)  throws  IOException{
         File file =  new  File( "d:"  + File.separator +  "hello.txt" );
         DataInputStream input =  new  DataInputStream( new  FileInputStream(file));
         char [] ch =  new  char [ 10 ];
         int  count =  0 ;
         char  temp;
         while ((temp = input.readChar()) !=  'C' ){
             ch[count++] = temp;
         }
         System.out.println(ch);
     }
}

 

 

【运行结果】:

 

AB

 

合并流 SequenceInputStream

 

SequenceInputStream主要用来将2个流合并在一起,比如将两个txt中的内容合并为另外一个txt。下面给出一个实例:

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import  java.io.File;
import  java.io.FileInputStream;
import  java.io.FileOutputStream;
import  java.io.IOException;
import  java.io.InputStream;
import  java.io.OutputStream;
import  java.io.SequenceInputStream;
 
/**
  * 将两个文本文件合并为另外一个文本文件
  * */
public  class  SequenceInputStreamDemo{
     public  static  void  main(String[] args)  throws  IOException{
         File file1 =  new  File( "d:"  + File.separator +  "hello1.txt" );
         File file2 =  new  File( "d:"  + File.separator +  "hello2.txt" );
         File file3 =  new  File( "d:"  + File.separator +  "hello.txt" );
         InputStream input1 =  new  FileInputStream(file1);
         InputStream input2 =  new  FileInputStream(file2);
         OutputStream output =  new  FileOutputStream(file3);
         // 合并流
         SequenceInputStream sis =  new  SequenceInputStream(input1, input2);
         int  temp =  0 ;
         while ((temp = sis.read()) != - 1 ){
             output.write(temp);
         }
         input1.close();
         input2.close();
         output.close();
         sis.close();
     }
}

 

 

【运行结果】

 

结果会在hello.txt文件中包含hello1.txt和hello2.txt文件中的内容。

 

文件压缩 ZipOutputStream类

 

 

先举一个压缩单个文件的例子吧:

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import  java.io.File;
import  java.io.FileInputStream;
import  java.io.FileOutputStream;
import  java.io.IOException;
import  java.io.InputStream;
import  java.util.zip.ZipEntry;
import  java.util.zip.ZipOutputStream;
 
public  class  ZipOutputStreamDemo1{
     public  static  void  main(String[] args)  throws  IOException{
         File file =  new  File( "d:"  + File.separator +  "hello.txt" );
         File zipFile =  new  File( "d:"  + File.separator +  "hello.zip" );
         InputStream input =  new  FileInputStream(file);
         ZipOutputStream zipOut =  new  ZipOutputStream( new  FileOutputStream(
                 zipFile));
         zipOut.putNextEntry( new  ZipEntry(file.getName()));
         // 设置注释
         zipOut.setComment( "hello" );
         int  temp =  0 ;
         while ((temp = input.read()) != - 1 ){
             zipOut.write(temp);
         }
         input.close();
         zipOut.close();
     }
}

 

 

【运行结果】

 

运行结果之前,我创建了一个hello.txt的文件,原本大小56个字节,但是压缩之后产生hello.zip之后,居然变成了175个字节,有点搞不懂。

 

不过结果肯定是正确的,我只是提出我的一个疑问而已。

 

 

 

上面的这个例子测试的是压缩单个文件,下面的们来看看如何压缩多个文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import  java.io.File;
import  java.io.FileInputStream;
import  java.io.FileOutputStream;
import  java.io.IOException;
import  java.io.InputStream;
import  java.util.zip.ZipEntry;
import  java.util.zip.ZipOutputStream;
 
/**
  * 一次性压缩多个文件
  * */
public  class  ZipOutputStreamDemo2{
     public  static  void  main(String[] args)  throws  IOException{
         // 要被压缩的文件夹
         File file =  new  File( "d:"  + File.separator +  "temp" );
         File zipFile =  new  File( "d:"  + File.separator +  "zipFile.zip" );
         InputStream input =  null ;
         ZipOutputStream zipOut =  new  ZipOutputStream( new  FileOutputStream(
                 zipFile));
         zipOut.setComment( "hello" );
         if (file.isDirectory()){
             File[] files = file.listFiles();
             for ( int  i =  0 ; i < files.length; ++i){
                 input =  new  FileInputStream(files[i]);
                 zipOut.putNextEntry( new  ZipEntry(file.getName()
                         + File.separator + files[i].getName()));
                 int  temp =  0 ;
                 while ((temp = input.read()) != - 1 ){
                     zipOut.write(temp);
                 }
                 input.close();
             }
         }
         zipOut.close();
     }
}

 

【运行结果】

 

先看看要被压缩的文件吧:

 

接下来看看压缩之后的:

 

大家自然想到,既然能压缩,自然能解压缩,在谈解压缩之前,我们会用到一个ZipFile类,先给一个这个例子吧。java中的每一个压缩文件都是可以使用ZipFile来进行表示的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import  java.io.File;
import  java.io.IOException;
import  java.util.zip.ZipFile;
 
/**
  * ZipFile演示
  * */
public  class  ZipFileDemo{
     public  static  void  main(String[] args)  throws  IOException{
         File file =  new  File( "d:"  + File.separator +  "hello.zip" );
         ZipFile zipFile =  new  ZipFile(file);
         System.out.println( "压缩文件的名称为:"  + zipFile.getName());
     }
}

 

【运行结果】:

 

压缩文件的名称为:d:\hello.zip

 

 

 

现在我们呢是时候来看看如何加压缩文件了,和之前一样,先让我们来解压单个压缩文件(也就是压缩文件中只有一个文件的情况),我们采用前面的例子产生的压缩文件hello.zip

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import  java.io.File;
import  java.io.FileOutputStream;
import  java.io.IOException;
import  java.io.InputStream;
import  java.io.OutputStream;
import  java.util.zip.ZipEntry;
import  java.util.zip.ZipFile;
 
/**
  * 解压缩文件(压缩文件中只有一个文件的情况)
  * */
public  class  ZipFileDemo2{
     public  static  void  main(String[] args)  throws  IOException{
         File file =  new  File( "d:"  + File.separator +  "hello.zip" );
         File outFile =  new  File( "d:"  + File.separator +  "unZipFile.txt" );
         ZipFile zipFile =  new  ZipFile(file);
         ZipEntry entry = zipFile.getEntry( "hello.txt" );
         InputStream input = zipFile.getInputStream(entry);
         OutputStream output =  new  FileOutputStream(outFile);
         int  temp =  0 ;
         while ((temp = input.read()) != - 1 ){
             output.write(temp);
         }
         input.close();
         output.close();
     }
}

 

【运行结果】:

 

解压缩之前:

 

这个压缩文件还是175字节

 

解压之后产生:

 

 

又回到了56字节,表示郁闷。

 

 

 

现在让我们来解压一个压缩文件中包含多个文件的情况吧

 

ZipInputStream类

 

当我们需要解压缩多个文件的时候,ZipEntry就无法使用了,如果想操作更加复杂的压缩文件,我们就必须使用ZipInputStream类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import  java.io.File;
import  java.io.FileInputStream;
import  java.io.FileOutputStream;
import  java.io.IOException;
import  java.io.InputStream;
import  java.io.OutputStream;
import  java.util.zip.ZipEntry;
import  java.util.zip.ZipFile;
import  java.util.zip.ZipInputStream;
 
/**
  * 解压缩一个压缩文件中包含多个文件的情况
  * */
public  class  ZipFileDemo3{
     public  static  void  main(String[] args)  throws  IOException{
         File file =  new  File( "d:"  + File.separator +  "zipFile.zip" );
         File outFile =  null ;
         ZipFile zipFile =  new  ZipFile(file);
         ZipInputStream zipInput =  new  ZipInputStream( new  FileInputStream(file));
         ZipEntry entry =  null ;
         InputStream input =  null ;
         OutputStream output =  null ;
         while ((entry = zipInput.getNextEntry()) !=  null ){
             System.out.println( "解压缩"  + entry.getName() +  "文件" );
             outFile =  new  File( "d:"  + File.separator + entry.getName());
             if (!outFile.getParentFile().exists()){
                 outFile.getParentFile().mkdir();
             }
             if (!outFile.exists()){
                 outFile.createNewFile();
             }
             input = zipFile.getInputStream(entry);
             output =  new  FileOutputStream(outFile);
             int  temp =  0 ;
             while ((temp = input.read()) != - 1 ){
                 output.write(temp);
             }
             input.close();
             output.close();
         }
     }
}

 

【运行结果】:

 

被解压的文件:

 

解压之后再D盘下会出现一个temp文件夹,里面内容:

 

 

PushBackInputStream回退流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import  java.io.ByteArrayInputStream;
import  java.io.IOException;
import  java.io.PushbackInputStream;
 
/**
  * 回退流操作
  * */
public  class  PushBackInputStreamDemo{
     public  static  void  main(String[] args)  throws  IOException{
         String str =  "hello,rollenholt" ;
         PushbackInputStream push =  null ;
         ByteArrayInputStream bat =  null ;
         bat =  new  ByteArrayInputStream(str.getBytes());
         push =  new  PushbackInputStream(bat);
         int  temp =  0 ;
         while ((temp = push.read()) != - 1 ){
             if (temp ==  ',' ){
                 push.unread(temp);
                 temp = push.read();
                 System.out.print( "(回退"  + ( char ) temp +  ") " );
             } else {
                 System.out.print(( char ) temp);
             }
         }
     }
}

 

【运行结果】:

 

hello(回退,) rollenholt

 

 

 

 

1
2
3
4
5
6
7
8
/**
  * 取得本地的默认编码
  * */
public  class  CharSetDemo{
     public  static  void  main(String[] args){
         System.out.println( "系统默认编码为:"  + System.getProperty( "file.encoding" ));
     }
}

 

 

【运行结果】:

 

系统默认编码为:GBK

 

 

 

乱码的产生:

import  java.io.File;
import  java.io.FileOutputStream;
import  java.io.IOException;
import  java.io.OutputStream;
 
/**
  * 乱码的产生
  * */
public  class  CharSetDemo2{
     public  static  void  main(String[] args) throws  IOException{
         File file = new  File( "d:"  + File.separator + "hello.txt" );
         OutputStream out = new  FileOutputStream(file);
         byte [] bytes = "你好" .getBytes( "ISO8859-1" );
         out.write(bytes);
         out.close();
     }
}

 

【运行结果】:

 

??

 

 

 

一般情况下产生乱码,都是由于编码不一致的问题。

 

对象的序列化

 

对象序列化就是把一个对象变为二进制数据流的一种方法。

 

一个类要想被序列化,就行必须实现java.io.Serializable接口。虽然这个接口中没有任何方法,就如同之前的cloneable接口一样。实现了这个接口之后,就表示这个类具有被序列化的能力。

 

先让我们实现一个具有序列化能力的类吧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import  java.io.*;
/**
  * 实现具有序列化能力的类
  * */
public  class  SerializableDemo  implements  Serializable{
     public  SerializableDemo(){
         
     }
     public  SerializableDemo(String name,  int  age){
         this .name=name;
         this .age=age;
     }
     @Override
     public  String toString(){
         return  "姓名:" +name+ "  年龄:" +age;
     }
     private  String name;
     private  int  age;
}

 

这个类就具有实现序列化能力,

 

在继续将序列化之前,先将一下ObjectInputStream和ObjectOutputStream这两个类

 

先给一个ObjectOutputStream的例子吧:

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import  java.io.Serializable;
import  java.io.File;
import  java.io.FileOutputStream;
import  java.io.IOException;
import  java.io.ObjectOutputStream;
 
/**
  * 实现具有序列化能力的类
  * */
public  class  Person  implements  Serializable{
     public  Person(){
 
     }
 
     public  Person(String name,  int  age){
         this .name = name;
         this .age = age;
     }
 
     @Override
     public  String toString(){
         return  "姓名:"  + name +  "  年龄:"  + age;
     }
 
     private  String name;
     private  int  age;
}
/**
  * 示范ObjectOutputStream
  * */
public  class  ObjectOutputStreamDemo{
     public  static  void  main(String[] args)  throws  IOException{
         File file =  new  File( "d:"  + File.separator +  "hello.txt" );
         ObjectOutputStream oos =  new  ObjectOutputStream( new  FileOutputStream(
                 file));
         oos.writeObject( new  Person( "rollen" 20 ));
         oos.close();
     }
}

 

 

【运行结果】:

 

当我们查看产生的hello.txt的时候,看到的是乱码,呵呵。因为是二进制文件。

 

虽然我们不能直接查看里面的内容,但是我们可以使用ObjectInputStream类查看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import  java.io.File;
import  java.io.FileInputStream;
import  java.io.ObjectInputStream;
 
/**
  * ObjectInputStream示范
  * */
public  class  ObjectInputStreamDemo{
     public  static  void  main(String[] args)  throws  Exception{
         File file =  new  File( "d:"  + File.separator +  "hello.txt" );
         ObjectInputStream input =  new  ObjectInputStream( new  FileInputStream(
                 file));
         Object obj = input.readObject();
         input.close();
         System.out.println(obj);
     }
}

 

【运行结果】

 

姓名:rollen  年龄:20

 

 

 

到底序列化什么内容呢?

 

其实只有属性会被序列化。

 

Externalizable接口

 

被Serializable接口声明的类的对象的属性都将被序列化,但是如果想自定义序列化的内容的时候,就需要实现Externalizable接口。

 

当一个类要使用Externalizable这个接口的时候,这个类中必须要有一个无参的构造函数,如果没有的话,在构造的时候会产生异常,这是因为在反序列话的时候会默认调用无参的构造函数。

 

现在我们来演示一下序列化和反序列话:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package  IO;
 
import  java.io.Externalizable;
import  java.io.File;
import  java.io.FileInputStream;
import  java.io.FileOutputStream;
import  java.io.IOException;
import  java.io.ObjectInput;
import  java.io.ObjectInputStream;
import  java.io.ObjectOutput;
import  java.io.ObjectOutputStream;
 
/**
  * 序列化和反序列化的操作
  * */
public  class  ExternalizableDemo{
     public  static  void  main(String[] args)  throws  Exception{
         ser();  // 序列化
         dser();  // 反序列话
     }
 
     public  static  void  ser()  throws  Exception{
         File file =  new  File( "d:"  + File.separator +  "hello.txt" );
         ObjectOutputStream out =  new  ObjectOutputStream( new  FileOutputStream(
                 file));
         out.writeObject( new  Person( "rollen" 20 ));
         out.close();
     }
 
     public  static  void  dser()  throws  Exception{
         File file =  new  File( "d:"  + File.separator +  "hello.txt" );
         ObjectInputStream input =  new  ObjectInputStream( new  FileInputStream(
                 file));
         Object obj = input.readObject();
         input.close();
         System.out.println(obj);
     }
}
 
class  Person  implements  Externalizable{
     public  Person(){
 
     }
 
     public  Person(String name,  int  age){
         this .name = name;
         this .age = age;
     }
 
     @Override
     public  String toString(){
         return  "姓名:"  + name +  "  年龄:"  + age;
     }
 
     // 复写这个方法,根据需要可以保存的属性或者具体内容,在序列化的时候使用
     @Override
     public  void  writeExternal(ObjectOutput out)  throws  IOException{
         out.writeObject( this .name);
         out.writeInt(age);
     }
 
     // 复写这个方法,根据需要读取内容 反序列话的时候需要
     @Override
     public  void  readExternal(ObjectInput in)  throws  IOException,
             ClassNotFoundException{
         this .name = (String) in.readObject();
         this .age = in.readInt();
     }
 
     private  String name;
     private  int  age;
}

 

【运行结果】:

 

姓名:rollen  年龄:20

 

本例中,我们将全部的属性都保留了下来,

 

Serializable接口实现的操作其实是吧一个对象中的全部属性进行序列化,当然也可以使用我们上使用是Externalizable接口以实现部分属性的序列化,但是这样的操作比较麻烦,

 

当我们使用Serializable接口实现序列化操作的时候,如果一个对象的某一个属性不想被序列化保存下来,那么我们可以使用transient关键字进行说明:

 

下面举一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package  IO;
 
import  java.io.File;
import  java.io.FileInputStream;
import  java.io.FileOutputStream;
import  java.io.ObjectInputStream;
import  java.io.ObjectOutputStream;
import  java.io.Serializable;
 
/**
  * 序列化和反序列化的操作
  * */
public  class  serDemo{
     public  static  void  main(String[] args)  throws  Exception{
         ser();  // 序列化
         dser();  // 反序列话
     }
 
     public  static  void  ser()  throws  Exception{
         File file =  new  File( "d:"  + File.separator +  "hello.txt" );
         ObjectOutputStream out =  new  ObjectOutputStream( new  FileOutputStream(
                 file));
         out.writeObject( new  Person1( "rollen" 20 ));
         out.close();
     }
 
     public  static  void  dser()  throws  Exception{
         File file =  new  File( "d:"  + File.separator +  "hello.txt" );
         ObjectInputStream input =  new  ObjectInputStream( new  FileInputStream(
                 file));
         Object obj = input.readObject();
         input.close();
         System.out.println(obj);
     }
}
 
class  Person1  implements  Serializable{
     public  Person1(){
 
     }
 
     public  Person1(String name,  int  age){
         this .name = name;
         this .age = age;
     }
 
     @Override
     public  String toString(){
         return  "姓名:"  + name +  "  年龄:"  + age;
     }
 
     // 注意这里
     private  transient  String name;
     private  int  age;
}

 

【运行结果】:

 

姓名:null  年龄:20

 

最后在给一个序列化一组对象的例子吧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import  java.io.File;
import  java.io.FileInputStream;
import  java.io.FileOutputStream;
import  java.io.ObjectInputStream;
import  java.io.ObjectOutputStream;
import  java.io.Serializable;
 
/**
  * 序列化一组对象
  * */
public  class  SerDemo1{
     public  static  void  main(String[] args)  throws  Exception{
         Student[] stu = {  new  Student( "hello" 20 ),  new  Student( "world" 30 ),
                 new  Student( "rollen" 40 ) };
         ser(stu);
         Object[] obj = dser();
         for ( int  i =  0 ; i < obj.length; ++i){
             Student s = (Student) obj[i];
             System.out.println(s);
         }
     }
 
     // 序列化
     public  static  void  ser(Object[] obj)  throws  Exception{
         File file =  new  File( "d:"  + File.separator +  "hello.txt" );
         ObjectOutputStream out =  new  ObjectOutputStream( new  FileOutputStream(
                 file));
         out.writeObject(obj);
         out.close();
     }
 
     // 反序列化
     public  static  Object[] dser()  throws  Exception{
         File file =  new  File( "d:"  + File.separator +  "hello.txt" );
         ObjectInputStream input =  new  ObjectInputStream( new  FileInputStream(
                 file));
         Object[] obj = (Object[]) input.readObject();
         input.close();
         return  obj;
     }
}
 
class  Student  implements  Serializable{
     public  Student(){
 
     }
 
     public  Student(String name,  int  age){
         this .name = name;
         this .age = age;
     }
 
     @Override
     public  String toString(){
         return  "姓名:  "  + name +  "  年龄:"  + age;
     }
 
     private  String name;
     private  int  age;
}

 

【运行结果】:

 

姓名:  hello  年龄:20

 

姓名:  world  年龄:30

 

姓名:  rollen  年龄:40

转自http://www.cnblogs.com/rollenholt/archive/2011/09/11/2173787.html

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部