Java中的I/O流是指用于处理输入和输出操作的类和方法集合。它提供了丰富的工具和功能,可以让我们在程序中读取和写入不同类型的数据。
下面是Java中I/O流的知识点:
一. 输入流和输出流:
1. 输入流(InputStream):
- 输入流用于从外部源(如文件、网络等)读取数据到程序中。
- InputStream 是抽象类,常用的子类有FileInputStream、BufferedInputStream、DataInputStream等。
- 可以使用read()方法从输入流中读取一个字节或一段字节数组,并返回读取到的数据。
- 通过close()方法关闭输入流,释放系统资源。
2. 输出流(OutputStream):
- 输出流用于将程序中的数据写入至外部目标(如文件、网络等)。
- OutputStream 是抽象类,常用的子类有FileOutputStream、BufferedOutputStream、DataOutputStream等。
- 可以使用write()方法将一个字节或一段字节数组写入输出流。
- 通过flush()方法将缓冲区中的数据立即输出,而不是等到缓冲区满或者流关闭时才输出。
- 通过close()方法关闭输出流,释放系统资源。
刷新flush() 和close()方法的区别?
当我们写出的时候,担心有字节没有写出完全,可以用刷新的方法。
一般我们关闭流通道的时候,用close()方法。
底层他会每次先刷新流通道,调用flush()方法。
二. 字节流和字符流:
- 字节流(ByteStream):以字节为单位进行读写操作,主要用于处理二进制数据。
- 字节输入流(InputStream):如FileInputStream,用于从文件或其他源中读取字节数据。
- 字节输出流 (OutputStream):如FileOutputStream,用于向文件或其他目标写入字节数据。
- 字符流(CharacterStream):以字符为单位进行读写操作,主要用于处理文本数据。
- 字符输入流(Reader):如FileReader,用于从文件或其他源中读取字符数据。
- 字符输出流(Writer):如FileWriter,用于向文件或其他目标写入字符数据。
三. 缓冲流:
缓冲流(BufferedInputStream 和 BufferedOutputStream):
- 缓冲流是对输入流和输出流的包装,提供了缓冲功能,可以减少频繁的IO操作,提高效率。
- BufferedInputStream 和 BufferedOutputStream 分别用于对输入流和输出流进行缓冲处理。
- 缓冲流内部维护了一个缓冲区,通过read()和write()方法分别从缓冲区读取数据和写入数据。
四. 文件操作:
- 文件类(File):用于表示文件或目录的抽象路径名。
- 文件输入流(FileInputStream)和文件输出流(FileOutputStream):用于读写文件数据。
下面是一些常见的IO流文件操作示例:
1. 读取文件内容:
```java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class FileReadExample {
public static void main(String[] args) {
String filePath = "文件路径";
try {
FileReader fileReader = new FileReader(filePath);
BufferedReader bufferedReader = new BufferedReader(fileReader);
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
bufferedReader.close();
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
```
在上述示例中,我们使用 FileReader 和 BufferedReader 来读取文件内容。通过循环读取每一行数据,并输出到控制台。
2. 写入文件内容:
```java
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class FileWriteExample {
public static void main(String[] args) {
String filePath = "文件路径";
String content = "写入的内容";
try {
FileWriter fileWriter = new FileWriter(filePath);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write(content);
bufferedWriter.close();
fileWriter.close();
System.out.println("内容已写入文件");
} catch (IOException e) {
e.printStackTrace();
}
}
}
```
在上述示例中,我们使用 FileWriter 和 BufferedWriter 来写入文件内容。将要写入的内容传递给 write() 方法,然后关闭流。
五. 标准输入输出流:
- 标准输入流(System.in):用于从控制台接收用户的输入。
- 标准输出流(System.out):用于向控制台输出结果。
六. 序列化和反序列化:
在Java中,IO流的序列化和反序列化是用于将对象转换为字节序列以便存储或传输,并在需要时将其重新构造为对象的过程。
1. 序列化:将对象转换为字节序列的过程称为序列化。通过将对象的状态信息写入输出流,可以实现将对象保存到文件或通过网络传输。Java中提供了两个主要的序列化流:ObjectOutputStream和ByteArrayOutputStream。要实现序列化,需要满足以下条件:
- 类必须实现java.io.Serializable接口。
- 所有非序列化的字段必须标记为transient。
2. 反序列化:将字节序列转换回对象的过程称为反序列化。通过读取输入流中的字节信息并重新构造对象,可以还原之前序列化的对象。Java中提供了两个主要的反序列化流:ObjectInputStream和ByteArrayInputStream。要实现反序列化,需要满足以下条件:
- 类必须实现java.io.Serializable接口。
- 类的序列化ID必须与序列化时使用的ID相同。
3. 实例化具有默认构造函数的对象:在反序列化过程中,如果类没有提供自定义的readObject()方法,Java会试图实例化一个具有默认构造函数的对象,并通过将对象的状态信息从字节序列中读取来恢复对象的状态。
4. 自定义序列化和反序列化:如果需要对序列化和反序列化过程进行更精细的控制,可以在类中实现以下两个方法:
- private void writeObject(java.io.ObjectOutputStream out) throws IOException:自定义序列化过程。
- private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException:自定义反序列化过程。
总之,通过Java的IO流的序列化和反序列化功能,我们可以方便地将对象转换为字节序列并进行存储或传输,以及将字节序列还原为对象。
七. 网络操作:
- Socket类:用于实现网络通信中的客户端和服务器端。
- URL类:用于处理URL地址。
八. 压缩和解压缩:
- 压缩流(ZipInputStream、GZIPInputStream等):用于解压缩数据。
- 解压缩流(ZipOutputStream、GZIPOutputStream等):用于压缩数据。
九. 对象流:
- 对象输入流(ObjectInputStream)和对象输出流(ObjectOutputStream):用于读写Java对象。
十. 处理文本文件:
- 字符编码(Charset):用于字符编码和解码。
- 字符集转换器(InputStreamReader、OutputStreamWriter):用于在字节流和字符流之间进行转换。
十一.综合练习:
读取文本,替换字符串,写出到另一个文本。
需求:将 a.txt中的一下文本,读取之后,进行替换
你好,我的名字是{name},
我是一只{type},
我的主人是{master}。
替换之后
你好,我的名字是{哮天犬},
我是一只{狗},
我的主人是{二郎神}。
最终,把替换后的字符串,写入 b.txt文件中。
具体代码:
public class Test{
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("b.txt"); // 字符读取流对象创建
StringBuffer sb = new StringBuffer(); // 创建一个字符串缓冲对象。
char[] arr = new char[1024]; // 定义一个字符数组,
int len; // 返回读取到的数组长度。
while ((len = fr.read(arr)) != -1) {
sb.append(arr); // 把数组中的字符,拼接到字符串对象中。
}
// 替换读取到的文本的内容。
String info = sb.toString().replace("name", "哮天犬");
String info2 = info.replace("type", "狗");
String newinfo = info2.replace("master", "二郎神");
// 创建文件输出流对象,然后写出字符串内容。
FileWriter fw = new FileWriter("bbb.txt");
fw.write(newinfo);
fr.close(); // 关闭流通道
fw.close();// 关闭流通道。
System.out.println("写出完成");
}
}
十二.通过IO流给文件加密
通过IO流给文件加密可以使用以下步骤:
1. 打开原始文件和目标文件的输入输出流,即创建 FileInputStream 和 FileOutputStream 对象。确保原始文件存在且可读,并且目标文件可以被创建或覆盖写入。
2. 创建加密算法,例如使用 AES(高级加密标准)算法。你可以使用 javax.crypto 包来实现加密算法。首先,创建一个 SecretKey 对象,可以通过 KeyGenerator 类生成一个密钥。然后,使用 Cipher 类来初始化加密模式,并将密钥传递给它。
3. 使用 FileInputStream 读取原始文件的内容,并使用 Cipher 对象中的 encrypt() 方法进行加密。encrypt() 方法将返回一个字节数组,表示加密后的数据。
4. 使用 FileOutputStream 将加密后的数据写入目标文件中。
5. 最后,关闭输入输出流,释放资源。
下面是一个示例代码:
```java
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
public class FileEncryptionExample {
public static void main(String[] args) {
String sourceFilePath = "原始文件路径";
String targetFilePath = "加密后的文件路径";
try {
// 创建密钥
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(128);
SecretKey secretKey = keyGenerator.generateKey();
// 创建密码器
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
// 打开输入输出流
FileInputStream fis = new FileInputStream(sourceFilePath);
FileOutputStream fos = new FileOutputStream(targetFilePath);
// 执行加密并写入目标文件
CipherInputStream cis = new CipherInputStream(fis, cipher);
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = cis.read(buffer)) != -1) {
fos.write(buffer, , bytesRead);
}
// 关闭流
cis.close();
fos.close();
fis.close();
System.out.println("文件加密成功");
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IOException e) {
e.printStackTrace();
}
}
}
```
请将 "原始文件路径" 和 "加密后的文件路径" 替换为你实际的文件路径。运行该代码后,原始文件将被加密,并保存到目标文件中。