Suren97 Ответов: 2

Как добавить данные из списка в файл .txt с помощью switch-case


у меня есть классы Controller и Person,мне нужно добавить данные в свой список,все данные, которые добавляются в консоль, должны храниться в файле .txt.То есть, если пользователь вводит 1, чтобы увидеть данные, они должны быть прочитаны из файла,а затем отображены, когда пользователь вводит 2, чтобы добавить новые данные, они должны быть прочитаны из файла, а затем отображены.
я уже написал функцию Show (), она работает,но функция add() не работает,что у меня ложно?

Что я уже пробовал:

class Controller
    {
        public List<Person> all; 
        public void Show()
        {
            string path = "C:/Users/User/Desktop/mardik.txt";
            FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Read);
            BinaryFormatter bf = new BinaryFormatter();
            List<Person> all = bf.Deserialize(fs) as List<Person>;
            foreach (Person item in all)
            {
                Console.WriteLine(item.name + " " + item.age);
            }
        }
        public void Add()
        {
            string path = "C:/Users/User/Desktop/mardik.txt";
            FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Read);
            BinaryFormatter bf = new BinaryFormatter();
            List<Person> all = bf.Deserialize(fs) as List<Person>;
            
            Console.WriteLine("Enter new user's data");
            string text = Console.ReadLine();
            
            foreach(Person item in all)
            {
                Console.WriteLine(item.name + " " + item.age);
            }
        }


В чем моя ошибка в функции Add ()?

[Serializable]
    class Person
    {
        public string name;
        public int age;
        public Person(string a, int b)
        {
            this.name = a;
            this.age = b;
        }
    }





static void Main(string[] args)
        {
            string path = "C:/Users/User/Desktop/mardik.txt";
            List<Person> mardik = new List<Person>();
            //mardik.Add(new Person("Valod", 20));
            //mardik.Add(new Person("Petros", 23));
            //mardik.Add(new Person("Poghos", 25));
            //mardik.Add(new Person("Hranush", 22));
            //mardik.Add(new Person("Suren", 18));
            //FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write);
            //BinaryFormatter bf = new BinaryFormatter();
            //bf.Serialize(fs, mardik);
            //fs.Close();
            Controller c = new Controller();
            while (true)
            {
                Console.WriteLine();
                Console.WriteLine("What do you want to do:\n1.Show all People\n2.Add new person\n3.Delete any person");
                int x = int.Parse(Console.ReadLine());
                switch (x)
                {
                    case 1:
                        c.Show();
                        break;
                    case 2:
                        c.Add();
                        break;
                    
                }
            }
        }

Richard MacCutchan

Вы забыли включить код для перезаписи файла после ввода новых данных. Лучшей структурой для вашей программы была бы:

Start:
    Read the input file data into the List
    While user select options:
        if 1 then show List
    Else
        if 2 then add new entry
    Else
        if some_other_value the end while loop
If new entries added
    Write entries to new file
End:

Suren97

я не понимаю, вы можете показать мне это как код?

Richard MacCutchan

Я дал вам псевдокод, преобразование которого в C# не составляет труда.

Suren97

но мне кажется, что я так и сделал, или я просто не понимаю, что вы имеете в виду?

Richard MacCutchan

Извините, но это не так. Посмотрите на структуру вашего кода. Вы читаете входной файл в двух местах, поэтому вы создаете два отдельных списка объектов; это просто дублирование работы. И это также означает, что каждый раз, когда вы вызываете Show или Add, вы снова перечитываете файл, что еще более расточительно. Другие проблемы, перечисленные в сообщении OriginalGriff ниже.

Suren97

Пожалуйста, если вы можете показать мне, как я должен написать этот код? тогда я попробую написать функцию delete() сам :)

2 Ответов

Рейтинг:
2

OriginalGriff

Здесь есть пара вещей:
1) не жестко кодируйте пути, вместо этого используйте конфигурационный файл - и если вы не можете это сделать, то используйте значение const, так что вам нужно изменить его только в одном месте.
2) Если вы открываете файл или поток, вы несете ответственность за его закрытие и удаление: ни один из ваших кодов этого не делает, а это означает, что поток остается открытым до тех пор, пока приложение не закроется или сборщик мусора не начнет убирать за вами. Если файл открыт, вы не можете открыть его для записи!
3) Ваш метод add считывает данные от пользователя, но ничего с ними не делает: он отбрасывается в конце метода, поэтому нет особого смысла читать его в первую очередь!
4) Использование .Расширение TXT вводит в заблуждение, когда вы используете BinaryFormatter - оно подразумевает читаемый человеком и редактируемый контент, который BinaryFormatter не производит.
5) Никогда не доверяйте вводу пользователя: int.Parse возникнет исключение, если пользователь введет "привет" или "А" вместо цифры. Я бы посоветовал вам использовать int.TryParse вместо.

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


