是否有比创建符合以下条件的流文件读取器类更好的可选Java1.6解决方案?
\n终止readLine()从文件中读取一条随机行。readLine()的调用不应返回同一行两次更新:
上下文:该文件的内容是通过Unix命令创建的,以获取包含在给定目录中的所有路径的目录列表;有数百万至10亿个文件(这在目标文件中产生了数百万至10亿行)。如果在创建过程中有某种方式随机地将路径分配到文件中,那么这也是一个可接受的解决方案。
发布于 2013-01-16 15:00:08
如果文件的数量确实是任意的,那么跟踪处理过的文件在内存使用方面可能会出现相关问题(如果在文件中跟踪而不是在列表或集合中跟踪,则是IO时间)。保留不断增加的选定行列表的解决方案也适用于与时间相关的问题。
我会考虑以下几点:
发布于 2013-01-15 13:28:24
为了避免读取整个文件(在您的情况下可能是不可能的),您可能需要使用RandomAccessFile而不是标准的FileInputStream。使用RandomAccessFile,您可以使用seek(long position)方法跳过文件中的任意位置,然后在那里开始读取。代码看起来会是这样的。
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验证行的唯一性。
发布于 2013-01-15 13:20:43
预处理输入文件并记住每一行的偏移量.使用BitSet跟踪已使用的行。如果您想节省一些内存,那么请记住每16行的偏移量;仍然很容易跳入文件并在一个16行的块内进行顺序查找。
https://stackoverflow.com/questions/14338350
复制相似问题