Редактирование текстового файла через С#
У меня есть огромный текстовый файл, размеp > 4 ГБ, и я хочу заменить какой-то текст в нем программным путем. Я знаю номер строки, в которой я должен заменить текст, но проблема в том, что я не хочу копировать весь текст (вместе с моей заменой строки) во второй файл. Я должен сделать это в исходном файле. Есть ли способ сделать это в С#?
Текст, который нужно заменить, точно такого же размера, как исходный текст (если это помогает).
Ответы
Ответ 1
Поскольку файл настолько велик, вы можете захотеть взглянуть на поддержку .NET 4.0 для файлов с отображением памяти. В основном вам нужно будет переместить указатель файла/потока на место в файле, перезаписать это местоположение, а затем вывести файл на диск. Вам не нужно будет загружать весь файл в память.
Например, без использования файлов с отображением памяти следующее будет перезаписывать часть файла ascii. Args - это входной файл, нулевой начальный индекс и новый текст.
static void Main(string[] args)
{
string inputFilename = args[0];
int startIndex = int.Parse(args[1]);
string newText = args[2];
using (FileStream fs = new FileStream(inputFilename, FileMode.Open, FileAccess.Write))
{
fs.Position = startIndex;
byte[] newTextBytes = Encoding.ASCII.GetBytes(newText);
fs.Write(newTextBytes, 0, newTextBytes.Length);
}
}
Ответ 2
Если новый текст точно такого же размера, как старый текст, вам придется перезаписать файл. Об этом нет. Вы можете хотя бы сделать это, не сохраняя весь файл в памяти.
Ответ 3
Здравствуйте, я проверил следующие функции: хорошо работает. Он обслуживает строки переменной длины, разделенные средой Environment.NewLine. если у вас есть фиксированные длины линий, вы можете прямо искать его. Для преобразования байтов в строку и наоборот вы можете использовать кодировку.
static byte[] ReadNextLine(FileStream fs)
{
byte[] nl = new byte[] {(byte) Environment.NewLine[0],(byte) Environment.NewLine[1] };
List<byte> ll = new List<byte>();
bool lineFound = false;
while (!lineFound)
{
byte b = (byte)fs.ReadByte();
if ((int)b == -1) break;
ll.Add(b);
if (b == nl[0]){
b = (byte)fs.ReadByte();
ll.Add(b);
if (b == nl[1]) lineFound = true;
}
}
return ll.Count ==0?null: ll.ToArray();
}
static void Main(string[] args)
{
using (FileStream fs = new FileStream(@"c:\70-528\junk.txt", FileMode.Open, FileAccess.ReadWrite))
{
int replaceLine=1231;
byte[] b = null;
int lineCount=1;
while (lineCount<replaceLine && (b=ReadNextLine(fs))!=null ) lineCount++;//Skip Lines
long seekPos = fs.Position;
b = ReadNextLine(fs);
fs.Seek(seekPos, 0);
string line=new string(b.Select(x=>(char)x).ToArray());
line = line.Replace("Text1", "Text2");
b=line.ToCharArray().Select(x=>(byte)x).ToArray();
fs.Write(b, 0, b.Length);
}
}
Ответ 4
Я предполагаю, что вы захотите использовать класс FileStream и искать свой позитив и размещать обновленные данные.