Jak przechowywać dane tylko do odczytu, aby wdrożyć je w mojej aplikacji?

17

Zajmuję się tworzeniem aplikacji komputerowej i ta aplikacja wymaga pewnych informacji do uruchomienia, ale nie zmienia żadnej z tych informacji (dane muszą być ładowane przy każdym uruchomieniu aplikacji, ale dane nigdy się nie zmieniają). Dane muszą być przechowywane na tym samym komputerze, na którym działa aplikacja (pamięć po stronie klienta?).

Lepiej jest również, jeśli użytkownik nie może łatwo zmienić tych informacji (zakładając, że nie ma dużej wiedzy informatycznej).

Jak mam przechowywać tego rodzaju informacje? Lokalna baza danych? XML przesyłany z aplikacją?

Używam WPF.

appa yip yip
źródło
2
To nie jest meta. Meta to strona, na której omawiane są problemy lub wątpliwości dotyczące głównych stron, na których zadawane są pytania.
jpmc26,
1
Dlaczego nie chcesz, aby użytkownicy zmieniali informacje? Czy to dotyczy bezpieczeństwa, czy co? Czy te informacje powinny być trzymane w tajemnicy przed użytkownikiem? Przyczyny mogą znacznie zmienić odpowiednie odpowiedzi.
jpmc26,
1
@ jpmc26 Cóż, to rodzaj troski o bezpieczeństwo, ale to nie jest wielka sprawa. Głównym celem aplikacji jest komunikacja przez port szeregowy z regulatorem temperatury (takim jak ten ), a XML przechowa pewne informacje o adresach pamięci sterownika. Jeśli użytkownik to zmieni, może powodować problemy podczas wykonywania, więc chciałbym tego uniknąć. Ale to tylko troska, jak powiedziałem, nic wielkiego. ps: zredagował pytanie, aby zastąpić meta dla SE . Dzięki.
appa yip yip
2
Jeśli chcesz lokalną bazę danych, spójrz na SQLite. (Ale jeśli dane są wystarczająco małe, aby załadować do pamięci RAM na starcie, wolę prostą strukturę pliku json lub coś podobnego binarny)
CodesInChaos
1
„Jeśli użytkownik to zmieni, może powodować problemy podczas wykonywania, więc chciałbym tego uniknąć”. w ogóle nie brzmi jak kwestia bezpieczeństwa. Kwestia bezpieczeństwa to taka, w której w pliku znajduje się hasło lub podobne hasło. Po prostu umieść ustawienia w pliku XML obok pliku wykonywalnego i umieść na górze komentarz z napisem „Nie dotykaj ustawień w tym pliku !!”. Jeśli użytkownik edytuje losowe pliki w katalogu instalacyjnym, zasługuje na wszelkie złamania, jakie otrzyma.
Roger Lipscombe

Odpowiedzi:

14

Plik binarny byłby oczywistą odpowiedzią, ale zależy od tego, w jaki sposób go ładujesz - równie dobrze możesz ułatwić sobie życie, jeśli możesz.

XML może być dobrym wyborem, ponieważ istnieją wbudowane metody w C # do odczytu tego. Możesz dodać sumę kontrolną do swoich danych, aby jeśli użytkownik ją zmieni, suma kontrolna nie będzie już zgodna (musisz dodać czek, aby upewnić się, że suma kontrolna jest poprawna)

Lokalna baza danych może powodować więcej problemów, ponieważ istnieją inne zależności, które wymagają dostępu do niej

