Как Leigh Caldwell заявил, оптимизатор запросов может произвести различные планы запросов на основе того, что функционально похоже на тот же SQL-оператор. Для дополнительных материалов для чтения на этом взгляните на следующие два postings:-
блога Одна регистрация от Команды Оптимизатора Oracle
"Структурированных данных", я надеюсь, что Вы находите это интересным.
Это должно работать (и будет копироваться с большими файлами).
Обратите внимание, что при этом удаляются только дубликаты последовательных строк, то есть
a
b
b
c
b
d
в итоге будет
a
b
c
b
d
Если вы не хотите нигде дубликатов, вам нужно сохранить набор строк, которые вы уже видели.
using System;
using System.IO;
class DeDuper
{
static void Main(string[] args)
{
if (args.Length != 2)
{
Console.WriteLine("Usage: DeDuper <input file> <output file>");
return;
}
using (TextReader reader = File.OpenText(args[0]))
using (TextWriter writer = File.CreateText(args[1]))
{
string currentLine;
string lastLine = null;
while ((currentLine = reader.ReadLine()) != null)
{
if (currentLine != lastLine)
{
writer.WriteLine(currentLine);
lastLine = currentLine;
}
}
}
}
}
Обратите внимание, что это предполагает ] Encoding.UTF8
, и вы хотите использовать файлы. Однако это легко обобщить как метод:
static void CopyLinesRemovingConsecutiveDupes
(TextReader reader, TextWriter writer)
{
string currentLine;
string lastLine = null;
while ((currentLine = reader.ReadLine()) != null)
{
if (currentLine != lastLine)
{
writer.WriteLine(currentLine);
lastLine = currentLine;
}
}
}
(Обратите внимание, что это ничего не закрывает - вызывающий должен это делать.)
Вот версия, которая удалит все дубликаты, а не просто последовательные:
static void CopyLinesRemovingAllDupes(TextReader reader, TextWriter writer)
{
string currentLine;
HashSet<string> previousLines = new HashSet<string>();
while ((currentLine = reader.ReadLine()) != null)
{
// Add returns true if it was actually added,
// false if it was already there
if (previousLines.Add(currentLine))
{
writer.WriteLine(currentLine);
}
}
}
Для маленьких файлов:
string[] lines = File.ReadAllLines("filename.txt");
File.WriteAllLines("filename.txt", lines.Distinct().ToArray());
Долгое время файл (и непоследовательные дублирования), я бы скопировал файлы построчно, построив таблицу поиска // хеш-позиции по ходу дела.
При копировании каждой строки проверяйте хешированное значение, если есть коллизия, дважды проверьте, что строка такая же и перейти к следующей. (
Только для довольно больших файлов.
Вот метод потоковой передачи, который требует меньше накладных расходов, чем чтение всех уникальных строк в память.
var sr = new StreamReader(File.OpenRead(@"C:\Temp\in.txt"));
var sw = new StreamWriter(File.OpenWrite(@"C:\Temp\out.txt"));
var lines = new HashSet<int>();
while (!sr.EndOfStream)
{
string line = sr.ReadLine();
int hc = line.GetHashCode();
if(lines.Contains(hc))
continue;
lines.Add(hc);
sw.WriteLine(line);
}
sw.Flush();
sw.Close();
sr.Close();