从文本文件中读取一行,然后用新文本替换同一行 C#
Reading a line from a text file and then replacing the same line with new text C#
我正在尝试弄清楚如何在按 ID 搜索文本文件中的一行之后替换它,然后写入新信息来替换它。它用于客户管理系统,其中此特定方法是通过 ID 搜索客户,返回搜索到的信息,然后修改相同的信息以将其写回。保存信息的 CSV 设置如下:
[身份证][职务][名字][姓氏][性别][出生日期]
[0][夫人][简][母鹿][女][1/1/1990]
[1][先生][约翰][母鹿][男][1/1/1991]
[2][女士][莎拉][母鹿][女][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,5}{1,10}{2,15}{3,15}{4,15}{5,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,5}{1,10}{2,15}{3,15}{4,15}{5,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])
};
}
}
}
}
}
任何帮助将不胜感激
首先,您确实不应该在接受用户输入的同时写入文件。你应该读取你的数据,更新你的数据,然后保存你的数据。不要混淆它们。
接下来,不要分享流。
我会这样做:
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,5}{1,10}{2,15}{3,15}{4,15}{5,25}\n", headers);
foreach (var customer in customers.Where(x => x.ID == ID))
{
Console.WriteLine("{0,5}{1,10}{2,15}{3,15}{4,15}{5,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);
}
}
我正在尝试弄清楚如何在按 ID 搜索文本文件中的一行之后替换它,然后写入新信息来替换它。它用于客户管理系统,其中此特定方法是通过 ID 搜索客户,返回搜索到的信息,然后修改相同的信息以将其写回。保存信息的 CSV 设置如下:
[身份证][职务][名字][姓氏][性别][出生日期]
[0][夫人][简][母鹿][女][1/1/1990]
[1][先生][约翰][母鹿][男][1/1/1991]
[2][女士][莎拉][母鹿][女][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,5}{1,10}{2,15}{3,15}{4,15}{5,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,5}{1,10}{2,15}{3,15}{4,15}{5,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])
};
}
}
}
}
}
任何帮助将不胜感激
首先,您确实不应该在接受用户输入的同时写入文件。你应该读取你的数据,更新你的数据,然后保存你的数据。不要混淆它们。
接下来,不要分享流。
我会这样做:
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,5}{1,10}{2,15}{3,15}{4,15}{5,25}\n", headers);
foreach (var customer in customers.Where(x => x.ID == ID))
{
Console.WriteLine("{0,5}{1,10}{2,15}{3,15}{4,15}{5,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);
}
}