简体   繁体   中英

Reading a line from a text file and then replacing the same line with new text C#

I'm trying to figure out how to replace a line in a text file after searching for it by ID and then writing new information to replace it. It's for a customer management system where this specific method is searching for the customer by ID, returning the searched information and then modifying that same information to write it back. The CSV holding the information is set up like this:

[ID][Title][firstName][lastName][Gender][DOB]

[0][Mrs][Jane][Doe][Female][1/1/1990]

[1][Mr][John][Doe][Male][1/1/1991]

[2][Ms][Sarah][Doe][Female][1/1/2010]

I have a feeling the StreamWriter is being used incorrectly as I can put everything in, the writer picks it all up at the bottom when I put a breakpoint in to debug, but as soon as I press enter nothing happens and the data just disappears. Or I might not be collecting user input in the right location. I've formatted the code so its easier to take and debug:

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])
                    };
                }
            }
        }
    }
}

Any help would be very appreciated

First-up, you really shouldn't write to a file at the same time that you're accepting user input. You should read your data, update your data, and then save your data. Don't mix them up.

Next, don't share streams.

Here's how I would do this:

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);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM