Цепной массив строк в файле C # - PullRequest
0 голосов
/ 22 декабря 2011

У меня есть три массива строк, и я хочу объединить их и записать в файл (S1 [] + S2 [] + S3 []). Каков наилучший способ сделать это?

Ответы [ 7 ]

1 голос
/ 22 декабря 2011

Если вы просто хотите объединить массивы, чтобы записать их в текстовый файл.,.

using(var writer = new StreamWriter("MyFile.txt"))
{
    foreach(var item in arr1.union(arr2).union(arr3))
       writer.WriteLine(item)
}

Этот ответ вызвал " Пишите один раз быстрее, чем пишите много дебатов", я хотел бы рассмотреть проблему в телеответ.

Во-первых, любой метод для небольших объемов данных не будет иметь большого значения, так или иначе.Действительно, в современных системах для размеров в мегабайтах (и, возможно, больше) разница в производительности не будет большой (на данный момент я ничего не тестировал, но положу свои деньги прямо на дисковый ввод-вывод).

Проблема действительно заключается в масштабируемости, если у вас загруженная система, и у вас есть пара 100-мегабайтных данных, то метод «сначала буфер» будет значительно медленнее, вынастраивая себя на целый мир боли из-за сбоев страниц ОС, особенно если ваши данные распределены по нескольким страницам, вы будете постоянно загружать и выгружать страницы памяти, что замедлит не только ваше приложение, но и всю машину.

Сейчас я напишу некоторый код для сравнения обоих подходов, вскоре выложу код и мои результаты.

И результаты есть, производительность на самом деле невеликаразница.Для 12 КБ данных * 100 записей поступают (очевидно, на моей машине) примерно за 1 минуту 38 секунд.При повторных запусках прямая передача на диск выполняется быстрее, но не более чем на полсекунды.

Настоящим сюрпризом были File.WriteAllLines и File.AppendAllLines, что заняло 8 минут 35 секунд.Я не пробовал объединять массивы и вызывать File.WriteAllLines один раз (доступно после .net 4.0), но я считаю, что было бы лучше, задержка, вероятно, открывает файл несколько раз.

Учитываячто различия (как и предполагалось) незначительны для небольших объемов данных, я бы предпочел пойти по более простому коду и записать строки непосредственно в файл.

Я не запускал его большечем пару раз, потому что это требует времени, если кто-то другой хочет настроить его так, чтобы он работал в течение ночи и получал более точные тренды, пожалуйста, будьте моим гостем.

    public static void Main(string[] args)
    {

        var arr1 = BuildArr(1000000);
        var arr2 = BuildArr(1000000);
        var arr3 = BuildArr(1000000);

        DoDirectToDisk(arr1, arr2, arr3);
        DoBuffered(arr1, arr2, arr3);
        DoWriteLines(arr1, arr2, arr3);

    }

    private static void DoWriteLines(string[] arr1, string[] arr2, string[] arr3)
    {
        var sw = new Stopwatch();
        sw.Start();
        for (int i = 0; i < 100; i++)
        {
            File.WriteAllLines(@"C:\WriteLines.txt", arr1);
            File.AppendAllLines(@"C:\WriteLines.txt", arr1);
            File.AppendAllLines(@"C:\WriteLines.txt", arr1);
        }
        sw.Stop();
        Console.WriteLine("Write Lines {0}", sw.Elapsed);
    }

    private static void DoBuffered(string[] arr1, string[] arr2, string[] arr3)
    {
        var sw = new Stopwatch();
        sw.Start();
        for (int i = 0; i < 100; i++)
        {
            using (var writer = new StringWriter())
            {
                foreach (var item in arr1.Union(arr2).Union(arr3))
                    writer.WriteLine(item);
                File.WriteAllText(@"C:\buffered.txt", writer.ToString());
            }
        }
        sw.Stop();
        Console.WriteLine("Buffered {0}", sw.Elapsed);
    }

    private static void DoDirectToDisk(string[] arr1, string[] arr2, string[] arr3)
    {
        var sw = new Stopwatch();
        sw.Start();
        for (int i = 0; i < 100; i++)
            using (var writer = new StreamWriter(@"C:\Direct.txt"))
            {
                foreach (var item in arr1.Union(arr2).Union(arr3))
                    writer.WriteLine(item);
            }
        sw.Stop();
        Console.WriteLine("Direct To Disk took {0}", sw.Elapsed);
    }

Последний вывод был

Direct To Disk заняло 00: 01: 38.2458291
Буферизовано 00: 01: 39.0499939
Строки записи 00: 08: 35.5900614

1 голос
/ 22 декабря 2011

Я не знаю, является ли это лучшим способом, но один из более простых вариантов был бы таким:

File.WriteAllLines(fileName, S1.Union(S2).Union(S3));
0 голосов
/ 22 декабря 2011

Чтобы собрать все строки:

var allStrings = new List<string>();
allStrings.AddRange(S1);
allStrings.AddRange(S2);
allStrings.AddRange(S3);

Где S1, S2 и S3 - строковые массивы, на которые вы ссылаетесь.

Для записи в стандартный текстовый файл со всеми строками, соединенными пробелами (в качестве примера):

string text = string.Join(" ", allStrings.ToArray());
System.IO.File.WriteAllText(@"C:\Path\To\Some\File.txt", text);
0 голосов
/ 22 декабря 2011
using System.IO;

var combinedList = a1.ToList().AddRange(a2);
var combinedArray = list.ToArray();

using (var stream = new StreamWriter(filename))
{
    stream.Write(combinedArray, 0, combinedArray.Length);
}
0 голосов
/ 22 декабря 2011

Вы можете использовать метод System.IO.File.AppendAllLines для добавления всех строк в конкретный файл.

0 голосов
/ 22 декабря 2011

Использовать LINQ:

var s1 = new string[0]; var s2 = new string[0]; var s3 = new string[0];

using (var writer = new StreamWriter("c:\temp.text.txt")) 
{   
  writer.Write(s1.Union(s2).Union(s3).Aggregate(string.Empty, (current, var) => current + var)); 
}
0 голосов
/ 22 декабря 2011

Описание

Предполагая, что вы хотите записать все содержимое массива в TextFile, вы можете сделать это, используя

  • List<string> (пространство имен System.Collections.Generic)
  • FileStream (пространство имен System.IO)
  • StreamWriter (пространство имен System.IO)

Образец

string[] a1 = new string[] { "Text1", "Text2" };
string[] a2 = new string[] { "Another Text1", "Another Text2" };

List<string> list = new List<string>();
list.AddRange(a1);
list.AddRange(a2);

using (FileStream str = new FileInfo(@"C:\MyFilePath.txt").OpenWrite())
{
    StreamWriter writter = new StreamWriter(str);
    writter.Write(string.Join(Environment.NewLine, list));
    writter.Close();
}

Дополнительная информация

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...