从文本文件中读取一行,然后用新文本 C# 替换同一行
Posted
技术标签:
【中文标题】从文本文件中读取一行,然后用新文本 C# 替换同一行【英文标题】:Reading a line from a text file and then replacing the same line with new text C# 【发布时间】:2020-08-11 17:58:21 【问题描述】:我试图弄清楚如何在通过 ID 搜索文本文件后替换它,然后编写新信息来替换它。它适用于客户管理系统,此特定方法是通过 ID 搜索客户,返回搜索到的信息,然后修改相同的信息以将其写回。保存信息的 CSV 设置如下:
[ID][Title][firstName][lastName][Gender][DOB]
[0][Mrs][Jane][Doe][Female][1/1/1990]
[1][先生][John][Doe][Male][1/1/1991]
[2][Ms][Sarah][Doe][Female][1/1/2010]
我有一种感觉 StreamWriter
使用不正确,因为我可以把所有东西都放进去,当我把断点放进去调试时,作者在底部把它全部捡起来,但是一旦我按下回车,什么都没有发生数据就消失了。或者我可能没有在正确的位置收集用户输入。我已经对代码进行了格式化,以便于获取和调试:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication1
class Program
public class Customer
public int ID get; set;
public string Title get; set;
public string FirstName get; set;
public string LastName get; set;
public string Gender get; set;
public DateTime DOB get; set;
static void Main(string[] args)
const char DELIM = ',';
const int END = 0;
const string FILENAME = "D:\\customers.csv";
FileStream inFile = new FileStream(FILENAME, FileMode.Open, FileAccess.ReadWrite);
StreamWriter writer = new StreamWriter(inFile);
while (true)
Console.WriteLine(" **Type " + END + " To Quit** Enter Customer ID Number> ");
var ID = Convert.ToInt32(Console.ReadLine());
if (ID == END) break;
inFile.Position = 0;
Console.WriteLine("0,51,102,153,154,155,25\n", "ID", "Title", "First Name", "Last Name", "Gender", "DOB");
foreach (var customer in GetCustomers(inFile, DELIM).Where(x => x.ID == ID))
Console.WriteLine("0,51,102,153,154,155,25\n", customer.ID, customer.Title, customer.FirstName, customer.LastName, customer.Gender, customer.DOB);
Write(" Title> ");
customer.Title = ReadLine();
Write(" First Name> ");
customer.FirstName = ReadLine();
Write(" Last Name> ");
customer.LastName = ReadLine();
Write(" Gender> ");
customer.Gender = ReadLine();
Write(" Date Of Birth> ");
customer.DOB = Convert.ToDateTime(ReadLine());
writer.WriteLine(customer.ID + DELIM + customer.Title + DELIM + customer.FirstName + DELIM + customer.LastName + DELIM + customer.Gender + DELIM + customer.DOB);
writer.Close();
inFile.Close();
static IEnumerable<Customer> GetCustomers(Stream input, char separator)
using (var reader = new StreamReader(input))
// read header
reader.ReadLine();
while (true)
var line = reader.ReadLine();
if (line == null) yield break;
var fields = line.Split(separator);
yield return new Customer
ID = Convert.ToInt32(fields[0]),
Title = fields[1],
FirstName = fields[2],
LastName = fields[3],
Gender = fields[4],
DOB = Convert.ToDateTime(fields[5])
;
任何帮助将不胜感激
【问题讨论】:
写入非结构化文件不是一个好主意,而其内容仍在被读取。您正在使用读取器和写入器访问同一流。流的当前位置(用于读/写)将受到写入器和读取器的影响。结果出乎意料。 【参考方案1】:首先,您确实不应该在接受用户输入的同时写入文件。您应该读取数据、更新数据,然后保存数据。不要混淆它们。
接下来,不要共享流。
我会这样做:
static IEnumerable<Customer> GetCustomers(string file, char separator)
return
from line in File.ReadLines(file).Skip(1)
let fields = line.Split(separator)
select new Customer()
ID = Convert.ToInt32(fields[0]),
Title = fields[1],
FirstName = fields[2],
LastName = fields[3],
Gender = fields[4],
DOB = Convert.ToDateTime(fields[5])
;
static void SaveCustomers(string file, char separator, string[] headers, IEnumerable<Customer> customers)
IEnumerable<string[]> parts =
from c in customers
select new []
c.ID.ToString(),
c.Title,
c.FirstName,
c.LastName,
c.Gender,
c.DOB.ToShortDateString()
;
IEnumerable<string> lines =
from ps in new [] headers .Concat(parts)
select String.Join(separator.ToString(), ps);
File.WriteAllLines(file, lines);
static void Main(string[] args)
const char DELIM = ',';
const int END = 0;
const string FILENAME = "D:\\customer.csv";
string[] headers = new [] "ID", "Title", "First Name", "Last Name", "Gender", "DOB" ;
List<Customer> customers = GetCustomers(FILENAME, DELIM).ToList(); //Must call `.ToList()` to force reading the file.
var ID = -1;
while (ID != 0)
Console.WriteLine(" **Type " + END + " To Quit** Enter Customer ID Number> ");
ID = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("0,51,102,153,154,155,25\n", headers);
foreach (var customer in customers.Where(x => x.ID == ID))
Console.WriteLine("0,51,102,153,154,155,25\n", customer.ID, customer.Title, customer.FirstName, customer.LastName, customer.Gender, customer.DOB);
Console.Write(" Title> ");
customer.Title = Console.ReadLine();
Console.Write(" First Name> ");
customer.FirstName = Console.ReadLine();
Console.Write(" Last Name> ");
customer.LastName = Console.ReadLine();
Console.Write(" Gender> ");
customer.Gender = Console.ReadLine();
Console.Write(" Date Of Birth> ");
customer.DOB = Convert.ToDateTime(Console.ReadLine());
// Always save to a temporary file & then swap.
var saveFileName = FILENAME.Replace(".csv", ".csv-temp");
if (File.Exists(saveFileName))
File.Delete(saveFileName);
SaveCustomers(saveFileName, DELIM, headers, customers);
if (File.Exists(saveFileName) && File.Exists(FILENAME))
File.Delete(FILENAME);
File.Move(saveFileName, FILENAME);
【讨论】:
以上是关于从文本文件中读取一行,然后用新文本 C# 替换同一行的主要内容,如果未能解决你的问题,请参考以下文章