Matt Wilko
źródło
Nie myślałem o sumie kontrolnej, to naprawdę fajny pomysł. Generuję więc sumę kontrolną i przechowuję ją w mojej aplikacji, więc za każdym razem, gdy rozpakowuję XML, generuję nową sumę kontrolną i porównuję ją z pierwszą?
appa yip yip
4
Jeśli przechowujesz sumę kontrolną w aplikacji, nigdy nie zezwolisz na inną konfigurację, więc równie dobrze możesz przechowywać dane konfiguracyjne jako stałe aplikacji w kodzie. Jeśli chcesz mieć możliwość zmiany konfiguracji w przyszłości, dodaj sumę kontrolną (lepszym terminem byłoby „hash”) jako pole XML i użyj jej do sprawdzenia, czy XML nie został zmieniony. Oczywiście zdeterminowany atakujący może zbadać Twój kod, znaleźć logikę mieszania i użyć go do wygenerowania prawidłowych plików XML, ale w każdym razie aplikacje po stronie klienta są zawsze podatne na określone ataki.
SJuan76,
4
Zamiast pliku lub lokalnego db lepiej plik zasobów osadzony w asemblerze byłby lepszy. Ukryty przed użytkownikiem końcowym, łatwy do zarządzania przez programistę, ale nadal przyjazny dla zaawansowanych użytkowników. Jeśli problemem jest wydajność, serializacja binarna byłaby lepsza.
PTwr
@ SJuan76 Tak, problem z hashem w XML polega na tym, że można go zmienić, jeśli ktoś go odserializuje. W każdym razie, jeśli zmiana XML (co myślę, że tak się nie stanie, ale kto wie) zmieni się tylko w nowej wersji aplikacji, więc zgadnij, że pozostanę przy haszowaniu kodu.
appa yip yip
2
@schmaedeck: Pliki zasobów to dosłownie pliki wewnątrz wykonywalnego pliku binarnego. Ikony i ciągi oraz wszelkie inne stałe dane, których potrzebuje Twój program.
Mooing Duck,
21

Jeśli dane nigdy się nie zmieniają i są tylko do odczytu , po prostu umieść je w pliku kodu jako listę stałych.

public readonly string AppStartUpData = "MyAppNeedsThis";

Jeśli te dane różnią się w zależności od wdrożenia, plik zewnętrzny jest w porządku.

.Net ma wbudowane pliki .config (App.Config). Należy ich używać, ponieważ istnieją standardowe sposoby (wbudowane w środowisko) do odczytywania z nich informacji.

Użyj plików konfiguracyjnych na wypadek, gdyby ustawienie musiało się zmienić (nigdy nie mów nigdy), ponieważ są to tylko pliki tekstowe (Xml). Jeśli istnieją poufne informacje, w razie potrzeby można zaszyfrować ustawienie.

Jon Raynor
źródło
Myślałem o stałych / tylko do odczytu, problem polega na tym, że jest dużo danych, więc myślę, że sprawdzę zewnętrzny plik. Dziękuję Ci!
appa yip yip
5
@schmaedeck ... więc? Możesz umieścić te definicje w osobnym pliku i zaimportować go. W rzeczywistości uważam, że Qt robi takie rzeczy podczas kompilowania formularzy i innych rzeczy, więc otrzymujesz automatycznie generowane pliki, które mają megabajty danych binarnych (np. Obrazów) w niektórych stałych, ale jeśli jest to osobny plik, nie ma w tym nic złego .
Bakuriu,
15

Zawsze możesz dodać plik do projektu i ustawić jego typ kompilacji, aby Embedded Resourcebył osadzony bezpośrednio w samej aplikacji.

Alternatywnie plik, który jest zaszyfrowany i umieszczony w dostępnej lokalizacji.

TheLethalCoder
źródło
1
To najlepsza odpowiedź. Chciałbym zobaczyć więcej wskazówek, jak to osiągnąć. Otrzymasz korzyści z potencjalnie zmiennego pliku konfiguracyjnego, ale utrzymasz go w stanie statycznym, ponieważ jest osadzony w zestawie.
Gusdor,
5

Jeśli nie chcesz, aby użytkownik nawet zerknął na dane, powinieneś serializować je do pliku danych binarnych.

Tylko aplikacja zna długość fragmentów do odczytania z niego.

Nie znam C #, ale w Javie utworzyłbyś taki plik:

FileOutputStream fos = new FileOutputStream(file);      
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(var1);
oos.writeObject(var2);
oos.writeObject(var3);
oos.writeObject(var4);

... i czytają to tak:

FileInputStream fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis);
Object o[] = new Object[4];
o[0] = ois.readObject();
o[1] = ois.readObject();
o[2] = ois.readObject();
o[3] = ois.readObject();
Tulains Córdova
źródło
Z pewnością skorzystam z binarnej serializacji. Wielkie dzięki za poświęcony czas!
appa yip yip