Zapis i odczyt obiektu z List<T> do i z pliku

0

Witam,
mam problemy z zapisem/odczytem z pliku. Moja aplikacja ma przechowywać dane o książkach - zrobiłem to na list<t> przechowującej obiekty - i od dłuższego czasu męczę się jak zapisać - to jeszcze w niektórych odmianach mojego kodu działało - ale odczyt i wrzucenie tych danych do obiektu i listy - masakra. Męczę się już tak kilka tygodni - przeszukałem net i wszystkie rozwiązania zwykle działały w jedną stronę - tj. zapisu. Będę wdzięczny za wszelką pomoc / krytykę/ uwagi :)

istotny fragment kodu:

using System;
using System.Xml;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
 
namespace BibliotekaOsobista
/*program gromadzacy dane o podrecznej biblioteczce, korzystający z listy struktur, potrafi zapisywać i odczytywać bazę z pliku,
 jak również wyszukiwać, sortować, edytować oraz usuwać rekordy. Przeglądanie bazy odbywa się po jednym rekordzie*/
 

{
    public class Ksiazka // klasa opisujaca książkę - zawierająca gromadzone informacje
    {
        public string Tytul;//tytul
        string Autor;//nazwisko i imie lub pseudonim autora
        string Wydawnictwo;//wydawnictwo
        string Miasto;//miasto wydania
        int Rok;//rWydawnictwook wydania
        int NumerKatalogowy; // nr katalogowy
 
        public Ksiazka (string tytul, string autor, string wydawnictwo, string miasto, int rok, int numerkatalogowy)
        {
            this.Tytul = tytul;
            this.Autor = autor;
            this.Wydawnictwo = wydawnictwo;
            this.Miasto = miasto;
            this.Rok = rok;
            this.NumerKatalogowy = numerkatalogowy;
        }
 
        public string GetTytul() //zwraca nazwę książki
        {
            return Tytul;
        }
        public string GetAutor() //zwraca autora ksiązki
        {
            return Autor;
        }
        public string GetWydawnictwo() //zwraca wydawnictwo
        {
            return Wydawnictwo;
        }
 
        public string GetMiasto() //zwraca miasto wydania
        {
            return Miasto;
        }
 
        public int GetRok() //zwraca rok wydania
        {
            return Rok;
        }
 
        public int GetNumerKatalogowy() //zwraca numer katalogowy
        {
            return NumerKatalogowy;
        }
        
    };
    
   public class Biblioteczka
    {
       public static List<Ksiazka> Biblioteka = new List<Ksiazka>(); //lista struktur typu 'Ksiazka'
 
       public void Stworz() //funkcja wypelniajaca bazę ksiazkami
       {
           Console.WriteLine("Podaj ile ksiazek masz do wpisania: "); //user decyduje ile ksiazek chce wprowadzic
           int tempx = int.Parse(Console.ReadLine());
           Console.Clear();
 
           for (int i = 0; i < tempx; i++)
           {
               //wczytujemy dane od usera
               Console.WriteLine("===================================================");
               Console.WriteLine("Podaj tytul ksiazki: ");
               string tytul = Console.ReadLine();
               Console.WriteLine("Podaj autora ksiazki: ");
               string autor = Console.ReadLine();
               Console.WriteLine("Podaj wydawnictwo: ");
               string wydawnictwo = Console.ReadLine();
               Console.WriteLine("Podaj miasto wydania: ");
               string miasto = Console.ReadLine();
               string string_rok;
               do //uniemożliwia wprowadzenie wartosci ujemnej i nie cyfry
                           //powtarza jesli bledny input
               {
                   Console.WriteLine("Podaj rok wydania: ");
                   string_rok = Console.ReadLine();
 
               }
               while (SprawdzInput(string_rok) == false);
               int rok = int.Parse(string_rok);
 
               string string_katalogowy;
               do //uniemożliwia wprowadzenie wartosci ujemnej i nie cyfry
                           //powtarza jesli bledny input
               {
                   Console.WriteLine("Podaj numer katalogowy: ");
                   string_katalogowy = Console.ReadLine();
 
               }
               while (SprawdzInput(string_katalogowy) == false);
               int numerktalogowy = int.Parse(string_katalogowy);
 
               Biblioteka.Add(new Ksiazka(tytul, autor, wydawnictwo, miasto, rok, numerktalogowy));
               Console.WriteLine("===================================================");
                        }
               Console.Clear();
               MainMenu();
           
           
       } 
	   
	   
	   public void ZapiszDoPliku() //zapisuje plik o podanej nazwie na dysk c:\ 
       {
           if (Biblioteka.Count > 0)
           {
 
               Console.WriteLine("Podaj nazwe pliku .txt ktory znajdzie się w folderze C:\\");
               string temp = Console.ReadLine();
               string filepath = @"C:\" + temp + ".txt";
               using (XmlWriter xml = XmlWriter.Create(filepath))
               //using (XmlTextWriter xml = new XmlTextWriter(filepath))
               {
                  
                   xml.WriteStartDocument();
                   xml.WriteStartElement(temp);
                   xml.WriteWhitespace("\n");
 
                   for (int i = 0; i < Biblioteka.Count; i++)
                   {
                       xml.WriteStartElement("Ksiazka");
                       {
                           xml.WriteElementString("Tytul", Biblioteka[i].GetTytul());
                           xml.WriteElementString("Autor", Biblioteka[i].GetAutor());
                           xml.WriteElementString("Wydawnictwo", Biblioteka[i].GetWydawnictwo());
                           xml.WriteElementString("Miasto", Biblioteka[i].GetMiasto());
                           xml.WriteElementString("Rok", Biblioteka[i].GetRok().ToString());
                           xml.WriteElementString("NumerKatalogowy", Biblioteka[i].GetNumerKatalogowy().ToString());
                       }
                       xml.WriteEndElement();
                       xml.WriteWhitespace("\n");
 
                   }
                   xml.WriteEndElement();
                   xml.WriteEndDocument();
 
 
               }
               Console.Clear();
               Console.WriteLine("Zapisano bazę do pliku " + temp + ".txt na dysku C");
           }
           else 
           {
               Console.Clear();
               Console.Beep();
               Console.WriteLine("ERROR: Najpierw załóż i zapełnij bazę lub odczytaj jakąś z pliku");
               Console.WriteLine();
               Console.WriteLine();
 
               MainMenu();
           }
           MainMenu();
       
 
          /* if (Biblioteka.Count > 0)
           {
               Console.WriteLine("Podaj nazwe pliku ktory zostanie zapisany w folderze C:\\");
               string temp = Console.ReadLine();
               //string filepath =     Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + temp + ".txt";
               
               string filepath = @"C:\" + temp + ".txt";
 
 
               using (StreamWriter writer = new StreamWriter(filepath))
               {
                   for (int i = 0; i < Biblioteka.Count; i++)
                   {
 
                       writer.WriteLine(Biblioteka[i].GetTytul());
                       writer.WriteLine(Biblioteka[i].GetAutor());
                       writer.WriteLine(Biblioteka[i].GetWydawnictwo());
                       writer.WriteLine(Biblioteka[i].GetMiasto());
                       writer.WriteLine(Biblioteka[i].GetRok());
                       writer.WriteLine(Biblioteka[i].GetNumerKatalogowy());
                       writer.WriteLine("END");
 
                   }
                   Console.Clear();
                   Console.WriteLine("Zapisano bazę do pliku " + temp + ".txt na dysku C");
 
               }
           }
           else
           {
               Console.Clear();
               Console.Beep();
               Console.WriteLine("ERROR: Najpierw załóż i zapełnij bazę lub odczytaj jakąś z pliku");
               Console.WriteLine(); 
               Console.WriteLine(); 
               
               MainMenu();
 
           }
           MainMenu();*/
       }
 
       public void OdczytZPliku() //odczytuje plik o podanej nazwie z dysku c:\ 
       {
               Wyczysc();
               Console.WriteLine("Podaj nazwe pliku .txt ktory znajduje się w folderze C:\\Users");
               string temp = Console.ReadLine();
               string filepath = @"C:\" + temp + ".txt";
 
               using (XmlTextReader reader = new XmlTextReader(filepath))
               {
                   while (reader.Read())
                   {
                       if (reader.IsStartElement())
                       {
                           string a, b, c, d;
                           a = b = c = d = "";
                           int e, f;
                           e = f = 0;
                           
                           switch (reader.Name)
                           {
                               
                               case "Tytul":
                                   a = reader.ReadString();
                                   break;
                               case "Autor":
                                   b = reader.ReadString();
                                   break;
                               case "Wydawnictwo":
                                   c = reader.ReadString();
                                   break;
                               case "Miasto":
                                   d = reader.ReadString();
                                   break;
                               case "Rok":
                                   e = Int32.Parse(reader.ReadString());
                                   break;
                               case "NumerKatalogowy":
                                   f = Int32.Parse(reader.ReadString());
                                   Biblioteka.Add(new Ksiazka(a, b, c, d, e, f));
                                   break;
                           }
                       }
                   }
               }
               /*Console.WriteLine("Podaj nazwe pliku .txt ktory znajduje się w folderze C:\\Users");
               string temp = Console.ReadLine();
               string filepath =   @"C:\" + temp + ".txt";
 
               //var lineCount = 0;
               using (var reader = File.OpenText(filepath))
               {
                   while (reader.ReadLine() != null)
                   {
                       lineCount++;
                   }
               }
 
               using (StreamReader reader = new StreamReader(filepath))
               {
 
                   for (int i = 0; i < File.ReadLines(filepath).Count(); i++)
                   {
 
                       if (i == 0 || i%6 == 0) reader.ReadLine();
 
                   }
                   Console.Clear();
                   Console.WriteLine("Wczytano baze z pliku " + temp + ".txt");
                   MainMenu();
 
 
               }*/
           
           
           }
		   
		    
    class Program
    {
        public static Biblioteczka Biezaca = new Biblioteczka();
        
        
        static void Main(string[] args)
        {
        Biezaca.Stworz();
        Biezaca.ZapiszDoPliku();
 
        Console.ReadKey();
        }
    }
0

Na moje oko, to to: Biblioteka.Add(new Ksiazka(a, b, c, d, e, f)); powinno być poza switch.
Kod generalnie trzeba poprawić, no i nie zapisywać plików bezpośrednio na "C:".

2

A nie będzie prościej tych danych zserializować ładniej i dożo mniej kodu zapis i odczyt można zastąpić jak poniżej tylko musisz zrobić property z każdego pola w klasie Ksiazka

       
 public void ZapiszDoPliku(){ //zapisuje plik o podanej nazwie na dysk c:\ 
            if (Biblioteka.Count > 0)
            {
                using (var writer = new StreamWriter(@"d:\plix.txt", true))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(List<Ksiazka>));
                    serializer.Serialize(writer, Biblioteka);
                }
            }
        }

public void OdczytZPliku(){ //odczytuje plik o podanej nazwie z dysku c:\ 
       using (var writer = new StreamReader(@"d:\plix.txt", true))
       {
                XmlSerializer ser = new XmlSerializer(typeof(List<Ksiazka>));
                var ksiazki = (List<Ksiazka>)ser.Deserialize(writer);

                Biblioteka.AddRange(ksiazki);
            }
 }
0

Jak na moje oko w pętli sobie reinicujesz zmienne, więc tak naprawdę. Gdy natrafisz na numerKatalogowy, to masz:
Biblioteka.Add(new Ksiazka("", "", "", "", "", jakisNumer));

0

dzięki za pomoc :) serialize/deserialize is aweeeeesome :P

0

hmmm... zmieniłem też miejsce przechowywania pliku - ale zastanawiam się czy jest jakiś sposób, żeby zapisywać np. w moje dokumenty niezależnie od rodzaju Windy - coś w rodzaju zmiennych środowiskowych?

2

string ścieżka = Environment.GetFolderPath(SpecialFolder.MyDocuments);

1 użytkowników online, w tym zalogowanych: 0, gości: 1