博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java IO整理
阅读量:6426 次
发布时间:2019-06-23

本文共 34837 字,大约阅读时间需要 116 分钟。

 

【案例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

新建文件夹

 

 

但是使用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:\新建文件夹

 

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

 

 

 列出当前目录下的目录名字和文件名字(包括隐藏文件)

1 public static void show(File file) { 2         if (file != null) { 3             if (file.isDirectory()) { // 判断一个指定的路径是否为目录 4                 File[] f = file.listFiles(); 5                 if (f != null) { 6                     for (int i = 0; i < f.length; i++) { 7                         if (f[i].isDirectory()) { 8                             System.out.println(f[i]);// 如果是个空文件夹,则直接输出该文件夹 9                         }10                         show(f[i]); // 递归调用11                     }12                 }13             } else {14                 System.out.println(file);15             }16         }17     }

 

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

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);
            
}
        
}
    
}
}

 

 

 

 

使用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

 

 

 转载自:

 
 

转载于:https://www.cnblogs.com/IT-utopia/p/3259517.html

你可能感兴趣的文章
黑客教父详解账号泄露全过程:1亿用户已泄露
查看>>
程序员必须软件
查看>>
Canvas里的globalCompositeOperation
查看>>
解决Unable to locate theme engine in module_path: "pixmap"
查看>>
贝叶斯文本分类c#版
查看>>
Centos安装KDE或GNOME
查看>>
Eclipse & IDEA 中常用的快捷键
查看>>
javascript ---IPhone滑动解锁
查看>>
table固定行和表头
查看>>
<每天读一点职场心理学>读书笔记
查看>>
Android权限大全代码
查看>>
android 判断SIM卡是哪个运营商
查看>>
删除N天前的M(天)个目录 、删除N天前最后修改的文件 ForFiles, dos command 批处理命令cmd/bat...
查看>>
十进制数1~n中1出现的次数
查看>>
PostgreSQL 的 语法分析的理解(五)
查看>>
[转载]Visual Studio 2010敏捷利剑:详解Scrum
查看>>
Java Collection: List、Set、 Map、 HashMap、 Hashtable、 Vector
查看>>
T-SQL查询进阶--流程控制语句
查看>>
Excel VBA小试
查看>>
备份Toad中保存的数据库连接用户名和密码
查看>>