Java中平面文件中的记录操作

Java中平面文件中的记录操作,java,memory,collections,crud,flat-file,Java,Memory,Collections,Crud,Flat File,这是我在StackOverflow的第一篇文章。我不是Java新手,但我也不是专家或专业程序员。这是相当长的一段时间,我有一些想法在我的脑海里,我不知道如何实施它们在一个适当的方式 一般来说,我正在编写一个软件(实际上是许多单独的应用程序)来处理一个列表(比如电话号码列表)。我的应用程序必须包含在单个文件(jar)或文件夹/目录中。它必须是一个“开箱即用,点击并运行”的应用程序。用Java创建GUI不是问题 我的问题是数据的存储。不要建议我使用任何第三方数据库服务器或应用程序;因为我将以普通格式

这是我在StackOverflow的第一篇文章。我不是Java新手,但我也不是专家或专业程序员。这是相当长的一段时间,我有一些想法在我的脑海里,我不知道如何实施它们在一个适当的方式

一般来说,我正在编写一个软件(实际上是许多单独的应用程序)来处理一个列表(比如电话号码列表)。我的应用程序必须包含在单个文件(jar)或文件夹/目录中。它必须是一个“开箱即用,点击并运行”的应用程序。用Java创建GUI不是问题

我的问题是数据的存储。不要建议我使用任何第三方数据库服务器或应用程序;因为我将以普通格式(或XML文件)将数据存储在平面文件中

目前,我想到了两个典型的想法,可以对文件中的数据进行CRUD(CRUD=CRUD=Create Read Update Delete)。详情如下:-

1不要使用集合

  • 创建-将记录附加到文件
  • 读取-读取完整文件
  • 更新-将所有记录复制到新文件中,需要替换的记录除外复制新数据;删除旧文件;将新文件重命名为旧文件
  • 删除-将所有记录复制到新文件中,需要删除的记录除外;删除旧文件;将新文件重命名为旧文件
  • 优点:内存需求少
  • 缺点:大量的文件IO
2使用集合

  • 应用程序启动-将所有记录从文件加载到集合中
  • 应用程序停止-将集合中的所有记录保存到文件中
  • 创建-将记录添加到集合
  • 读取-读取集合的所有元素
  • 更新-直接在集合中更新记录
  • 删除-从集合中删除记录
  • 优点:文件IO非常少
  • 缺点:内存要求高。如果加载所有记录时内存不足,应用程序就会崩溃
这两种方法各有利弊。还有别的办法吗?或者在这两种方法之间有没有一种方法?我这里急需一些指导。这个问题已经讨论了很长时间了。欢迎提出任何理论、建议或建议


下面的方法可以吗?这是有害的还是有害的?我的意思是它的缺点是什么

注意:r-->记录。每条记录都在一个新行上。每个记录中的字段由一些分隔符分隔,例如“::”。因此,我将使用BufferedReader轻松获取每一行。这些尺寸只是假设的,或者只是给你一张图片

File={r1r2r3r4r5…r500}//该文件有500条记录
集合cPrev、cCurrent、cNext//3个包含连续记录的集合对象;每人持有(比如)30条记录

所以一开始
cPrev={}
cCurrent={r1 r2 r3…r30}//由主线程填充
cNext={r31 r32 r33…r60}//在用户查看cCurrent时由子线程填充

cCurrent可供用户查看。用户可以上下滚动(或任意方向),查看所有30条记录。现在,用户希望看到下一组记录。 所以
cPrev=cCurrent//主线程
cCurrent=cNext//主线程
因此
cPrev={r1r2r3…r30}
cCurrent={r31 r32 r33…r60}
cNext={r61 r62 r63…r90}//在用户查看cCurrent时由子线程填充

考虑以下状态
cPrev={r121 r121 r123…r150}
cCurrent={r151 r152 r153…r180}
cNext={r181 r182 r183…r210}

如果用户希望查看r151之前的记录,则
cNext=cCurrent//主线程
cCurrent=cPrev//主线程

所以 cPrev={r90 r91 r92…r120}//在用户查看cCurrent时由子线程填充
cCurrent={r121 r121 r123…r150}
cNext={r151 r152 r153…r180}

显然,只要文件中有前后记录,就可以执行下一个和上一个。执行“下一步”操作简单易行。我不需要关闭文件连接,只需要从我停止的地方开始阅读


但是“以前”的行动呢?我想到的唯一解决方案是[1]关闭当前文件连接[2]打开新文件连接[3]开始从文件开始读取,直到到达相关记录,[4]然后将记录集分配给集合。(我不知道怎么问)这种方法有什么不对?另外,这里有更好的方法或算法吗?伙计们,保持简单,但不要压缩。我不是Java大师。

我可以想到以下方法-

使用某种“缓存”机制和一些策略(后进先出、先进先出),在内存中读取多达100条记录,其余的保留在平面文件中


编写一个后台线程来处理集合的更新/添加/删除,并相应地更新平面文件

一个嵌入式数据库,如Java DB。它存储在一个文件中,有很好的教程。它允许扩展到大型数据库:当应用程序速度过快时,会给人留下不太好的印象


此外,您不需要开发自己的类似数据库的机制,但可以专注于业务逻辑。

您正在管理电话号码列表。我想您现在并不真正关心应用程序的性能;您将不会通过大量数据进行困难的查询

那么为什么不将Hibernate/JPA与嵌入式数据库一起使用呢?这样,您可以对简单数据执行CRUD,但如果需要,可以轻松扩展到关系模型。嵌入式数据库管理缓存、事务、锁定。。。缺点是学习曲线陡峭

因此,如果您想避免陡峭的学习曲线,我建议您使用Collections方法。如果应用程序内存不足,您会担心它会崩溃。这是真的吗
private List<DataSlice> slices;
public class DataSlice {
  private ArrayList<Object> data;
  private File backingFile;

  private void load() {
    data = deserialize(backingFile);
  }

  private void release() {
    if(dirty) save(data, backingFile);
    data = null; // data is garbage collected, but there is a risk the objects are still referenced in memory
  }

  private void doCrudOperation() {
    dirty = true;
    doSomething();
  }
}