Чтение строки из текстового файла, а затем замена той же строки новым текстом C# - PullRequest
0 голосов
/ 28 апреля 2020

Я пытаюсь выяснить, как заменить строку в текстовом файле после поиска по идентификатору, а затем записать новую информацию для ее замены. Это для системы управления клиентами, где этот конкретный метод c ищет клиента по идентификатору, возвращает искомую информацию и затем изменяет ту же информацию, чтобы записать ее обратно. CSV, содержащий информацию, настроен следующим образом:

[ID] [Заголовок] [Имя] [Фамилия] [Пол] [DOB]

[0] [Миссис] [Джейн] [Доу] [Женщина] [01.01.1990]

[1] [Мистер] [Джон] [Доу] [Мужчина] [ 01.01.1991]

[2] [Ms] [Сара] [Доу] [Женский] [01.01.2010]

I есть ощущение, что 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])
                    };
                }
            }
        }
    }
}

Любая помощь будет очень признательна

1 Ответ

0 голосов
/ 28 апреля 2020

Во-первых, вам действительно не следует записывать в файл в то же время, когда вы принимаете пользовательский ввод. Вы должны прочитать свои данные, обновить их, а затем сохранить свои данные. Не путайте их.

Далее, не делитесь потоками.

Вот как я бы это сделал:

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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...