чтение и редактирование содержимого файла - PullRequest
0 голосов
/ 23 декабря 2011

У меня есть файл в следующем формате:

AA
AA AA AA
AA AA AA AA AA AA
AA AA AA
file.txt
0

Где AA представляет одно или двухзначное число (длина каждого не должна быть 2), а file.txt - это имя файла. Мне нужен очень быстрый способ получить имя файла. Кроме того, мне нужно заменить последние 0 на 1. Если в конце файла нет 0 (это необязательно), мне нужно добавить 1 в новой строке. Вот мой текущий код:

StringBuilder sb = new StringBuilder("\r\n1");
string txt = File.ReadAllText(args[0]);
string[] lines = txt.Split('\n');
string name = lines[4];

if (lines.Length != 6) // Check if EOF is 0 or not.
    txt += sb.ToString();
else
    txt = txt.Substring(0, txt.Length - 1) + '1'; // Replace 0 with 1.

File.WriteAllText(args[0], txt);
Console.WriteLine(name);

Однако мне было интересно, есть ли еще более быстрый способ сделать это (возможно, без необходимости загружать файл в память). Я должен обработать тонны таких файлов, поэтому сохранение десятых было бы чрезвычайно полезно.

Ответы [ 3 ]

1 голос
/ 23 декабря 2011
var lines = new List<string>(File.ReadAllLines(args[0]));
string name = lines[4];

if (lines.Length != 6) // Check if EOF is 0 or not.
    lines.Add("1");
else
    lines[5] = "1";

File.WriteAllLines(args[0], lines);
Console.WriteLine(name);
1 голос
/ 23 декабря 2011

Если вы ищете скорость, то вы хотите использовать FileStream.Read для временного буфера. Вот кое-что, что я собрал вместе, что может помочь вам указать немного другое, но более быстрое направление:

StringBuilder filename = new StringBuilder();
using (FileStream stream = new FileStream(args[0], FileMode.Open, FileAccess.Read))
{
    byte[] buffer = new byte[1];
    while (stream.Read(buffer, 0, 1) > 0)
    {
        char c = (char) buffer[0];
        if (char.IsLetter(c) || char.IsPunctuation(c))
            filename.Append(c);
    }
}
1 голос
/ 23 декабря 2011

Загрузка всего файла в память, скорее всего, будет вашим самым быстрым выбором, если размер файла меньше мин (MemoryPageSize, FSBlockSize), обычно 4K

Предполагая, что у вас есть содержимое файла в строке, метинкс использует что-то вроде

int n;
if (content.EndsWith("\r\n0")
{
  n=content.Length-3;
  content=content.Substring(0,n+2)+"1";
}
else
{
  n=content.Length;
  content=content+"\r\n1";
}

и запишите строку в файл. Это избавит вас от довольно дорогого Split ()

для имени файла мы продолжаем следующим образом:

int p=content.LastIndexOf('\n',n);
String filename=content.Substring(p+1,n-p);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...