Ответ 1
StreamWriter.Write
не
обрезает строку и не имеет ограничений.
Внутри он использует String.CopyTo
, который, с другой стороны, использует небезопасный код (используя fixed
) для копирования символов, поэтому он наиболее эффективный.
В С# я читаю умеренный размер файла (100 КБ ~ 1 МБ), изменяя некоторые части содержимого и, наконец, записывая в другой файл. Все содержимое - это текст. Модификация выполняется как строковые объекты и строковые операции. Мой текущий подход:
StreamReader
.StringBuilder
для содержимого нового файла.AppendLine
StringBuilder
(до конца файла)StreamWriter
и напишите StringBuilder
в поток записи.Однако я обнаружил, что StremWriter.Write
обрезает 32768 байт (2 ^ 16), но длина StringBuilder
больше. Я мог бы написать простой цикл, чтобы гарантировать полную строку в файле. Но, мне интересно, что было бы самым эффективным способом в С# для выполнения этой задачи?
Подводя итог, я хотел бы изменить только некоторые части текстового файла и записать в другой файл. Но размер текстового файла может быть больше 32768 байт.
== Ответ == Прошу прощения, чтобы сделать confusin! Просто я не называл flush
. StremWriter.Write
не имеет короткого (например, 2 ^ 16) ограничения.
StreamWriter.Write
обрезает строку и не имеет ограничений.
Внутри он использует String.CopyTo
, который, с другой стороны, использует небезопасный код (используя fixed
) для копирования символов, поэтому он наиболее эффективный.
Проблема скорее всего связана с не закрытием писателя. См. http://msdn.microsoft.com/en-us/library/system.io.streamwriter.flush.aspx.
Но я бы предложил не загружать весь файл в память, если этого можно избежать.
Вы можете попробовать следующее:
void Test()
{
using (var inputFile = File.OpenText(@"c:\in.txt"))
{
using (var outputFile = File.CreateText(@"c:\out.txt"))
{
string current;
while ((current = inputFile.ReadLine()) != null)
{
outputFile.WriteLine(Process(current));
}
}
}
}
string Process(string current)
{
return current.ToLower();
}
Он не должен иметь полный файл, загруженный в память, обрабатывая строку за строкой и записывая ее напрямую
Вместо того, чтобы запускать хотя бы отверстие dokument, я бы использовал регулярное выражение, чтобы найти то, что вы ищете. Пример:
public List<string> GetAllProfiles()
{
List<string> profileNames = new List<string>();
using (StreamReader reader = new StreamReader(_folderLocation + "profiles.pg"))
{
string profiles = reader.ReadToEnd();
var regex = new Regex("\nname=([^\r]{0,})", RegexOptions.IgnoreCase);
var regexMatchs = regex.Matches(profiles);
profileNames.AddRange(from Match regexMatch in regexMatchs select regexMatch.Groups[1].Value);
}
return profileNames;
}
Я нашел этот ответ весьма полезным в подобной ситуации. Нет никакого исходного кода, это больше похоже на подсказки. Я надеюсь, что это поможет.
Ну, это полностью зависит от того, что вы хотите изменить. Если ваши изменения одной части текстового файла зависят от другой части текстового файла, вам, очевидно, необходимо иметь обе эти части в памяти. Однако, однако, вам нужно всего лишь изменить текстовый файл поэтапно, а затем использовать что-то вроде этого:
using (StreamReader sr = new StreamReader(@"test.txt"))
{
using (StreamWriter sw = new StreamWriter(@"modifiedtest.txt"))
{
while (!sr.EndOfStream)
{
string line = sr.ReadLine();
//do some modifications
sw.WriteLine(line);
sw.Flush(); //force line to be written to disk
}
}
}
Вы пробовали File.WriteAllText()
метод?