Suren97

Как я могу использовать конфигурационный файл?

OriginalGriff

https://msdn.microsoft.com/en-us/library/ms184658.aspx

Suren97

или значение const?

OriginalGriff

Ты ведь шутишь, правда?

const string myConstValue = "значение строки";

Suren97

для чего мне его использовать?

OriginalGriff

Вместо того чтобы каждый раз записывать путь к файлу, вы объявляете его как значение const и используете имя const каждый раз, когда вам нужен путь. Таким образом, если вы перемещаете файл, вам нужно только изменить одно место в приложении и перекомпилировать его, чтобы он был более надежным и менее подверженным ошибкам.
Это не так гибко, как конфигурационный файл - вам все равно придется перекомпилировать приложение каждый раз, когда вы перемещаете файл, - но это намного лучше, чем вводить путь каждый раз!

Suren97

это всегда давало мне исключение :(

OriginalGriff

Затем вам нужно выяснить, что такое исключение и почему вы его получаете ... помните, что мы не можем видеть ваш экран, получить доступ к вашему жесткому диску или прочитать ваши мысли - мы получаем только то, что вы печатаете для работы.

Suren97

Большое вам спасибо, я мог бы это сделать, но есть одна проблема, когда я пишу новые данные, это добавление моего списка, но потом, когда я ввожу 1, чтобы увидеть моих всех людей + моего добавляющего человека, его там нет

OriginalGriff

Это потому, что вы ничего не делаете с данными!
Для этого вам нужно добавить его в файл - и это означает, что вы разберетесь с другими вещами, которые я упомянул, или файл не сможет открыться для записи.

Suren97

Как я могу добавить? Файл.AppendAllLines(?)

OriginalGriff

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

Suren97

что же мне делать?

OriginalGriff

Прочтите, что я сказал в своем первоначальном ответе.

Suren97

я не понимаю,где я должен вносить изменения?

OriginalGriff

Какую часть того, что я первоначально написал, Вы не понимаете? Если вы скажете нам, мы сможем помочь. Но просто сказать: "я не знаю, что мне делать?" - никому не поможет!

Suren97

Посмотрите мое решение ниже.

Suren97

а вы видели?

OriginalGriff

Вы разместили его как решение, так что я предполагаю, что вы закончили.

Suren97

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

OriginalGriff

Это очень плохой код.
Почему вы рекурсивно вызываете себя, когда получаете ошибку? Вы же понимаете, что это вернется в конце...

Suren97

Как я могу сохранить свои добавленные данные ?

Рейтинг:
0

Suren97

public void Add()
        {
            const string path = "C:/Users/User/Desktop/mardik.txt";
            FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite);
            BinaryFormatter bf = new BinaryFormatter();
            List<Person> all = bf.Deserialize(fs) as List<Person>;
            fs.Close();
            Console.WriteLine("Enter new user's data with comma");
            string text = Console.ReadLine();
            string[] segments = text.Split(',');
            string a = segments[0];
            int b;
            bool hajoxvec = int.TryParse(segments[1], out b);
            if (!hajoxvec)
            {
                Console.WriteLine("Please try again");
                this.Add();
            }
            else
            {
                all.Add(new Person(a, b));

            }
                foreach (Person item in all)
                {
                    Console.WriteLine(item.name + " " + item.age);
                }
            fs.Close();
        }


это работает, теперь мне нужно только сохранить мои добавленные данные.


Richard MacCutchan

И все равно это неправильно.

Suren97

в чем моя ошибка?

Richard MacCutchan

Ты все еще делаешь то, что я сказал тебе не делать. Вернитесь и прочтите мое предложение, а также оригинальное предложение Гриффа.

Suren97

Не могли бы вы прислать мне какой-нибудь источник, где я мог бы найти ответ на свой вопрос?

Richard MacCutchan

Я дал вам ответ; вы просто не будете пытаться использовать его.

Suren97

я так старалась :)