我是java和文件的初学者。我有一个任务来计算某个符号在文件中出现的次数,但是我必须使用随机数量的线程。我的想法是将文件拆分为我必须使用的许多线程,将其添加到集合中,然后使用具有固定线程池的ExecutorService。但我不确定如何将文件分成同样大的部分。我很感激任何提示!
你说的随机线程数是什么意思?你是指cpu上可用的核数吗?或者从函数中抽取一个随机数并应用这么多线程!
我对解决这个问题的看法是
- 读取文件,然后遍历其内容,将它们存储在数组列表中。
- 根据你的随机数将数组列表拆分为数组或更小的数组列表。
- 创建随机数量的线程并将它们添加到线程池中。
- 将较小的数组/数组列表传递给线程,线程函数中的逻辑(如果element.equals(symbol) {then count})
- 每个线程返回一个数字,把这些数字加起来,你就得到了你的发生率。
如何将文件分割成同样大的部分
将实际的I/O读取分成几个线程是没有意义的,因为在单个线程中读取整个文件会更快(更少的随机访问和争用)。为什么?
因此,您应该简单地按顺序读取文件,一个块一个块,并在每次块变得足够大时提交符号计数任务。
java.util。Scanner很好,因为它允许流式传输文件内容而不将其完全放在内存中,这对于大小超过RAM的文件来说是很好的。
StringBuffer chunk = new StringBuffer();
try(FileInputStream inputStream = new FileInputStream("filename.txt");
Scanner sc = new Scanner(inputStream, "UTF-8")) {
while (sc.hasNextLine()) {
chunk.append(sc.nextLine());
if (chunk.length() > FILE_SIZE / THREAD_NB) {
executorService.submit( () -> handleChunkSymbolCounting(chunk) );
chunk = new StringBuffer();
}
}
}
注:如果你需要一个物理分割的文件,即如果你想创建中间文件,如file001.txt, file002.txt…fileXXX.txt。然后需要并行化文件读取。
上面的代码仍然可以工作,但是您提交的不是计数任务,而是文件写入任务。