一、转换流:
- 在一个文本文件中,如果程序中读取文本文件使用的节点流是字节流的时候,可以使用转换流将字节流转换为字符流,以提高读取的效率。
- 解码与编码:解码和编码使用的规则应该是相同的。
- 使用转换流将字节流转换为字符流称之为解码过程,也就是可以说按照某一个编码的规则将字节数组【字节流】转换成字符串【字符流】。
- 使用转换流将字符流转换为字节流称之为编码过程,也就是可以说按照某一个编码的规则将字符串【字符流】转换成字节数组【字节流】。
应用实例:
1、使用转换流实现文本的复制:
public void TestCopy(String src, String desc) {
BufferedReader br = null;
BufferedWriter bw = null;
try {
File file1 = new File(src);
File file2 = new File(desc);
FileInputStream fis = new FileInputStream(file1);
FileOutputStream fos = new FileOutputStream(file2);
// 字节流转换成字符流
InputStreamReader isr = new InputStreamReader(fis);
OutputStreamWriter osw = new OutputStreamWriter(fos);
// 使用缓冲流
br = new BufferedReader(isr);
bw = new BufferedWriter(osw);
String str = null;
while ((str = br.readLine()) != null) {
bw.write(str);
bw.newLine();
bw.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (bw != null) {
try {
bw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
二、标准的输入输出流:
1、概述:
i.Standard Input Stream:System.in
在标准的输入部件中,System.in返回的是InputStream
ii.Standard Output Stream : System.out
所以当要处理的内容是字符串的时候,需要运用到转换流来实现功能。
2、标准输入输出流的使用:
题目:使用键盘来字符串,要求将输入的字符按照要求变成大写操作,如果遇到“e”或者是“exit”的时候,退出程序。
//标准的输入输出流
/*
* Standard InputStream: System.in; 返回的是FileInputStream 字节流 ,因为在键盘输入的是字符串,所以需要将字节流转换成字符流
* Standard OutputStream: System.out;
*/
@Test
public void Test2(){
BufferedReader br = null;
System.out.println("请输入字符串:");
try {
InputStream is = System.in;
//直接转换
InputStreamReader isr = new InputStreamReader(is);
br = new BufferedReader(isr);
String str = null;
while(true){
str = br.readLine();
if(str.equalsIgnoreCase("e")||str.equalsIgnoreCase("exit")){
System.out.println("Out of program.");
break;
}else{
System.out.println(str.toUpperCase());
}
}
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(br!= null){
try {
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
三、ObjectInputStream & ObjectOutputStream对象流
该处理流是主要就是针对处理对象的流,主要的强大之处就是可以将Java中的对象写入到数据流之中,也可以将数据流之中的对象数据还原回来。
在对象流的转换之中有涉及到了两个概念:
1、序列化:使用ObjectOutputStream 将Java对象写入IO流之中。
2、反序列化:使用ObjectInputStream 将Java对象在IO中还原回来。
对象的序列化机制:允许吧内存中的Java对象那个转换为平台无关的二进制流,从而云讯吧这种二进制流持久的保存在磁盘中,或者通过网络将这种二进制流传输到另一个网络节点上,当其他程序获取了这种二进制流,,就可以恢复成原来的Java对象。
序列化的好处在于可以将如何实现了Serializable接口的对象转化为字节数据,使其在保存和传输时可以被还原。
序列化时RMI过程的参数和返回值都必须实现的机制,而RMI是JavaEE的基础。因此序列化机制是JavaEE平台的基础。
注意点:
1、序列化的类需要实现Serializable接口,同样类的属性也要实现Serializable 接口。
2、凡是实现了Serializable 接口的类,都要有一个版本号:
a)Private static final long serialVersionID = ??????L;
3、ObejctOutputStream 和ObejctInputStream不能序列化static 和transient修饰的成员变量。
应用实例:
1、使用对象流将数据写入IO流中:
实现类序列化的对象类:
//写入IO的类必须实现Serializable接口,表明这个类是可以序列化的。
class Person implements Serializable {
//类的属性也是要其实现序列化的,但是不能序列化static 和 transient 修饰的变量。
String name;
Integer age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
实现功能类:
@Test
public void Test1() {
Object p1 = new Person("小米", 23);
Object p2 = new Person("红木", 21);
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("text55.txt"));
oos.writeObject(p1);
oos.flush();
oos.writeObject(p2);
oos.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (oos != null) {
try {
oos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
将对象写入指定的IO文本文件中。
实例二:
将文本文件中的对象信息还原到Java程序的虚拟机当中。
@Test
public void Test2() {
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream("text55.txt"));
Person p3 = (Person) ois.readObject();
System.out.println(p3.toString());
Person p4 = (Person) ois.readObject();
System.out.println(p4.toString());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (ois != null) {
try {
ois.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
总结:
1、使用对象流的好处就是在于可以将创建出来的对象通过IO流来永久的存到磁盘中去,使文件不易丢失。
2、对象流可以存储Java中的对象。
四、随机存储流RandomAccseeFile
1、RandomAccessFile类支持“随机访问”的方式,程序可以直接跳到文件的任意地方来读写文件。
a)支持只访问文件的部分内容。
b)可以向已存在的文件后追加内容。
2、RandomAccessFile对象包含一个记录指针,用于标识当前读写出的位置,RandomAccessFile类对象可以自由移动记录指针:
a)Long getFilePointer(); 获取文件记录指针的当前位置。
b)Void seek(long pos);将文件记录在指针定位到pos位置。
3、构造器:
a)Public RandomAccessFile(File file,String mode);
b)public RandomAccessFile(String name,String mode);
i.Mode参数说明: 该参数制定RandomAccessFile的访问模式:
1.r:以只读的方式打开。
2.rw:打开以便读取和写入。
3.rwd: 打开以便读取和写入,同步文件内容的更新。
4.rws:打开以便读取和写入,同步文件内容和元数据更新。
应用实例:
1、使用RandomAccessFile实现在一个文本文件里面在任意的位置上插入字符串。
package RandomAccessFile;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import org.junit.Test;
/*
*
*/
public class TestRandomAccessFile {
/*
* 使用RandomAccessStream 实现基本的读写操作。
*/
@Test
public void Test1(){
RandomAccessFile raf1 = null;
RandomAccessFile raf2 = null;
try {
raf1 = new RandomAccessFile(new File("Test5.txt"),"r");
raf2 = new RandomAccessFile(new File("Test5new.txt"),"rw");
byte[] b = new byte[20];
int len;
while((len = raf1.read(b))!= -1){
raf2.write(b, 0, len);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(raf2!= null){
try {
raf2.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(raf1!= null){
try {
raf1.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}