C# Filestream nieprawidłowa ścieżka

0

Dzień dobry,

Utworzyłem sobie do mojego projektu klasę statyczną zarządzającą plikami. Są w niej min. dwie takie oto funkcje:

	public static void zapisz(string nazwaPliku, List<string> dane){
            FileStream plik = new FileStream(nazwaPliku, FileMode.Create, FileAccess.Write);
            BinaryWriter br = new BinaryWriter(plik);

            for (int i = 0; i < dane.Count; i++) {
                br.Write(dane[i].Length);
                br.Write(dane[i]);
            }

            br.Close();
            plik.Close();
        }

        public static List<string> odczytaj(string nazwaPliku) {
            string sciezka = System.IO.Path.GetFullPath(nazwaPliku);
            FileStream plik = new FileStream(sciezka, FileMode.Open, FileAccess.Read);
            BinaryReader br = new BinaryReader(plik);
            List<string> wyn = new List<string>();

            int poz = 0;
            int dl = (int)br.BaseStream.Length;

            while (poz < dl-poz) {
                poz += br.ReadInt32();
                wyn.Add(br.ReadString());
            }

            br.Close();
            plik.Close();

            return wyn;
        }

Pierwsza zapisuje do pliku binarnego, a druga go odczytuje.
Problem leży przy próbie odczytania pliku.
Visual Studio 2013 wywala mi w programie wyjątek System.IO.FileNotFoundException i twierdzi, że nie może odnaleźć pliku w lokalizacji C:\Windows\System32.
To bardzo dziwna sprawa ponieważ jeżeli spróbujecie sprawdzić co jest w zmiennej 'sciezka' to okaże się, że przechowuje on prawidłową lokalizację.

Chodzi o np. takie wywołanie funkcji:

 
// Chodzi o ścieżkę względną;
List<string> dane = odczytaj(@"Config\plik.bin");

Mała prośba o pomoc... :)

0

Sprawdź gdzie ten plik trzymasz Ty, a gdzie program go szuka... ponieważ u mnie ten plik jest w folderze programu którym kompilowałem (C:\Program Files(x86)\LINQPad4\plik.bin"

0
List<string> dane = odczytaj(@"Config\plik.bin");

No dobrze, a jak wywołujesz zapisz() i czy podczas tego samego uruchomienia programu, czy osobno uruchamiasz program dla zapisu i osobno dla odczytu?
..i czy jest to ten sam program ;-)

0

Dodaję treść wyjątku w załączniku gdyż debugerem nie mam jak go wyłapać (wiem, to dziwne).

@Azarien
Tak, używam tych funkcji w jednym programie, podczas tego samego uruchomienia, w różnych ViewModelach - w zależności od potrzeb.
Klasa i funkcje są statyczne więc, jeśli klasa nazywa się ObslugaPlikow to używam tych funkcji np. tak:

List<string> dane = ObslugaPlikow.odczytaj(@"Config\plik.bin"); 

Pliki, które chcę odczytać są dokładnie tam gdzie być powinny. Na razie są w projekcie w katalogu Debug.

VS2013 usilnie szuka ich w system32 zamiast w prawidłowej ścieżce. Zapis jest ok, problem jest z odczytem.
Co dziwne kiedy uruchomię program bezpośrednio z katalogu Debug (poza IDE) to wszystko działa jak należy.

Aha, zapomniałem. Zapisz wywołuję tak:

 
List<string> dane = new List<string>();
dane.Add("Przyklad");
ObslugaPlikow.zapisz(@"Config\lgData.bin", dane); // nazwa pliku rzecz jasna jest taka sama przy zapisie i odczycie;
0

Z jakiegoś powodu bieżący katalog jest inny podczas zapisu a inny podczas odczytu.

Jeśli umieścisz zapis i odczyt linia po linii w tym samym miejscu programu to ma obowiązek działać.

Trudno cokolwiek więcej powiedzieć.

