编写一个带缓存的对文本文件进行读写操作的java程序。 (1)可以读取不同位置的信息 (2)可以把数据写入到不同的位置
时间: 2024-02-06 17:09:50 浏览: 24
以下是一个简单的带缓存的对文本文件进行读写操作的Java程序,实现了读取和写入不同位置的功能:
```java
import java.io.*;
public class FileCache {
private static final int CACHE_SIZE = 1024; // 缓存大小为 1KB
private RandomAccessFile file;
private byte[] cache;
private int cacheStart; // 缓存开始的位置
private int cacheEnd; // 缓存结束的位置
public FileCache(String path, String mode) throws IOException {
file = new RandomAccessFile(path, mode);
cache = new byte[CACHE_SIZE];
cacheStart = -1;
cacheEnd = -1;
}
public void seek(long pos) throws IOException {
if (pos >= cacheStart && pos < cacheEnd) { // 如果要读取的位置在缓存范围内
file.seek(pos); // 直接定位到文件位置
} else { // 如果要读取的位置不在缓存范围内
flushCache(); // 先将缓存写入文件
cacheStart = (int) (pos / CACHE_SIZE) * CACHE_SIZE; // 计算缓存开始的位置
cacheEnd = cacheStart + CACHE_SIZE; // 计算缓存结束的位置
file.seek(cacheStart); // 定位到缓存开始的位置
file.read(cache, 0, CACHE_SIZE); // 读取缓存数据
}
}
public String readLine() throws IOException {
StringBuilder sb = new StringBuilder();
int b;
while ((b = readByte()) != -1) {
if (b == '\r') { // 忽略 \r
continue;
} else if (b == '\n') { // 读取到 \n,返回字符串
return sb.toString();
} else {
sb.append((char) b); // 将字符添加到字符串中
}
}
return sb.length() > 0 ? sb.toString() : null; // 如果字符串不为空,返回字符串,否则返回 null
}
public void write(String str, long pos) throws IOException {
byte[] data = str.getBytes();
int offset = 0;
while (offset < data.length) {
if (pos >= cacheStart && pos < cacheEnd) { // 如果要写入的位置在缓存范围内
int index = (int) (pos - cacheStart); // 计算在缓存中的位置
int len = Math.min(data.length - offset, CACHE_SIZE - index); // 计算可以写入的数据长度
System.arraycopy(data, offset, cache, index, len); // 将数据拷贝到缓存中
offset += len;
pos += len;
} else { // 如果要写入的位置不在缓存范围内
flushCache(); // 先将缓存写入文件
cacheStart = (int) (pos / CACHE_SIZE) * CACHE_SIZE; // 计算缓存开始的位置
cacheEnd = cacheStart + CACHE_SIZE; // 计算缓存结束的位置
file.seek(cacheStart); // 定位到缓存开始的位置
}
}
flushCache(); // 写入完成后,将缓存写入文件
}
private int readByte() throws IOException {
if (cacheStart == -1 || file.getFilePointer() >= cacheEnd) { // 如果缓存为空或已经读取完毕,需要重新读取缓存
cacheStart = (int) (file.getFilePointer() / CACHE_SIZE) * CACHE_SIZE; // 计算缓存开始的位置
cacheEnd = cacheStart + CACHE_SIZE; // 计算缓存结束的位置
file.seek(cacheStart); // 定位到缓存开始的位置
file.read(cache, 0, CACHE_SIZE); // 读取缓存数据
}
if (file.getFilePointer() >= file.length()) { // 如果已经读取到文件末尾,返回 -1
return -1;
}
return cache[(int) (file.getFilePointer() - cacheStart)] & 0xff; // 返回缓存中的数据
}
private void flushCache() throws IOException {
if (cacheStart != -1) { // 如果缓存不为空,需要将缓存写入文件
file.seek(cacheStart); // 定位到缓存开始的位置
file.write(cache, 0, cacheEnd - cacheStart); // 写入缓存数据
cacheStart = -1;
cacheEnd = -1;
}
}
public void close() throws IOException {
flushCache(); // 关闭文件前,先将缓存写入文件
file.close();
}
}
```
使用示例:
```java
public static void main(String[] args) throws IOException {
// 创建 FileCache 对象,打开文件
FileCache fileCache = new FileCache("test.txt", "rw");
// 读取文件中第 10 ~ 20 个字符
fileCache.seek(10);
byte[] buf = new byte[10];
int len = fileCache.read(buf);
System.out.println(new String(buf, 0, len));
// 写入数据到文件中第 30 ~ 40 个字符
fileCache.write("Hello World", 30);
// 读取文件中第 25 ~ 35 行
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("test.txt")));
for (int i = 0; i < 25; i++) {
reader.readLine();
}
for (int i = 0; i < 10; i++) {
String line = reader.readLine();
System.out.println(line);
}
// 关闭文件
fileCache.close();
}
```