博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java基础知识----IO篇
阅读量:4709 次
发布时间:2019-06-10

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

写在前面:本文章基本覆盖了java IO的所有内容。java新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();  
    
}
}

假设你此时打开hellotxt查看的话,会发现那是乱码。

 

字节流

【向文件里写入字符串】

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

当你打开hellotxt的时候。会看到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盘看到rollentxt了。

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.txthello2.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接口实现序列化操作的时候,假设一个对象的某一个属性不想被序列化保存下来,那么我们能够使用transientkeyword进行说明:

以下举一个样例:

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

 

写在最后:本文章没有涉及java.nio。等我有时间,我自会补上的。欢迎大家关注我的博客,大家一起交流学习。

转载于:https://www.cnblogs.com/zfyouxi/p/5176769.html

你可能感兴趣的文章
(转)关于sql和MySQL的语句执行顺序(必看!!!)
查看>>
UVALive 3668 A Funny Stone Game(博弈)
查看>>
信息论随笔2: 交叉熵、相对熵
查看>>
再学习之MyBatis.
查看>>
CodeWars题目筛选
查看>>
MySQL— 索引
查看>>
电子书下载:Professional Web Design: Techniques and Templates, 4th Edition
查看>>
10要点解决IE6兼容性问题
查看>>
Seven Python Tools All Data Scientists Should Know How to Use
查看>>
cocos2d-x学习之路(二)——分析AppDelegate和HelloWorldScene文件
查看>>
Asp.net 对于服务器控件添加Client端方法
查看>>
在Salesforce中创建Approval Process
查看>>
NFS服务搭建与配置
查看>>
python计算文件md5值
查看>>
android 4.1 Emulator Skins
查看>>
Web站点防注入注意事项(转)
查看>>
第0次作业
查看>>
广播接收器——接收系统广播
查看>>
亿能测试资讯_2013-8-11
查看>>
北京地铁月度消费总金额计算(Python版)
查看>>