C# 在txt文件中添加一行
我有一个包含以下数据的txt文件:C# 在txt文件中添加一行,c#,C#,我有一个包含以下数据的txt文件: :10FF800000040B4E00040B4E00047D1400047D148D :10FF900000040B4E0004CF6200040B4E00040B4E15 :10FFA00000040B4E00040B4E00040B4E00040B4EDD :10FFB00000047D1400047D1400047D1400047D14ED :10FFC00000040B4E000000000000000000000000D4 :10FFD000000
:10FF800000040B4E00040B4E00047D1400047D148D
:10FF900000040B4E0004CF6200040B4E00040B4E15
:10FFA00000040B4E00040B4E00040B4E00040B4EDD
:10FFB00000047D1400047D1400047D1400047D14ED
:10FFC00000040B4E000000000000000000000000D4
:10FFD0000000000000040B4E0000000000000000C4
:10FFE0000000000000000000000000000000000011
:10FFF0000000000000000000060000000000BFF844
:020000020000FC
:020000040014E6
:043FF0005AC8A58C7A
:00000001FF
我想用我的C#程序在特定行之后或之前添加一行,比如添加行:
:020000098723060
在这一行之前:
:020000020000FC
我尝试过使用File.ReadLines(“File.txt”).Last();但这只给了我最后一个,如果我想要第三个或第四个呢?此外,是否有任何方法可以识别文件中的“:”如果您愿意将整个文件读入内存,最简单的方法就是:
public void InsertLineBefore(string file, string lineToFind, string lineToInsert)
{
List<string> lines = File.ReadLines(file).ToList();
int index = lines.IndexOf(lineToFind);
// TODO: Validation (if index is -1, we couldn't find it)
lines.Insert(index, lineToInsert);
File.WriteAllLines(file, lines);
}
public void InsertLineAfter(string file, string lineToFind, string lineToInsert)
{
List<string> lines = File.ReadLines(file).ToList();
int index = lines.IndexOf(lineToFind);
// TODO: Validation (if index is -1, we couldn't find it)
lines.Insert(index + 1, lineToInsert);
File.WriteAllLines(file, lines);
}
public void InsertLineBefore(字符串文件、字符串lineToFind、字符串lineToInsert)
{
列表行=File.ReadLines(File.ToList();
int index=lines.IndexOf(lineToFind);
//TODO:验证(如果索引为-1,则无法找到它)
行。插入(索引,lineToInsert);
File.writeAllines(文件,行);
}
public void InsertLineAfter(字符串文件、字符串lineToFind、字符串lineToInsert)
{
列表行=File.ReadLines(File.ToList();
int index=lines.IndexOf(lineToFind);
//TODO:验证(如果索引为-1,则无法找到它)
行。插入(索引+1,lineToInsert);
File.writeAllines(文件,行);
}
有很多更有效的方法可以做到这一点,但这种方法非常简单。如果您愿意将整个文件读入内存,最简单的方法就是:
public void InsertLineBefore(string file, string lineToFind, string lineToInsert)
{
List<string> lines = File.ReadLines(file).ToList();
int index = lines.IndexOf(lineToFind);
// TODO: Validation (if index is -1, we couldn't find it)
lines.Insert(index, lineToInsert);
File.WriteAllLines(file, lines);
}
public void InsertLineAfter(string file, string lineToFind, string lineToInsert)
{
List<string> lines = File.ReadLines(file).ToList();
int index = lines.IndexOf(lineToFind);
// TODO: Validation (if index is -1, we couldn't find it)
lines.Insert(index + 1, lineToInsert);
File.WriteAllLines(file, lines);
}
public void InsertLineBefore(字符串文件、字符串lineToFind、字符串lineToInsert)
{
列表行=File.ReadLines(File.ToList();
int index=lines.IndexOf(lineToFind);
//TODO:验证(如果索引为-1,则无法找到它)
行。插入(索引,lineToInsert);
File.writeAllines(文件,行);
}
public void InsertLineAfter(字符串文件、字符串lineToFind、字符串lineToInsert)
{
列表行=File.ReadLines(File.ToList();
int index=lines.IndexOf(lineToFind);
//TODO:验证(如果索引为-1,则无法找到它)
行。插入(索引+1,lineToInsert);
File.writeAllines(文件,行);
}
有很多更有效的方法可以做到这一点,但这种方法非常简单。蛮力方法
string[] lines = File.ReadAllLines("file.txt");
using(StreamWrite sw = new StreamWriter("file.txt"))
{
foreach(string line in lines)
{
if(line == ":020000020000FC")
sw.WriteLine(":020000098723060");
sw.WriteLine(line);
}
}
暴力手段
string[] lines = File.ReadAllLines("file.txt");
using(StreamWrite sw = new StreamWriter("file.txt"))
{
foreach(string line in lines)
{
if(line == ":020000020000FC")
sw.WriteLine(":020000098723060");
sw.WriteLine(line);
}
}
我认为最好是逐行读写,尤其是当目标文件的大小较大时:
using (StreamReader r = new StreamReader("Test.txt"))
{
using (StreamWriter w = new StreamWriter("TestOut.txt"))
{
while (!r.EndOfStream)
{
string line = r.ReadLine();
w.WriteLine(line);
if (line == ":020000020000FC")
w.WriteLine(":020000098723060");
}
w.Close();
r.Close();
}
}
我认为最好是逐行读写,尤其是当目标文件的大小较大时:
using (StreamReader r = new StreamReader("Test.txt"))
{
using (StreamWriter w = new StreamWriter("TestOut.txt"))
{
while (!r.EndOfStream)
{
string line = r.ReadLine();
w.WriteLine(line);
if (line == ":020000020000FC")
w.WriteLine(":020000098723060");
}
w.Close();
r.Close();
}
}
不确定您是否由于大小等原因试图避免读取整个文件,但您不能读取文件然后替换…例如
var text = readFile(somePath);
writeFile( text.replace(":020000020000FC\n",":020000098723060\n:020000020000FC\n") , somePath);
不确定您是否由于大小等原因试图避免读取整个文件,但您不能读取文件然后替换…例如
var text = readFile(somePath);
writeFile( text.replace(":020000020000FC\n",":020000098723060\n:020000020000FC\n") , somePath);
这里有一个解决方案,虽然它可能不是最好的,但它确实有效:
public void AddTextToFile(string filePath, int lineNumber, string txt) //zero based lineNumber
{
Collection<string> newLines = new Collection<string>(File.ReadAllLines(filePath).ToList());
if (lineNumber < newLines.Count)
newLines.Insert(lineNumber, txt);
else
newLines.Add(txt);
using (StreamWriter writer = new StreamWriter(filePath, false))
{
foreach (string s in newLines)
writer.WriteLine(s);
}
}
这里有一个解决方案,虽然它可能不是最好的,但它确实有效:
public void AddTextToFile(string filePath, int lineNumber, string txt) //zero based lineNumber
{
Collection<string> newLines = new Collection<string>(File.ReadAllLines(filePath).ToList());
if (lineNumber < newLines.Count)
newLines.Insert(lineNumber, txt);
else
newLines.Add(txt);
using (StreamWriter writer = new StreamWriter(filePath, false))
{
foreach (string s in newLines)
writer.WriteLine(s);
}
}
“:”字符实际上对实现没有帮助,所有行都已用换行符分隔
这里尝试一种方法,它不会将所有内容加载到内存或输出到其他文件
千万不要穿越溪流。
static Int32 GetCharPos(StreamReader s)
{
var ia = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField;
Int32 charpos = (Int32)s.GetType().InvokeMember("charPos", ia, null, s, null);
Int32 charlen = (Int32)s.GetType().InvokeMember("charLen", ia, null, s, null);
return (Int32)s.BaseStream.Position - charlen + charpos;
}
static void Appsert(string data, string precedingEntry = null)
{
if (precedingEntry == null)
{
using (var filestream = new FileStream(dataPath, FileMode.Append))
using (var tw = new StreamWriter(filestream))
{
tw.WriteLine(data);
return;
}
}
int seekPos = -1;
using (var readstream = new FileStream(dataPath,
FileMode.Open, FileAccess.Read, FileShare.Write))
using (var writestream = new FileStream(dataPath,
FileMode.Open, FileAccess.Write, FileShare.Read))
using (var tr = new StreamReader(readstream))
{
while (seekPos == -1)
{
var line = tr.ReadLine();
if (line == precedingEntry)
seekPos = GetCharPos(tr);
else if (tr.EndOfStream)
seekPos = (int)readstream.Length;
}
writestream.Seek(seekPos, SeekOrigin.Begin);
readstream.Seek(seekPos, SeekOrigin.Begin);
int readLength = 0;
var readBuffer = new byte[4096];
var writeBuffer = new byte[4096];
var writeData = tr.CurrentEncoding.GetBytes(data + Environment.NewLine);
int writeLength = writeData.Length;
writeData.CopyTo(writeBuffer, 0);
while (true & writeLength > 0)
{
readLength = readstream.Read(readBuffer, 0, readBuffer.Length);
writestream.Write(writeBuffer, 0, writeLength);
var tmp = writeBuffer;
writeBuffer = readBuffer;
writeLength = readLength;
readBuffer = tmp;
}
}
}
“:”字符实际上对实现没有帮助,所有行都已用换行符分隔
这里尝试一种方法,它不会将所有内容加载到内存或输出到其他文件
千万不要穿越溪流。
static Int32 GetCharPos(StreamReader s)
{
var ia = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField;
Int32 charpos = (Int32)s.GetType().InvokeMember("charPos", ia, null, s, null);
Int32 charlen = (Int32)s.GetType().InvokeMember("charLen", ia, null, s, null);
return (Int32)s.BaseStream.Position - charlen + charpos;
}
static void Appsert(string data, string precedingEntry = null)
{
if (precedingEntry == null)
{
using (var filestream = new FileStream(dataPath, FileMode.Append))
using (var tw = new StreamWriter(filestream))
{
tw.WriteLine(data);
return;
}
}
int seekPos = -1;
using (var readstream = new FileStream(dataPath,
FileMode.Open, FileAccess.Read, FileShare.Write))
using (var writestream = new FileStream(dataPath,
FileMode.Open, FileAccess.Write, FileShare.Read))
using (var tr = new StreamReader(readstream))
{
while (seekPos == -1)
{
var line = tr.ReadLine();
if (line == precedingEntry)
seekPos = GetCharPos(tr);
else if (tr.EndOfStream)
seekPos = (int)readstream.Length;
}
writestream.Seek(seekPos, SeekOrigin.Begin);
readstream.Seek(seekPos, SeekOrigin.Begin);
int readLength = 0;
var readBuffer = new byte[4096];
var writeBuffer = new byte[4096];
var writeData = tr.CurrentEncoding.GetBytes(data + Environment.NewLine);
int writeLength = writeData.Length;
writeData.CopyTo(writeBuffer, 0);
while (true & writeLength > 0)
{
readLength = readstream.Read(readBuffer, 0, readBuffer.Length);
writestream.Write(writeBuffer, 0, writeLength);
var tmp = writeBuffer;
writeBuffer = readBuffer;
writeLength = readLength;
readBuffer = tmp;
}
}
}
@布莱恩:“我试过使用……”@MStodd-我应该更具体一点。我指的是他在代码方面所做的尝试,就像在《发布你的代码》中一样。@Brian“我尝试过使用……”@MStodd-我应该更具体一些。我指的是他在代码方面所做的尝试,就像在发布你的代码一样。当然,看着你的代码,我觉得我的自尊受到了一些伤害,但是,像往常一样,观看并从中学习总是一种乐趣。我很好奇,还有什么更有效的方法可以做到这一点?除了使用迭代器查找行并只读取行,直到找到所需的行为止(与加载整个文件相反),我想不出任何其他方法。@G.Bach:正是这样-您可以在一次扫描中读取文件,在读取时写出行。对于“after”,这相当容易,因为当你阅读了你要找的那一行时,你只需添加额外的一行。对于“before”,它要稍微复杂一些,因为您需要保留一行的缓冲区,以防下一行就是您要查找的行。如果我想标识字符串的特定部分,就像它是数组一样,该怎么办?类似字符串x=lines.IndexOf(2)[2]?在我的例子中,假设我想得到第2行中的第四个字符有一个F。。字符串F=行。IndexOf(1)[3];当然,看着你的代码,我觉得我的自尊心受到了一些伤害,但是,像往常一样,观看并从中学习总是一种乐趣。我很好奇,还有什么更有效的方法呢?除了使用迭代器查找行并只读取行,直到找到所需的行为止(与加载整个文件相反),我想不出任何其他方法。@G.Bach:正是这样-您可以在一次扫描中读取文件,在读取时写出行。对于“after”,这相当容易,因为当你阅读了你要找的那一行时,你只需添加额外的一行。对于“before”,它要稍微复杂一些,因为您需要保留一行的缓冲区,以防下一行就是您要查找的行。如果我想标识字符串的特定部分,就像它是数组一样,该怎么办?类似字符串x=lines.IndexOf(2)[2]?在我的例子中,假设我想得到第2行中的第四个字符有一个F。。字符串F=行。IndexOf(1)[3];