Jeśli plik ma być w katalogu z exekiem, a nie w bieżącym katalogu, to nie używaj ścieżki względnej, tylko pobierz ścieżkę do exeka.

AppDomain.CurrentDomain.BaseDirectory
1

@grzesiek51114

Wyjątek wywala mi nawet nieuruchomiona aplikacja podczas przeglądania widoków xaml.

VS Designer podczas generowania widoku działa w całkiem innym miejscu niż katalog projektu, Debug czy tam Release więc jak masz gdzieś na zdarzeniu okna, widoku np. Loaded ten zapis lub odczyt to nie dziwota że się wywala.

0

To będzie to. W widoku mam określony datacontext w ten sposób:

<Grid.DataContext>
      <local:LogowanieViewModel/>
</Grid.DataContext>

A w konstruktorze ViewModelu mam coś takiego:

        public LogowanieViewModel() {
            this.logowanie = new LogowanieModel() { nazwaUzytkownika = "", haslo = "", pamietanie = false };
            this.db = BazaDanych.zwrocInstancje();
            this.sprawdzPamietanie();

            try {
                // Tutaj jest wspomniany odczyt;
                List<string> odcz = ObslugaPlikow.odczytaj(@"Config\dbconf.bin");

                // Poniżej tylko obróbka danych z klasy plików, bazująca na już odczytanych danych powyżej;
                List<string> dane = ObslugaPlikow.przygotujDoOdczytu(odcz);
                this.db.inicjalizuj(dane[0], dane[1], dane[2], dane[3]);
            }
            catch (Exception e) {
                MessageBox.Show(e.ToString(), "Niepowodzenie", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

Możesz mieć rację. Pytanie tylko jak mogę pozbyć się tych irytujących komunikatów w IDE?

0
                List<string> odcz = ObslugaPlikow.odczytaj(@"Config\dbconf.bin");

Jeszcze raz:

Azarien napisał(a)

Jeśli plik ma być w katalogu z exekiem, a nie w bieżącym katalogu, to nie używaj ścieżki względnej, tylko pobierz ścieżkę do exeka.

0

Kiedy właśnie to nie działa. Nie działa żadna z tych trzech opcji:

string sciezka = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
// To też -> string sciezka = Path.GetFullPath(AppDomain.CurrentDomain.BaseDirectory);
// I to -> string sciezka = System.IO.Path.GetFullPath(nazwaPliku);
FileStream plik = new FileStream(sciezka + nazwaPliku, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(plik);

Obiekt sciezka w debugowaniu przechowuje za każdym razem dobrą wartość. To designer wywala mi wyjątki podczas oglądania widoku oraz sam program przy uruchomieniu z poziomu IDE.

0

No właśnie nie :)

      public static List<string> odczytaj(string nazwaPliku) {
            string sciezka = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
            //string sciezka = Path.GetFullPath(AppDomain.CurrentDomain.BaseDirectory);
            //string sciezka = System.IO.Path.GetFullPath(nazwaPliku);
            FileStream plik = new FileStream(sciezka + nazwaPliku, FileMode.Open, FileAccess.Read);
            BinaryReader br = new BinaryReader(plik);
            List<string> wyn = new List<string>();

            int poz = 0;
            int dl = (int)br.BaseStream.Length;

            while (poz < dl-poz) {
                poz += br.ReadInt32();
                wyn.Add(br.ReadString());
            }

            br.Close();
            plik.Close();

            return wyn;
        }

Wywołanie:

       try {
                List<string> odcz = ObslugaPlikow.odczytaj(@"\Config\dbconf.bin");
                List<string> dane = ObslugaPlikow.przygotujDoOdczytu(odcz);
                this.db.inicjalizuj(dane[0], dane[1], dane[2], dane[3]);
            }
            catch (Exception e) {
                MessageBox.Show(e.ToString(), "Niepowodzenie", MessageBoxButton.OK, MessageBoxImage.Error);
            }

Jest okej. W debugerze widzę, że ścieżka jest w porządku.

0

Może usuń backslash przed Config

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