C # - удалить дубликаты строк в текстовом файле - PullRequest
4 голосов
/ 17 июня 2011

Может ли кто-нибудь продемонстрировать, как файл проверяется на наличие дублирующих строк, а затем удаляются любые дубликаты, либо перезаписывая существующий файл, либо создавать новый файл с удаленными дублирующимися строками

Ответы [ 5 ]

10 голосов
/ 17 июня 2011

Если вы используете .NET4, вы можете использовать комбинацию File.ReadLines и File.WriteAllLines:

var previousLines = new HashSet<string>();

File.WriteAllLines(destinationPath, File.ReadLines(sourcePath)
                                        .Where(line => previousLines.Add(line)));

Это работает почти так же, как и метод Distinct LINQ, с одним важным отличием: вывод Distinct не обязательно будет в том же порядке, что и последовательность ввода. Использование HashSet<T> явно предоставляет эту гарантию.

2 голосов
/ 17 июня 2011
File.WriteAllLines(topath, File.ReadAllLines(frompath).Distinct().ToArray());

Редактировать: изменено для работы в .net 3.5

1 голос
/ 17 июня 2011
// Requires .NET 3.5
private void RemoveDuplicate(string sourceFilePath, string destinationFilePath)
{
    var readLines = File.ReadAllLines(sourceFilePath, Encoding.Default);

    File.WriteAllLines(destinationFilePath, readLines.Distinct().ToArray(), Encoding.Default);
}
1 голос
/ 17 июня 2011

Какого размера файла мы говорим?

Одной из стратегий может быть чтение строк по одной за раз и загрузка их в структуру данных, которую можно легко проверить на наличие существующего элемента, например Hashset<int>. Я знаю, что могу надежно хэшировать каждую строковую строку файла, используя GetHashCode () (используется для внутренней проверки равенства строк - это то, что мы хотим определить дубликаты), и просто проверять известные хэши. Итак, что-то вроде

var known = new Hashset<int>();
using (var dupe_free = new StreamWriter(@"c:\path\to\dupe_free.txt"))
{
    foreach(var line in File.ReadLines(@"c:\path\to\has_dupes.txt")
    {
        var hash = line.GetHashCode();
        if (!known.Contains(hash)) 
        {
            known.Add(hash);
            dupe_free.Write(line);
        }
    }
}

Кроме того, вы можете воспользоваться Distinct() методом Линка и сделать это в одной строке, как Блинди предложил:

File.WriteAllLines(@"c:\path\to\dupe_free.txt", File.ReadAllLines((@"c:\path\to\has_dupes.txt").Distinct().ToArray());
1 голос
/ 17 июня 2011

Псевдокод:

open file reading only

List<string> list = new List<string>();

for each line in the file:
    if(!list.contains(line)):
        list.append(line)

close file
open file for writing

for each string in list:
    file.write(string);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...