Java中字节流的相关内容
字节流(Byte Streams):用于读写二进制数据,以字节为单位
1.1 InputStream 和 OutputStream
InputStream和OutputStream是Java中最基本的字节流,它们分别是所有字节输入流和字节输出流的基类。
1.InputStream:
- 从输入流中读取一个字节:
int read() throws IOException
- 从输入流中读取字节数组:
int read(byte[] b) throws IOException
- 从输入流中读取指定长度的字节数组:
int read(byte[] b, int off, int len) throws IOException
- 跳过指定的字节数:
long skip(long n) throws IOException
- 返回输入流中可读取的字节数:
int available() throws IOException
- 关闭输入流:
void close() throws IOException
2.outputStream:
- 将一个字节写入输出流:
void write(int b) throws IOException
- 将字节数组写入输出流:
void write(byte[] b) throws IOException
- 将指定长度的字节数组写入输出流:
void write(byte[] b, int off, int len) throws IOException
- 刷新输出流:
void flush() throws IOException
- 关闭输出流:
void close() throws IOException
1.2 FileInputStream 和 FileOutputStream:用于读写文件的字节流。
FileInputStream:用于读取文件的字节数据,其构造函数可以接受一个File对象或者一个字符串作为参数,表示要读取的文件路径。
File file = new File("test.txt");
InputStream inputStream = new FileInputStream(file);
FileOutputStream用于写入文件的字节数据,其构造函数可以接受一个File对象或者一个字符串作为参数,表示要写入的文件路径。
File file = new File("test.txt");
OutputStream outputStream = new FileOutputStream(file);
读取文件:
FileInputStream的read()方法可以从文件中读取一个字节,返回值为读取到的字节,如果已经读取到文件的末尾则返回-1。
File file = new File("test.txt");
InputStream inputStream = new FileInputStream(file);
int data = inputStream.read(); // 读取一个字节
FileInputStream的read(byte[] b)方法可以从文件中读取指定长度的字节数组,返回值为实际读取的字节数,如果已经读取到文件的末尾则返回-1。
File file = new File("test.txt");
InputStream inputStream = new FileInputStream(file);
byte[] buffer = new byte[1024];
int length = inputStream.read(buffer); // 读取字节数组
FileInputStream的read(byte[] b, int off, int len)方法可以从文件中读取指定长度的字节数组,返回值为实际读取的字节数,如果已经读取到文件的末尾则返回-1。
File file = new File("test.txt");
InputStream inputStream = new FileInputStream(file);
byte[] buffer = new byte[1024];
int length = inputStream.read(buffer, 0, 1024); // 读取1024个字节到字节数组中
写入文件:
FileOutputStream的write(int b)方法可以向文件中写入一个字节。
File file = new File("test.txt");
OutputStream outputStream = new FileOutputStream(file);
outputStream.write(65); // 写入一个字节
FileOutputStream的write(byte[] b)方法可以向文件中写入字节数组。
File file = new File("test.txt");
OutputStream outputStream = new FileOutputStream(file);
byte[] buffer = "hello world".getBytes();
outputStream.write(buffer); // 写入字节数组
FileOutputStream的write(byte[] b, int off, int len)方法可以向文件中写入指定长度的字节数组。
File file = new File("test.txt");
OutputStream outputStream = new FileOutputStream(file);
byte[] buffer = "hello world".getBytes();
outputStream.write(buffer, 0, 5); // 写入前5个字节
关闭流:
FileInputStream和FileOutputStream的close()方法可以关闭输入流和输出流,释放相关的资源。
File file = new File("test.txt");
InputStream inputStream = new FileInputStream(file);
inputStream.close();
File file = new File("test.txt");
OutputStream outputStream = new FileOutputStream(file);
outputStream.close();
1.3 ByteArrayInputStream 和 ByteArrayOutputStream:
用于读写内存中的字节数据的流。
ByteArrayInputStream用于在内存中读取字节数组,其构造函数可以接受一个byte数组作为参数,表示要读取的字节数组。
byte[] buffer = "hello world".getBytes();
InputStream inputStream = new ByteArrayInputStream(buffer);
使用ByteArrayInputStream的read()方法可以从字节数组中读取一个字节,返回值为读取到的字节,如果已经读取到数组的末尾则返回-1。
byte[] buffer = "hello world".getBytes();
InputStream inputStream = new ByteArrayInputStream(buffer);
int data = inputStream.read(); // 读取一个字节
使用ByteArrayInputStream的read(byte[] b)方法可以从字节数组中读取指定长度的字节数组,返回值为实际读取的字节数,如果已经读取到数组的末尾则返回-1。
byte[] buffer = "hello world".getBytes();
InputStream inputStream = new ByteArrayInputStream(buffer);
byte[] data = new byte[1024];
int length = inputStream.read(data); // 读取字节数组
使用ByteArrayInputStream的read(byte[] b, int off, int len)方法可以从字节数组中读取指定长度的字节数组,返回值为实际读取的字节数,如果已经读取到数组的末尾则返回-1。
byte[] buffer = "hello world".getBytes();
InputStream inputStream = new ByteArrayInputStream(buffer);
byte[] data = new byte[1024];
int length = inputStream.read(data, 0, 1024); // 读取1024个字节到字节数组中
ByteArrayOutputStream用于在内存中写入字节数组,其构造函数不需要参数。
OutputStream outputStream = new ByteArrayOutputStream();
使用ByteArrayOutputStream的write(int b)方法可以向字节数组中写入一个字节。
OutputStream outputStream = new ByteArrayOutputStream();
outputStream.write(65); // 写入一个字节
使用ByteArrayOutputStream的write(byte[] b)方法可以向字节数组中写入字节数组。
OutputStream outputStream = new ByteArrayOutputStream();
byte[] buffer = "hello world".getBytes();
outputStream.write(buffer); // 写入字节数组
使用ByteArrayOutputStream的write(byte[] b, int off, int len)方法可以向字节数组中写入指定长度的字节数组。
OutputStream outputStream = new ByteArrayOutputStream();
byte[] buffer = "hello world".getBytes();
outputStream.write(buffer, 0, 5); // 写入前5个字节
使用ByteArrayOutputStream的toByteArray()方法可以获取当前字节数组的值。
OutputStream outputStream = new ByteArrayOutputStream();
byte[] buffer = "hello world".getBytes();
outputStream.write(buffer, 0, 5);
byte[] data = ((ByteArrayOutputStream) outputStream).toByteArray(); // 获取当前字节数组的值
使用ByteArrayOutputStream的reset()方法可以重置字节数组。
OutputStream outputStream = new ByteArrayOutputStream();
byte[] buffer = "hello world".getBytes();
outputStream.write(buffer, 0, 5);
((ByteArrayOutputStream) outputStream).reset(); // 重置字节数组
1.4 DataInputStream 和 DataOutputStream:用于读写基本数据类型的字节流。
DataInputStream继承自FilterInputStream,可以从任何一个输入流中读取基本类型数据和字符串,其构造函数需要一个InputStream对象作为参数。
InputStream inputStream = new FileInputStream("data.txt");
DataInputStream dataInputStream = new DataInputStream(inputStream);
使用DataInputStream的readBoolean()方法可以从输入流中读取一个布尔值,返回值为读取到的布尔值。
boolean value = dataInputStream.readBoolean();
使用DataInputStream的readByte()方法可以从输入流中读取一个字节,返回值为读取到的字节。
byte value = dataInputStream.readByte();
使用DataInputStream的readShort()方法可以从输入流中读取一个短整型数据,返回值为读取到的短整型数据。
short value = dataInputStream.readShort();
使用DataInputStream的readInt()方法可以从输入流中读取一个整型数据,返回值为读取到的整型数据。
int value = dataInputStream.readInt();
使用DataInputStream的readLong()方法可以从输入流中读取一个长整型数据,返回值为读取到的长整型数据。
long value = dataInputStream.readLong();
使用DataInputStream的readFloat()方法可以从输入流中读取一个单精度浮点数,返回值为读取到的单精度浮点数。
float value = dataInputStream.readFloat();
使用DataInputStream的readDouble()方法可以从输入流中读取一个双精度浮点数,返回值为读取到的双精度浮点数。
double value = dataInputStream.readDouble();
使用DataInputStream的readChar()方法可以从输入流中读取一个字符,返回值为读取到的字符。
char value = dataInputStream.readChar();
使用DataInputStream的readUTF()方法可以从输入流中读取一个UTF-8编码的字符串,返回值为读取到的字符串
String value = dataInputStream.readUTF();
DataOutputStream继承自FilterOutputStream,可以向任何一个输出流中写入基本类型数据和字符串,其构造函数需要一个OutputStream对象作为参数。
OutputStream outputStream = new FileOutputStream("data.txt");
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
使用DataOutputStream的writeBoolean(boolean v)方法可以向输出流中写入一个布尔值。
boolean value = true;
dataOutputStream.writeBoolean(value);
使用DataOutputStream的writeByte(int v)方法可以向输出流中写入一个字节。
byte value = 100;
dataOutputStream.writeByte(value);
使用DataOutputStream的writeShort(int v)方法可以向输出流中写入一个短整型数据。
short value = 1000;
dataOutputStream.writeShort(value);
使用DataOutputStream的writeInt(int v)方法可以向输出流中写入一个整型数据。
int value = 100000;
dataOutputStream.writeInt(value);
使用DataOutputStream的writeLong(long v)方法可以向输出流中写入一个长整型数据
1.5 BufferedInputStream 和 BufferedOutputStream:提供了缓冲功能的字节流。
BufferedInputStream继承自FilterInputStream,可以从任何一个输入流中读取字节数据,并提供了缓存读取功能,其构造函数需要一个InputStream对象作为参数。
InputStream inputStream = new FileInputStream("data.txt");
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
使用BufferedInputStream的read()方法可以从输入流中读取一个字节,返回值为读取到的字节,如果读取到文件末尾返回-1。
int value = bufferedInputStream.read();
使用BufferedInputStream的read(byte[] b)方法可以从输入流中读取指定长度的字节数据并存储到一个字节数组中,返回值为读取到的字节数,如果读取到文件末尾返回-1。
byte[] buffer = new byte[1024];
int length = bufferedInputStream.read(buffer);
BufferedOutputStream
BufferedOutputStream继承自FilterOutputStream,可以向任何一个输出流中写入字节数据,并提供了缓存写入功能,其构造函数需要一个OutputStream对象作为参数。
OutputStream outputStream = new FileOutputStream("data.txt");
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
使用BufferedOutputStream的write(int b)方法可以向输出流中写入一个字节。
byte value = 100;
bufferedOutputStream.write(value);
使用BufferedOutputStream的write(byte[] b)方法可以向输出流中写入一个字节数组。
byte[] buffer = new byte[]{1,2,3,4,5};
bufferedOutputStream.write(buffer);
使用BufferedOutputStream的flush()方法可以将缓存中的数据立即写入输出流中,可以确保数据被及时写入。
bufferedOutputStream.flush();
1.6 ObjectInputStream 和 ObjectOutputStream:用于读写 Java 对象的字节流。
ObjectInputStream和ObjectOutputStream是Java中用于读写对象的高级流,可以将对象序列化为字节序列并写入输出流中,也可以从输入流中读取字节序列并反序列化为对象。这两个流通常用于在不同的Java应用程序之间传输对象或将对象保存到文件中。
以下是一个简单的示例,演示如何使用ObjectOutputStream将对象序列化并写入文件中,然后使用ObjectInputStream从文件中读取字节序列并反序列化为对象。
import java.io.*;
public class ObjectStreamExample {
public static void main(String[] args) {
// 创建一个Person对象
Person person = new Person("Tom", 20);
// 将对象写入文件中
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"))) {
oos.writeObject(person);
} catch (IOException e) {
e.printStackTrace();
}
// 从文件中读取对象
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"))) {
Person newPerson = (Person) ois.readObject();
System.out.println(newPerson);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
// 定义一个可序列化的Person类
class Person implements Serializable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
在这个示例中,我们创建了一个可序列化的Person类,然后创建了一个Person对象,并使用ObjectOutputStream将它写入到一个名为"person.ser"的文件中。接着,我们使用ObjectInputStream从文件中读取字节序列,并将其反序列化为一个新的Person对象。最后,我们打印出新的Person对象。
【注意】序列化是指将一个Java对象转换成字节序列的过程,以便将其存储到文件、数据库或网络中,或在不同的Java应用程序之间传输。序列化可以理解为一种将对象持久化的方式,将一个对象的状态转换为字节流的形式,可以将其保存到磁盘或通过网络传输到远程系统。
在Java中,要将一个对象序列化,需要让该对象所属的类实现java.io.Serializable接口,该接口没有任何方法,只是一个标记接口,表明实现该接口的类可以被序列化。当对象被序列化时,Java会将对象的状态(也就是它的属性)转换成一连串字节,可以使用ObjectOutputStream将字节序列写入到文件、数据库或网络中。
反序列化是指将字节序列转换成Java对象的过程,以便重新创建对象。当接收到字节序列时,可以使用ObjectInputStream从文件、数据库或网络中读取字节序列,并将其反序列化为Java对象。在反序列化的过程中,Java会根据字节流中的信息,重新构造出原来的对象,并将其状态还原到对象中,从而重新获得该对象的实例。
需要注意的是,在序列化和反序列化的过程中,需要保证对象的属性是可序列化的,也就是说,它们必须是基本数据类型、字符串或实现了java.io.Serializable接口的对象。如果某个对象包含一个不可序列化的属性,则序列化该对象时会抛出java.io.NotSerializableException异常。