跳到主要内容

Java 字节流

字节流(Byte Stream)是Java中的一种流,它是处理二进制数据的最基本的流,可以处理任何类型的数据,例如字符串、图像等。 字节流的特点是把数据看成一个个字节,它们是无类型的,可以处理任何类型的数据。

常见的字节流方法:

  • InputStream / OutputStream
  • FileInputStream / FileOutputStream
  • ByteArrayInputStream / ByteArrayOutputStream
  • DataInputStream / DataOutputStream
  • FilterInputStream / FilterOutputStream
  • ObjectInputStream / ObjectOutputStream
  • PipedInputStream / PipedOutputStream

FileInputStream / FileOutputStream

示例:


import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
* 使用FileInputStream和FileOutputStream实现了文件的复制操作
*/
public class FileInputOutputStreamDemo {

public static void main(String[] args) {
try {
FileInputStream fis = new FileInputStream("./test.txt");
FileOutputStream fos = new FileOutputStream("./test_copy.txt");
int len;
byte[] buf = new byte[1024];
while ((len = fis.read(buf)) != -1) {
fos.write(buf, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
}

}

ByteArrayInputStream / ByteArrayOutputStream

示例:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

/**
* 使用了ByteArrayInputStream和ByteArrayOutputStream来实现字符串大小写转换的功能
*/
public class ByteArrayDemo {
public static void main(String[] args) {
String str = "This is just a test";
try {
ByteArrayInputStream bais = new ByteArrayInputStream(str.getBytes());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int c = 0;
while ((c = bais.read()) != -1) {
baos.write(Character.toUpperCase(c));
}
System.out.println(baos); // THIS IS JUST A TEST
} catch (Exception e) {
e.printStackTrace();
}
}
}

DataInputStream / DataOutputStream


import java.io.*;

/**
* 使用DataInputStream和DataOutputStream来读取和写入基本类型的数据
*/
public class DataStreamDemo {
public static void main(String[] args) {
String fileName = "data.txt";
try {
// 定义文件输入流对象fis
FileInputStream fis = new FileInputStream(fileName);
// 根据fis定义数据输入流对象dis(依赖FileInputStream实例对象?)
DataInputStream dis = new DataInputStream(fis);

// 定义文件输出流对象fos
FileOutputStream fos = new FileOutputStream(fileName);
// 根据fos定义数据输出流对象dos(依赖FileOutputStream实例对象?)
DataOutputStream dos = new DataOutputStream(fos);

// 写入字符
dos.writeUTF("Hello world!");
dos.writeInt(123);
dos.writeFloat(123.455F);
dos.writeBoolean(true);

// 读取各种类型数据
String str = dis.readUTF();
int i = dis.readInt();
float f = dis.readFloat();
boolean b = dis.readBoolean();

// 打印读取的数据
System.out.println("str = " + str);
System.out.println("i = " + i);
System.out.println("f = " + f);
System.out.println("b = " + b);
} catch (Exception e) {
e.printStackTrace();
}
}
}

ObjectInputStream / ObjectOutputStream

示例:


import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
* 使用ObjectOutputStream将Person对象序列化到文件data.obj中,并使用ObjectInputStream从data.obj文件反序列化出Person对象,并打印出Person对象的信息
*/
public class ObjectSerializationDemo {

static String OBJECT_FILENAME = "data.obj";

public static void main(String[] args) {
// 将对象序列化到文件
try {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(OBJECT_FILENAME));
oos.writeObject(new Person("John", 192));
} catch (Exception e) {
e.printStackTrace();
}

// 从文件反序列化出对象
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(OBJECT_FILENAME));
Person person = (Person) ois.readObject();
System.out.println(person);
} catch (Exception e) {
e.printStackTrace();
}
}
}

PipedInputStream / PipedOutputStream

示例:


import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

/**
* 使用了PipedInputStream和PipedOutputStream来实现数据的管道传输,使用try-with-resources去实现资源的自动关闭
*/
public class PipedInputStreamExample {
public static void main(String[] args) throws IOException {
try {
PipedInputStream pis = new PipedInputStream();
PipedOutputStream pos = new PipedOutputStream();
pis.connect(pos);
byte[] b = { 11, 21, 33,77};
pos.write(b);
int data = pis.read();
while (data != -1) {
System.out.println(data + "");
data = pis.read();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

IO 流的关闭

Java 的 IO 流会占用系统资源,如果不关闭,可能会造成系统资源的浪费,影响程序的性能。此外,如果不关闭 IO 流,可能会导致文件无法被写入或读取,从而影响程序的正常运行。

常见的关闭 IO 流操作:

  • 使用 try-with-resources 方法关闭资源:try-with-resources 语句可以优雅地关闭 IO 流,它可以在 try 语句块结束时自动关闭资源,而不需要手动关闭
  • 使用 close() 方法关闭资源:close() 方法是用来关闭输入流或输出流的方法,它处理的是一次性的资源关闭,其具体的实现是将资源的引用设置为 null
  • 使用 flush() 方法清空缓冲区:flush() 方法是用来清空输出缓冲区的方法,它会将缓冲区中的内容刷新到输出流中,使得缓冲区清空,这样就可以避免程序出现异常

如何检测字节流的结束标志?

  • 可以使用 InputStream 的 available() 方法来检测字节流的结束标志,当 available() 返回 0 时,表示字节流已经结束

示例:

if (inputStream.available() == 0) {
//字节流已结束
}