JAVA 字节流
什么是字节流?
字节流是Java中用于处理二进制数据的一种机制。它们主要用于读取和写入字节(8位)数据,而不考虑数据的内容。在处理文件、网络连接和其他I/O操作时,字节流是必不可少的。
字节流分为两种类型:
- 输入字节流(Input Byte Stream):用于从外部数据源(如文件或网络连接)读取数据到Java程序中。
- 输出字节流(Output Byte Stream):用于将数据从Java程序写入外部数据源。
输入字节流
FileInputStream
FileInputStream
是用于从文件中读取字节数据的类。以下是一个简单的示例,演示如何使用 FileInputStream
读取文件:
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputStreamExample {
public static void main(String[] args) {
try {
FileInputStream fileInputStream = new FileInputStream("example.txt");
int data;
while ((data = fileInputStream.read()) != -1) {
System.out.print((char) data);
}
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在上述示例中,我们首先创建一个 FileInputStream
来打开文件 “example.txt”,然后使用 read()
方法逐字节读取文件内容。读取的数据以整数形式返回,我们将其转换为字符并打印出来。
BufferedInputStream
BufferedInputStream
是 FileInputStream
的装饰器类,它提供了缓冲功能,可以提高文件读取的效率。使用 BufferedInputStream
可以减少频繁的磁盘访问。
以下是一个使用 BufferedInputStream
的示例:
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class BufferedInputStreamExample {
public static void main(String[] args) {
try {
FileInputStream fileInputStream = new FileInputStream("example.txt");
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
int data;
while ((data = bufferedInputStream.read()) != -1) {
System.out.print((char) data);
}
bufferedInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
DataInputStream
DataInputStream
是用于从输入字节流中读取基本数据类型的类,如整数、浮点数等。这对于读取二进制数据非常有用。
以下是一个使用 DataInputStream
读取整数的示例:
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class DataInputStreamExample {
public static void main(String[] args) {
try {
FileInputStream fileInputStream = new FileInputStream("data.bin");
DataInputStream dataInputStream = new DataInputStream(fileInputStream);
int number = dataInputStream.readInt();
System.out.println("Read number: " + number);
dataInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
输出字节流
FileOutputStream
FileOutputStream
是用于将字节数据写入文件的类。以下是一个示例,演示如何使用 FileOutputStream
写入文件:
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamExample {
public static void main(String[] args) {
try {
FileOutputStream fileOutputStream = new FileOutputStream("output.txt");
String text = "Hello, Java Byte Streams!";
byte[] bytes = text.getBytes();
fileOutputStream.write(bytes);
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在上述示例中,我们首先创建一个 FileOutputStream 来指定输出文件 “output.txt”,然后将字符串转换为字节数组并使用 write() 方法写入文件。
BufferedOutputStream
BufferedOutputStream 是 FileOutputStream 的装饰器类,它提供了缓冲功能,可以提高文件写入的效率。
以下是一个使用 BufferedOutputStream 的示例:
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class BufferedOutputStreamExample {
public static void main(String[] args) {
try {
FileOutputStream fileOutputStream = new FileOutputStream("output.txt");
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
String text = "Hello, Buffered Streams!";
byte[] bytes = text.getBytes();
bufferedOutputStream.write(bytes);
bufferedOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
DataOutputStream
DataOutputStream
是用于将基本数据类型写入输出字节流的类,与 DataInputStream
相对应。这对于将二进制数据写入文件非常有用。
以下是一个使用 DataOutputStream
写入整数的示例:
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class DataOutputStreamExample {
public static void main(String[] args) {
try {
FileOutputStream fileOutputStream = new FileOutputStream("data.bin");
DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream);
int number = 42;
dataOutputStream.writeInt(number);
dataOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
文件处理的异常处理
在上述示例中,我们使用了异常处理来处理可能出现的错误情况。在实际应用中,确保适当处理文件操作中的异常非常重要,以避免程序崩溃。
JAVA字节流的更多用法
1.复制文件
将一个文件的内容复制到另一个文件是常见的文件操作之一。你可以使用Java字节流来轻松实现文件复制。以下是一个示例:
import java.io.*;
public class FileCopyExample {
public static void main(String[] args) {
try (FileInputStream inputStream = new FileInputStream("source.txt");
FileOutputStream outputStream = new FileOutputStream("destination.txt")) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
System.out.println("文件复制完成。");
} catch (IOException e) {
e.printStackTrace();
}
}
}
在上述示例中,我们使用 FileInputStream 从源文件读取数据,然后使用 FileOutputStream 将数据写入目标文件。通过不断读取和写入数据块,可以有效地复制大型文件。
2.过滤流
过滤流(Filter Stream)是Java字节流的一种变体,它们可以用于对底层字节流进行包装,添加额外的功能。一个常见的用例是使用 BufferedInputStream 和 BufferedOutputStream 来提高性能,但还有其他过滤流可供选择。
例如,DataInputStream 和 DataOutputStream 允许你读写基本数据类型,而不必手动进行字节操作。
try (DataInputStream dataInputStream = new DataInputStream(new FileInputStream("data.bin"));
DataOutputStream dataOutputStream = new DataOutputStream(new FileOutputStream("output.bin"))) {
int number = dataInputStream.readInt();
dataOutputStream.writeInt(number * 2);
System.out.println("数据已处理并写入 output.bin");
} catch (IOException e) {
e.printStackTrace();
}
3. 序列化与反序列化
Java提供了对象的序列化和反序列化功能,可以将对象转换为字节流以进行存储或传输,然后再将其还原为对象。这在网络通信和持久化存储中非常有用。
import java.io.*;
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 +
'}';
}
}
public class SerializationExample {
public static void main(String[] args) {
// 序列化对象
try (ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("person.ser"))) {
Person person = new Person("Alice", 30);
outputStream.writeObject(person);
System.out.println("对象已序列化并保存到 person.ser");
} catch (IOException e) {
e.printStackTrace();
}
// 反序列化对象
try (ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("person.ser"))) {
Person person = (Person) inputStream.readObject();
System.out.println("从 person.ser 反序列化得到对象:" + person);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
在上述示例中,我们首先将一个 Person 对象序列化并保存到文件 “person.ser” 中,然后从该文件中反序列化对象。这使得我们能够有效地保存和还原对象。
4.压缩与解压缩
使用Java字节流,你可以轻松地将数据压缩为ZIP或GZIP格式,或者从压缩文件中解压数据。Java提供了 ZipInputStream、ZipOutputStream、GZIPInputStream 和 GZIPOutputStream 等类来支持这些操作。
import java.io.*;
import java.util.zip.*;
public class CompressionExample {
public static void main(String[] args) {
// 压缩文件
try (FileInputStream fileInputStream = new FileInputStream("source.txt");
FileOutputStream fileOutputStream = new FileOutputStream("compressed.zip");
ZipOutputStream zipOutputStream = new ZipOutputStream(fileOutputStream)) {
ZipEntry zipEntry = new ZipEntry("source.txt");
zipOutputStream.putNextEntry(zipEntry);
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fileInputStream.read(buffer)) != -1) {
zipOutputStream.write(buffer, 0, bytesRead);
}
zipOutputStream.closeEntry();
System.out.println("文件已压缩为 compressed.zip");
} catch (IOException e) {
e.printStackTrace();
}
// 解压文件
try (FileInputStream fileInputStream = new FileInputStream("compressed.zip");
ZipInputStream zipInputStream = new ZipInputStream(fileInputStream)) {
ZipEntry zipEntry = zipInputStream.getNextEntry();
while (zipEntry != null) {
FileOutputStream fileOutputStream = new FileOutputStream(zipEntry.getName());
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = zipInputStream.read(buffer)) != -1) {
fileOutputStream.write(buffer, 0, bytesRead);
}
fileOutputStream.close();
zipEntry = zipInputStream.getNextEntry();
}
System.out.println("compressed.zip 已解压");
} catch (IOException e) {
e.printStackTrace();
}
}
}
5. 网络编程
Java字节流也广泛用于网络编程,用于与远程服务器通信。你可以使用 Socket
和 ServerSocket
类来创建网络套接字,并使用字节流在网络上传输数据。
6. 大数据处理
在处理大数据文件时,需要小心内存的使用。Java字节流允许你逐行或逐块处理数据,而不必将整个文件加载到内存中。这对于处理大型日志文件、数据库导出文件等非常有用。
我们详细介绍了Java字节流的基础知识和应用。我们讨论了输入字节流和输出字节流的各种类别,包括FileInputStream
、BufferedInputStream
、DataInputStream
、FileOutputStream
、BufferedOutputStream
和DataOutputStream
。这些类是Java文件和数据处理的重要组成部分,为你提供了强大的工具来处理二进制数据。