Java学习教程,从入门到精通,Java 流(Stream)、文件(File)和IO 语法知识点及案例代码(125)
Java 流(Stream)、文件(File)和IO 语法知识点及案例代码
一、Java 流(Stream)
1.1 概念
- 流是 Java 中用于处理输入/输出操作的抽象概念。
- 流可以看作是数据的管道,数据从源头流向目的地。
- Java 中的流分为两大类:
- 字节流:以字节为单位进行数据读写,适用于所有类型的数据。
- 字符流:以字符为单位进行数据读写,适用于文本数据。
1.2 字节流
- InputStream:所有字节输入流的父类。
- FileInputStream:从文件中读取字节数据。
- ByteArrayInputStream:从字节数组中读取字节数据。
- BufferedInputStream:带缓冲区的字节输入流,提高读取效率。
- OutputStream:所有字节输出流的父类。
- FileOutputStream:向文件中写入字节数据。
- ByteArrayOutputStream:向字节数组中写入字节数据。
- BufferedOutputStream:带缓冲区的字节输出流,提高写入效率。
1.3 字符流
- Reader:所有字符输入流的父类。
- FileReader:从文件中读取字符数据。
- InputStreamReader:将字节流转换为字符流。
- BufferedReader:带缓冲区的字符输入流,提高读取效率。
- Writer:所有字符输出流的父类。
- FileWriter:向文件中写入字符数据。
- OutputStreamWriter:将字符流转换为字节流。
- BufferedWriter:带缓冲区的字符输出流,提高写入效率。
1.4 案例代码
import java.io.*;
public class StreamExample {
public static void main(String[] args) {
// 1. 使用字节流复制文件
try (FileInputStream fis = new FileInputStream("input.txt");
FileOutputStream fos = new FileOutputStream("output.txt")) {
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
System.out.println("文件复制成功!");
} catch (IOException e) {
e.printStackTrace();
}
// 2. 使用字符流读取文件内容并打印
try (BufferedReader br = new BufferedReader(new FileReader("input.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
// 3. 使用缓冲流提高读写效率
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("input.txt"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("output.txt"))) {
byte[] buffer = new byte[1024];
int len;
while ((len = bis.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
System.out.println("文件复制成功!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
二、Java 文件(File)
2.1 概念
- File 类代表文件和目录路径名的抽象表示。
- 可以使用 File 类来创建、删除、重命名文件和目录,以及获取文件和目录的属性信息。
2.2 常用方法
- boolean createNewFile():创建新文件。
- boolean mkdir():创建目录。
- boolean delete():删除文件或目录。
- boolean exists():判断文件或目录是否存在。
- String getName():获取文件或目录的名称。
- String getPath():获取文件或目录的路径。
- long length():获取文件的大小。
- boolean isFile():判断是否是文件。
- boolean isDirectory():判断是否是目录。
2.3 案例代码
import java.io.File;
public class FileExample {
public static void main(String[] args) {
// 1. 创建文件
File file = new File("test.txt");
try {
if (file.createNewFile()) {
System.out.println("文件创建成功!");
} else {
System.out.println("文件已存在!");
}
} catch (IOException e) {
e.printStackTrace();
}
// 2. 获取文件信息
System.out.println("文件名称:" + file.getName());
System.out.println("文件路径:" + file.getPath());
System.out.println("文件大小:" + file.length() + " bytes");
System.out.println("是否是文件:" + file.isFile());
System.out.println("是否是目录:" + file.isDirectory());
// 3. 删除文件
if (file.delete()) {
System.out.println("文件删除成功!");
} else {
System.out.println("文件删除失败!");
}
}
}
三、Java IO
3.1 概念
- IO 是 Input/Output 的缩写,即输入/输出。
- Java IO 提供了丰富的类库来处理各种输入/输出操作,例如文件读写、网络通信等。
3.2 常用类
- File:代表文件和目录。
- InputStream/OutputStream:字节流。
- Reader/Writer:字符流。
- BufferedReader/BufferedWriter:带缓冲区的字符流。
- DataInputStream/DataOutputStream:用于读写基本数据类型。
- ObjectInputStream/ObjectOutputStream:用于读写对象。
3.3 案例代码
import java.io.*;
public class IOExample {
public static void main(String[] args) {
// 1. 使用 DataOutputStream 写入数据
try (DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"))) {
dos.writeInt(100);
dos.writeDouble(3.14);
dos.writeBoolean(true);
dos.writeUTF("Hello, World!");
} catch (IOException e) {
e.printStackTrace();
}
// 2. 使用 DataInputStream 读取数据
try (DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"))) {
int i = dis.readInt();
double d = dis.readDouble();
boolean b = dis.readBoolean();
String s = dis.readUTF();
System.out.println("读取的数据:" + i + ", " + d + ", " + b + ", " + s);
} catch (IOException e) {
e.printStackTrace();
}
// 3. 使用 ObjectOutputStream 序列化对象
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object.txt"))) {
oos.writeObject(new Person("张三", 20));
} catch (IOException e) {
e.printStackTrace();
}
// 4. 使用 ObjectInputStream 反序列化对象
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("object.txt"))) {
Person person = (Person) ois.readObject();
System.out.println("反序列化的对象:" + person);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
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 +
'}';
}
}
四、总结
Java 流、文件和 IO 是 Java 编程中非常重要的部分,掌握这些知识可以帮助我们更好地处理各种输入/输出操作。
以下是一些实际开发中常见的 Java 流、文件和 IO 的具体案例,涵盖了文件读写、网络通信、数据处理等场景。
五、实际开发案例
1. 读取配置文件
在实际开发中,经常需要读取配置文件(如 .properties
文件)来加载配置信息。
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class ConfigFileExample {
public static void main(String[] args) {
Properties properties = new Properties();
try (FileInputStream fis = new FileInputStream("config.properties")) {
// 加载配置文件
properties.load(fis);
// 读取配置项
String username = properties.getProperty("username");
String password = properties.getProperty("password");
System.out.println("Username: " + username);
System.out.println("Password: " + password);
} catch (IOException e) {
e.printStackTrace();
}
}
}
配置文件 config.properties
内容:
username=admin
password=123456
2. 日志记录到文件
在实际开发中,通常需要将日志信息记录到文件中,以便后续分析和排查问题。
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.time.LocalDateTime;
public class LoggingExample {
public static void main(String[] args) {
String logFile = "app.log";
try (PrintWriter writer = new PrintWriter(new FileWriter(logFile, true))) {
// 记录日志
writer.println(LocalDateTime.now() + " - Application started.");
writer.println(LocalDateTime.now() + " - Performing some operation...");
writer.println(LocalDateTime.now() + " - Application finished.");
System.out.println("日志已记录到文件: " + logFile);
} catch (IOException e) {
e.printStackTrace();
}
}
}
日志文件 app.log
内容:
2023-10-25T14:30:00.123 - Application started.
2023-10-25T14:30:01.456 - Performing some operation...
2023-10-25T14:30:02.789 - Application finished.
3. 文件上传功能
在 Web 开发中,文件上传是一个常见的功能。以下是一个模拟文件上传的案例。
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class FileUploadExample {
public static void main(String[] args) {
// 模拟上传的文件流(假设从网络或客户端获取)
InputStream inputStream = FileUploadExample.class.getResourceAsStream("/example.txt");
// 目标文件路径
String uploadPath = "uploads/example.txt";
File uploadDir = new File("uploads");
if (!uploadDir.exists()) {
uploadDir.mkdir(); // 创建上传目录
}
try (FileOutputStream fos = new FileOutputStream(uploadPath)) {
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) != -1) {
fos.write(buffer, 0, len); // 将文件写入目标路径
}
System.out.println("文件上传成功: " + uploadPath);
} catch (IOException e) {
e.printStackTrace();
}
}
}
4. 读取 CSV 文件并解析
在实际开发中,CSV 文件常用于数据导入导出。以下是一个读取 CSV 文件并解析数据的案例。
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class CSVReaderExample {
public static void main(String[] args) {
String csvFile = "data.csv";
try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {
String line;
while ((line = br.readLine()) != null) {
// 按逗号分割每一行数据
String[] data = line.split(",");
System.out.println("Name: " + data[0] + ", Age: " + data[1] + ", City: " + data[2]);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
CSV 文件 data.csv
内容:
John,25,New York
Alice,30,Los Angeles
Bob,22,Chicago
5. 网络文件下载
在实际开发中,经常需要从网络下载文件并保存到本地。
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
public class FileDownloadExample {
public static void main(String[] args) {
String fileUrl = "https://example.com/path/to/file.zip";
String savePath = "downloads/file.zip";
try (BufferedInputStream in = new BufferedInputStream(new URL(fileUrl).openStream());
FileOutputStream fos = new FileOutputStream(savePath)) {
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) != -1) {
fos.write(buffer, 0, len); // 将网络文件写入本地
}
System.out.println("文件下载完成: " + savePath);
} catch (IOException e) {
e.printStackTrace();
}
}
}
6. 对象序列化与反序列化
在实际开发中,对象序列化常用于将对象保存到文件或通过网络传输。
import java.io.*;
public class SerializationExample {
public static void main(String[] args) {
// 对象序列化
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.dat"))) {
User user = new User("Alice", 30);
oos.writeObject(user);
System.out.println("对象已序列化到文件: user.dat");
} catch (IOException e) {
e.printStackTrace();
}
// 对象反序列化
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.dat"))) {
User user = (User) ois.readObject();
System.out.println("从文件反序列化的对象: " + user);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
class User implements Serializable {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "User{name='" + name + "', age=" + age + "}";
}
}
7. 大文件分块读取
对于大文件,一次性读取可能会导致内存溢出。可以通过分块读取的方式处理。
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class LargeFileReadExample {
public static void main(String[] args) {
String filePath = "largefile.log";
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath))) {
byte[] buffer = new byte[1024 * 1024]; // 每次读取 1MB
int len;
while ((len = bis.read(buffer)) != -1) {
// 处理读取的数据
System.out.println("读取了 " + len + " 字节数据");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
8. 文件压缩与解压缩
在实际开发中,文件压缩和解压缩是常见的操作。
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZipExample {
public static void main(String[] args) {
String[] filesToZip = {"file1.txt", "file2.txt"};
String zipFile = "archive.zip";
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile))) {
for (String file : filesToZip) {
try (FileInputStream fis = new FileInputStream(file)) {
ZipEntry zipEntry = new ZipEntry(file);
zos.putNextEntry(zipEntry);
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
zos.write(buffer, 0, len);
}
zos.closeEntry();
}
}
System.out.println("文件压缩完成: " + zipFile);
} catch (IOException e) {
e.printStackTrace();
}
}
}
总结
以上案例涵盖了文件读写、网络通信、数据处理等实际开发中常见的场景。通过这些案例,可以更好地理解 Java 流、文件和 IO 的应用。希望对你有所帮助!