首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java:带有状态的ASCII随机行文件访问

Java:带有状态的ASCII随机行文件访问
EN

Stack Overflow用户
提问于 2013-01-15 13:01:57
回答 4查看 513关注 0票数 4

是否有比创建符合以下条件的流文件读取器类更好的可选Java1.6解决方案?

  • 给定任意大大小的ASCII文件,其中每一行都由\n终止
  • 对于某些方法的每次调用,readLine()从文件中读取一条随机行。
  • 在文件句柄的生命周期中,对readLine()的调用不应返回同一行两次

更新:

  • 所有的行最终都必须被读出。

上下文:该文件的内容是通过Unix命令创建的,以获取包含在给定目录中的所有路径的目录列表;有数百万至10亿个文件(这在目标文件中产生了数百万至10亿行)。如果在创建过程中有某种方式随机地将路径分配到文件中,那么这也是一个可接受的解决方案。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-01-16 15:00:08

如果文件的数量确实是任意的,那么跟踪处理过的文件在内存使用方面可能会出现相关问题(如果在文件中跟踪而不是在列表或集合中跟踪,则是IO时间)。保留不断增加的选定行列表的解决方案也适用于与时间相关的问题。

我会考虑以下几点:

  1. 创建n个“桶”文件。可以根据考虑到文件和系统内存数量的内容来确定n。(如果n很大,则可以生成n的子集,以使打开的文件句柄保持向下。)
  2. 每个文件的名称都被散列,并进入一个适当的桶文件中,根据任意条件“对”目录进行“切分”。
  3. 读取桶文件内容(仅文件名)和进程原样(哈希机制提供的随机性),或者选择rnd(n)并在执行过程中删除,提供了更多的随机性。
  4. 或者,您可以使用随机访问的想法,从列表中删除索引/偏移量。
票数 1
EN

Stack Overflow用户

发布于 2013-01-15 13:28:24

为了避免读取整个文件(在您的情况下可能是不可能的),您可能需要使用RandomAccessFile而不是标准的FileInputStream。使用RandomAccessFile,您可以使用seek(long position)方法跳过文件中的任意位置,然后在那里开始读取。代码看起来会是这样的。

代码语言:javascript
复制
RandomAccessFile raf = new RandomAccessFile("path-to-file","rw");
HashMap<Integer,String> sampledLines = new HashMap<Integer,String>();
for(int i = 0; i < numberOfRandomSamples; i++)
{
    //seek to a random point in the file
    raf.seek((long)(Math.random()*raf.length()));

    //skip from the random location to the beginning of the next line
    int nextByte = raf.read();
    while(((char)nextByte) != '\n')
    {
        if(nextByte == -1) raf.seek(0);//wrap around to the beginning of the file if you reach the end
        nextByte = raf.read();
    }

    //read the line into a buffer
    StringBuffer lineBuffer = new StringBuffer();
    nextByte = raf.read();
    while(nextByte != -1 && (((char)nextByte) != '\n'))
        lineBuffer.append((char)nextByte);

    //ensure uniqueness
    String line = lineBuffer.toString();
    if(sampledLines.get(line.hashCode()) != null)
        i--;
    else
       sampledLines.put(line.hashCode(),line);
}

在这里,sampledLines应该将随机选择的行放在末尾。您可能需要检查您没有随机跳到文件的末尾,以避免在这种情况下出现错误。

编辑:,我将其包装到文件的开头,以防您到达末尾。这是个很简单的支票。

编辑2: i让它使用HashMap验证行的唯一性。

票数 5
EN

Stack Overflow用户

发布于 2013-01-15 13:20:43

预处理输入文件并记住每一行的偏移量.使用BitSet跟踪已使用的行。如果您想节省一些内存,那么请记住每16行的偏移量;仍然很容易跳入文件并在一个16行的块内进行顺序查找。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14338350

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档