天天看点

I\O知识点

知识点包括:

1、 序列化

2、 读写文件

3、 字节流

4、 字符流

5、 Servlet输入输出流:ServletInputStream、ServletOutputStream

IO(是 Input 输入、 Output 输出的首字母),是一个抽象的概念,输入输出是相对于

CPU 而言的。

输入输出流又分为字节流、字符流;字节流的输入输出单位是字节,通过字节流可以读写任何文件;字符流的输入输出的单位是字符;它只能读写字符,适合处理由字符组成的文档类型文件。

IO 的用途有哪些:

1、读写文件

2、上传下载

3、将 Java对象序列化到硬盘

例子:使用 Java 语言,分别用字节流和字符流复制文件。

答:复制文件的过程可以分为读取文件和写出文件两部分,转化为计算机的操作实质上是读取文件和写出文件。用字节流读取文件可以使用 InputStream,写出文件可以使用

OutputSream。用字符流读取文件可以用Reader,写出文件可以用 Writer。然而知道这些知识并不一定能写出程序,还需要有一定的思路以及将思路转化为计算机语言的能力。

字节流读取文件时,可以用 Inputsream提供的 read(byte[] byt)方法,此方法将读取到的字节数据保存到参数 byt数组中。byt 字节数组被作为字节流缓冲区定义。那该数组的作用是什么呢?既然是缓冲区,其实就是说保存在内存当中的。我们读取文件的时候,可以一次性读取更多的数据到缓冲中,而不是一个字节一个字节读取,这样读取效率会提  高。而往出写数据的时候,又可以一次性将缓冲中的所有字节写出到硬盘,而不是一个个

写出,这样会提高写出效率。那缓冲数组大小应该设置为多大呢?如果设置大了,那么会过多消耗内存空间。如果设置小了,读写效率又不会有多少提高。目前常见的大小是

1024。

关于 read(byte[] byt)方法,他有一个返回参数,是 int 类型。返回的值代表这次读取操作读取到多少个字节并写入到缓冲数组中。为什么要设定返回值呢,因为每次读取的字节数不一定是 1024 个,可能会比 1024 少,而我们的字节数组定义的是 1024 的大小,

如果读取的字节数小于1024 个,那么数组中就会有空元素。而我们知道了此次读取了多少个字节后,再往出写数据的时候,我们就能把数组中有效的数据写出,无效的数据将不写出。

将字节读取到缓冲区后,那么就可以写出数据到硬盘了。写出可以用 OutputSream的writer(byte[] byt,int start, int length)方法。这个方法的第一个参数是缓冲数组,就是上边定义的数组。第二个参数是在给定的缓冲数组中,从哪一个下标位置开始读取数组数据。第三个参数是读取该数组中多长的数据。给定了这些参数后,writer(byte[]byt, int start, int length)方法会将指定的数据写出到硬盘中。

那参数该如何指定呢?第一个参数自然是我们定义的缓冲数组;第二个参数我们设置为 0,因为我们是从0 开始读取的。第三个参数我们设置为在读取数据时的长度,读取了多少字节,我们就写出多少字节。

字节流读写文件:

public class CopyFile {

/**
*	字节流复制文件
*	@param args

*	@throws IOException

*/

public static void main(String[] args) throws IOException {


//1、定义文件输入流
InputStream in = new FileInputStream("c:/soft/test.jpg");
 
//2、定义文件的输出流
OutputStream out = new FileOutputStream("c:/soft/test(1).jpg");


//3、定义缓冲区
byte[] byt = new byte[1024];



int length = -1;

while((length = in.read(byt)) !=-1){ out.write(byt, 0, length);
}



out.close();

in.close();

}

}
           

字符流读写文件

字符流读写文件与字节流类似,只是将对应的接口和缓冲数组类型换一下。字符流读取文件的接口是 Reader,写出文件的接口是 Writer。缓冲数组类型是char[]。

代码如下:

public class CharCopyFile {



/**
*	字符流读写文件
*	@param args

*	@throws IOException

*/

public static void main(String[] args) throws IOException {


//1、定义字符输入流
 
Reader reader = new FileReader("c:/soft/test.txt");


//2、定义字符输出流
Writer writer = new FileWriter("c:/soft/test-副本.txt"); char[] buffer = new char[1024];

int length = -1;



while((length = reader.read(buffer))!=-1) { writer.write(buffer, 0, length);
}



writer.close(); reader.close();
}

}

           

对象的序列化反序列化

由于Java的对象同样是以数据的形式在内存保存,所以可以将对象保存到硬盘,也可以从硬盘读取对象到内存供程序使用。对象的序列化和反序列化是指:将对象保存至硬盘中,这是序列化;将硬盘中的对象加载进来供程序使用,这是反序列化。

例子:用 Java 创建一个 User对象,其中有 username、password 属性。

   将此 User 对象序列化到硬盘;

 将硬盘中的 User 对象反序列化。代码如下:

序列化:public class SerializableObject {

 

public static void main(String[] args) throws IOException { User user = new User();


user.setUsername("mayanyun"); user.setPassword("123456");

 

ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("c:/soft/user.obj"));

out.writeObject(user); out.close();

}

}

反序列化:

 

public class ReadObjectFromDesk {

 

public static void main(String[] args) throws Exception {

ObjectInputStream in = new ObjectInputStream(new FileInputStream("c:/soft/user.obj"));

User user = (User)in.readObject();



in.close();

System.out.println(user.getUsername()); System.out.println(user.getPassword());

}

 

}