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) {
//字节流已结束
}