主要内容
- 缓冲流
- 转换流
- 字节数组流
- 数据流
- 对象流
笔记详情
1. 缓冲流
Java中的流可以分为节点流和处理流,节点流处于IO操作的第一线,所有的操作都必须通过他们进行。处理流可以对节点流进行其他流进行处理(提高效率或者操作灵活性)。
缓冲流是Java中的处理流,可以用来提高性能。常见的处理流有字节处理流(BufferedInputStream、BufferedOutputStream )和字符处理流(BufferReader BufferWriter)。常用的用法如下:
/**
* 使用缓冲流增强功能,提高性能
*/
import java.io.*;
public class Demo01 {
public static void main(String[] args) throws IOException {
// 建立文件的联系
File src = new File("src/testStream/1.jpg");
File dest = new File("src/testStream/2.jpg");
// 缓冲流,嵌套在文件流的外面,提高性能
InputStream is = new BufferedInputStream(new FileInputStream(src));
OutputStream os = new BufferedOutputStream(new FileOutputStream(dest));
byte[] data = new byte[10]; // 每次读取和写入的字节大小
int len;
// 不断读取和写入
while ((len = is.read(data)) != -1) {
os.write(data);
os.flush();
}
// 关闭的时候,先打开的后关闭
os.close();
is.close();
}
}
2. 转换流
转换流是Java中的处理流,主要的作用是在字节流和字符流之间的转换,在使用的时候要注意到字符集的选择,否则会出现乱码的情况。这里提一下编码和解码: 字符到字节的过程称为编码,字节到字符的过程称为解码。
实例如下:
字符流转换为字节流(编码过程)
import java.io.*;
/**
* 使用转换流实现字节到字符的转换,写出到外部文件
* 字符流 ----> 字节流
*/
public class Demo04 {
public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException ,IOException{
File file01 = new File("src/testStream/1.txt");
// 使用指定的字符集,将字符流转成字节流
OutputStream os = new FileOutputStream(file01);
Writer fileWriter = new OutputStreamWriter(os, "GBK");
String content = new String("冯振振");
fileWriter.write(content);
fileWriter.flush();
fileWriter.close();
}
}
字节流转换为字符流(解码过程)
import java.io.*;
/**
* 使用转换流实现字节到字符的转换,读取外部文件
* 字节流 ----> 字符流
*/
public class Demo03 {
public static void main(String[] args) {
File file01 = new File("src/testStream/1.txt");
try {
// 使用字节流读取文本,然后使用指定的字符集,将字节流转成字符流
// 如此一来,就不会出现读取文本乱码的问题
InputStream tempStream = new FileInputStream(file01);
Reader is = new InputStreamReader(tempStream, "Unicode");
char[] flush = new char[1024];
int len;
while ((len = is.read(flush)) != -1) {
System.out.println(flush);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("文件未找到");
} catch (IOException e) {
e.printStackTrace();
System.out.println("文件读取失败");
}
}
}
3. 字节数组流
字节数组流也是用来处理数据的一种形式,在使用的时候与前面提到的几种流相似,也有输入流(ByteArrayInputStream)和输出流(ByteArrayOutputStream)。下面给出连个方法的实例,介绍一下字节数组流的使用方式:
将字节数组流的数据写入到外部文件中
/**
* 将字节数组写入到外部文件中
* @param src 字节数组
* @param destPath 写出的外部文件
* @throws IOException
*/
public static void write(byte[] src, String destPath) throws IOException {
// 根据传入的参数,创建字节数组输入流和文件输出流
File dest = new File(destPath);
InputStream is = new BufferedInputStream(new ByteArrayInputStream(src));
OutputStream os = new BufferedOutputStream(new FileOutputStream(dest));
byte[] flush = new byte[10];
int len = 0;
// 不断读取字节数组输入流,写出到外部文件
while (-1 != (len = is.read(flush))) {
os.write(flush, 0, len);
}
os.flush();
os.close();
is.close();
}
以字节数组流的形式读取外部文件中的内容
/**
* 从外部文件中读取字节数组内容
* @param srcPath 外部文件的路径
* @return 包含外部文件的字节数组
* @throws IOException
*/
public static byte[] read(String srcPath) throws IOException {
File src = new File(srcPath);
InputStream is = new BufferedInputStream(new FileInputStream(src));
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] flush = new byte[10];
int len = 0;
while (-1 != (len = is.read(flush))) {
bos.write(flush, 0, len);
}
bos.flush();
return bos.toByteArray();
}
4. 数据流
数据流可以实现Java中数据类型的写入与写出,不仅保存数据值本身,还可以保存数据的类型。
其中数据输出流允许应用程序以适当方式将基本 Java 数据类型写入输出流中。然后,应用程序可以使用数据输入流将数据读入。
需要注意的是,使用数据输出流将数据类型写出到外部文件中的时候,内容和字节码文件相似,是一些机器识别的编码,我们看不懂。在读取外部文件中数据流内容的时候,读取的顺序要和写入的顺序相同,否则会发生错误。下面给出两个实例:
将Java中的数据流写出到外部文件
public static void write() throws FileNotFoundException, IOException {
File dest = new File("src/testStream/3.txt");
DataOutputStream dos = new DataOutputStream(
new BufferedOutputStream(new FileOutputStream(dest))
);
int num = 6;
double doubleNum = 20.5;
String name = "fengzhen";
dos.writeInt(num);
dos.writeDouble(doubleNum);
dos.writeUTF(name);
dos.close();
}
从外部文件中读取Java数据流
public static void read(String srcPath) throws FileNotFoundException, IOException {
File srcFile = new File(srcPath);
DataInputStream dis = new DataInputStream(
new BufferedInputStream(new FileInputStream(srcFile))
);
int num = dis.readInt();
double doubleNum = dis.readDouble();
String name = dis.readUTF();
System.out.println(num);
System.out.println(doubleNum);
System.out.println(name);
}
5. 对象流
对象流和上面的数据流一样,可以实现对象的写入与写出。对象的写入与写出又被称为 反序列化 和 序列化 。
但是并不是每一个对象都可以被写入写出,也不是每一个属性能够被写入和写出。首先我们先定义一个Student类,注意看其中的注释:
/**
* 定义一个Student类,该类必须继承Serializable接口,才能实现对象的写入与写出
* 该接口是一个空接口,里面没有定义方法
*/
public class Student implements java.io.Serializable {
private String name;
private double height;
private transient String gender; // 不需要序列化的属性,使用transient修饰
public Student() {
}
public Student(String name, double height, String gender) {
this.name = name;
this.height = height;
this.gender = gender;
}
public String getName() {
return name;
}
public double getHeight() {
return height;
}
public String getGender() {
return gender;
}
}
下面提供两个方法的实例,了解一下对象流的使用:
将Java程序中的对象写出到外部文件
/**
* 将对象写出到外部文件中,即对象的序列化
* @throws IOException
*/
public static void write() throws IOException {
File dest = new File("src/testStream/3.txt");
ObjectOutputStream dos = new ObjectOutputStream(
new BufferedOutputStream(new FileOutputStream(dest))
);
Student stu = new Student("Tom", 175, "male");
dos.writeObject(stu);
dos.close();
}
从外部文件中读取对象
/**
* 从外部文件中读取对象,即对象的反序列化
* @param srcPath
* @throws IOException
* @throws ClassNotFoundException
*/
public static void read(String srcPath) throws IOException, ClassNotFoundException {
File srcFile = new File(srcPath);
ObjectInputStream dis = new ObjectInputStream(
new BufferedInputStream(new FileInputStream(srcFile))
);
Student stu = (Student) dis.readObject();
System.out.println(stu.getGender()); // 没有被序列化,结果为null
System.out.println(stu.getHeight());
System.out.println(stu.getName());
}
网友评论