Я пытаюсь найти эффективный способ удаления дубликатов строк из файла без чтения всего содержимого файла в памяти. Файл произвольно упорядочен. Я пытаюсь не читать его в памяти, потому что файл слишком большой (20GB+). Может ли кто-нибудь предложить способ исправить мой код, чтобы он не читал весь файл в памяти?
val oldFile="steam_out_scala.txt"
val noDupFile="nodup_steam_out.txt"
import scala.io.Source
import java.io.{FileReader, FileNotFoundException, IOException}
import java.io.FileWriter;
import scala.collection.mutable.ListBuffer
var numbers = new ListBuffer[String]()
val fw = new FileWriter(noDupFile, true)
for (line <- Source.fromFile(oldFile).getLines()) {
numbers+=line
}
numbers.distinct.foreach((x)=>{
//println(x)
fw.write(x)
})
fw.close()
Что я знаю о данных:
каждая строка длинная: 76561193756669631 он не упорядочен, и конечный результат не нужно заказывать каким-либо образом список был сгенерирован с использованием другой программы. Число может быть повторено (0,4 миллиона)
Вы можете решить эту проблему несколькими способами:
1) Прочитайте исходный файл по строкам и перед добавлением его в новый файл, который содержит только уникальные строки, проверяет этот файл, если такая строка уже существует. Это будет довольно медленным, потому что O(n^2)
.
Код будет выглядеть примерно так:
val oldFile="steam_out_scala.txt"
val noDupFile="nodup_steam_out.txt"
import scala.io.Source
import java.io.{FileReader, FileNotFoundException, IOException}
import java.io.FileWriter;
import scala.collection.mutable.ListBuffer
var numbers = new ListBuffer[String]()
val fw = new FileWriter(noDupFile, true)
for (line <- Source.fromFile(oldFile).getLines()) {
if(Source.fromFile(noDupFile).getLines().forall(!_.equals(line))) {
fw.write(line)
}
}
fw.close()
2) Вы можете выполнить так называемую внешнюю сортировку, которая была изобретена именно для сортировки больших объемов данных, которые не вписываются в память и быстрее, чем описанный выше метод. Он сортирует небольшие фрагменты всего набора данных (который может вписываться в память), сохраняет их во временных файлах и затем объединяет их. Удовлетворительный факт, если у вашей ОС есть опция виртуальной памяти, тогда ОС будет делать что-то подобное для вас, поменяв данные, которые не помещаются в память на жесткий диск.
Это универсальные решения, которые будут работать с любыми данными. Если вы можете предоставить более подробную информацию о содержании файла, мы могли бы придумать что-то более умное.
Вы можете использовать фильтр цветения (https://en.m.wikipedia.org/wiki/Bloom_filter), чтобы удалить дублирование из файла