Найкращий спосіб зберігати дані локально в .NET (C #)


75

Я пишу програму, яка бере дані користувача та зберігає їх локально для подальшого використання. Додаток запускатиметься та зупинятиметься досить часто, і я хотів би змусити його зберігати / завантажувати дані при запуску / закінченні програми.

Було б досить просто, якби я використовував плоскі файли, оскільки дані насправді не потребують захисту (вони зберігатимуться лише на цьому ПК). Таким чином, я вважаю варіанти:

  • Плоскі файли
  • XML
  • SQL DB

Плоскі файли вимагають трохи більше зусиль для підтримання (відсутні вбудовані класи, як у XML), однак я раніше не використовував XML, і SQL здається надмірним для цього порівняно легкого завдання.

Чи є інші шляхи, які варто вивчити? Якщо ні, то яке з них є найкращим рішенням?


Редагувати: Щоб додати до проблеми трохи більше даних, в основному єдине, що я хотів би зберігати, - це Словник, який виглядає так

Dictionary<string, List<Account>> 

де Обліковий запис - інший спеціальний тип.

Я б серіалізував dict як xmlroot, а потім тип Account як атрибути?


Оновлення 2:

Тож можна серіалізувати словник. Ускладнює те, що значення цього дикту є самим загальним, що є переліком складних структур даних типу Account. Кожен рахунок досить простий, це лише купа властивостей.

Я розумію, що мета тут - спробувати закінчити з цим:

<Username1>
    <Account1>
        <Data1>data1</Data1>
        <Data2>data2</Data2>
    </Account1>
</Username1>
<Username2>
    <Account1>
        <Data1>data1</Data1>
        <Data2>data2</Data2>
    </Account1>
    <Account2>
        <Data1>data1</Data1>
        <Data2>data2</Data2>
    </Account2>
 </Username2>

Як бачите, ірахія є

  • Ім'я користувача (рядок dict)>
  • Обліковий запис (кожен рахунок у Переліку)>
  • Дані облікового запису (тобто властивості класу).

Отримати цей макет з a Dictionary<Username, List<Account>>- хитрий біт, і суть цього питання.

Тут є багато відповідей "як відповісти" щодо серіалізації, і це моя вина, оскільки я не пояснив це на початку, але зараз я шукаю певне рішення.


дайте більше подробиць про тип програми та збережені дані, а також очікуваний sizr
AK_

3
Для сериализации словника: stackoverflow.com/questions/1111724
Cheeso

Відповіді:


26

Я зберігав би файл як JSON . Оскільки ви зберігаєте словник, який є лише списком пари ім'я / значення, то це майже те, для чого був розроблений json.
Існує досить багато пристойних безкоштовних бібліотек .NET json - ось одна, але ви можете знайти повний список за першим посиланням.


json трохи незвичний для локального сховища, але це, безумовно, чудове рішення. Особливо з такою бібліотекою, як Json.NET від Newtonsoft
AFract

2
замість того, щоб покладатися на сторонні бібліотеки, я б зберігав дані, використовуючи вбудований тип набору даних, який надзвичайно просто записати на диск (див. приклад Тома Міллера нижче)
EKanadily

24

Це насправді залежить від того, що ви зберігаєте. Якщо ви говорите про структуровані дані, то для вас добре підійде XML або дуже легкий SQL RDBMS, такий як SQLite або SQL Server Compact Edition. Рішення SQL стає особливо привабливим, якщо дані виходять за межі тривіального розміру.

Якщо ви зберігаєте великі фрагменти відносно неструктурованих даних (наприклад, двійкові об'єкти, такі як зображення), то, очевидно, ні база даних, ні рішення XML не підходять, але, враховуючи ваше запитання, я здогадуюсь, що це більше перші, ніж другі.


Файли конфігурації XML мають бути структурованими?

@Roboto: XML, за визначенням, структурований. Це не означає, що вам доведеться використовувати їх у структурованому вигляді.
Адам Робінсон,

17

Все вищезазначене є гарними відповідями і загалом вирішує проблему.

Якщо вам потрібен простий, безкоштовний спосіб масштабування до мільйонів даних, спробуйте проект керованого інтерфейсу ESENT на GitHub або від NuGet .

ESENT - це вбудований механізм зберігання баз даних (ISAM), який є частиною Windows. Він забезпечує надійне, транзакційне, одночасне, високопродуктивне зберігання даних із блокуванням на рівні рядка, реєстрацією вперед і ізоляцією знімків. Це керована обгортка для ESENT Win32 API.

Він має об’єкт PersistentDictionary, який досить простий у використанні. Подумайте про це як про об’єкт Dictionary (), але він автоматично завантажується та зберігається на диску без зайвого коду.

Наприклад:

/// <summary>
/// Ask the user for their first name and see if we remember 
/// their last name.
/// </summary>
public static void Main()
{
    PersistentDictionary<string, string> dictionary = new PersistentDictionary<string, string>("Names");
    Console.WriteLine("What is your first name?");
    string firstName = Console.ReadLine();
    if (dictionary.ContainsKey(firstName))
    {
        Console.WriteLine("Welcome back {0} {1}", firstName, dictionary[firstName]);
    }
    else
    {
        Console.WriteLine("I don't know you, {0}. What is your last name?", firstName);
        dictionary[firstName] = Console.ReadLine();
    }

Щоб відповісти на запитання Джорджа:

Підтримувані типи ключів

В якості ключів словника підтримуються лише такі типи:

Логічний байт Int16 UInt16 Int32 UInt32 Int64 UInt64 Float Double Guid DateTime TimeSpan String

Підтримувані типи значень

Значеннями словника можуть бути будь-які з типів ключів, версії типів ключів, що допускають відхилення, Uri, IPAddress або серіалізована структура. Структура вважається серіалізованою лише в тому випадку, якщо вона відповідає всім цим критеріям:

• Структура позначена як серіалізуюча. • Кожен член структури є: 1. Примітивним типом даних (наприклад, Int32) 2. Рядком, Uri або IPAddress 3. Серіалізованою структурою.

Або, інакше кажучи, серіализуемая структура не може містити жодних посилань на об’єкт класу. Це робиться для збереження узгодженості API. Додавання об’єкта до PersistentDictionary створює копію об’єкта за допомогою серіалізації. Зміна оригінального об'єкта не призведе до модифікації копії, що призведе до заплутаної поведінки. Щоб уникнути цих проблем, PersistentDictionary приймає лише типи значень як значення.

Чи можна серіалізувати [серіалізується] структуру Добре {public DateTime? Отримано; загальнодоступний рядок Ім'я; публічна десяткова ціна; загальнодоступна URL-адреса Урі; }

Неможливо серіалізувати [серіалізується] struct Погане {загальнодоступний байт [] Дані; // масиви не підтримуються публічною помилкою винятків; // посилальний об'єкт}


Цей метод в основному замінює вбудований загальний на постійний словник. Це досить елегантне рішення, але як воно обробляє складні об’єкти, як у прикладі OP? Він зберігає все, що знаходиться всередині дикту, або лише сам дикт?
Джордж

Це може не досягти кінцевої мети - спробувати зберегти списки типу Account. Ключі були б чудовими, але зробити загальну серіалізацію може бути важко: /.
Джордж

1
Будь-хто інший, хто реалізує це, може отримати користь від того, що ви можете використовувати Nuget для отримання ManagedEsent. Тоді вам потрібно посилатися на Esent.Collections.DLL та Esent.ISAM.DLL. Потім додайте "за допомогою Microsoft.Isam.Esent.Collections.Generic;" отримати тип PersistentDictionary. Колекції DLL, можливо, доведеться завантажувати з опції завантаження на Managedesent.codeplex.com
Стів Хібберт,

"ManagedEsent" перетворився на "Microsoft.Database.ManagedEsent". Натомість слід використовувати "Microsoft.Database.Collections.Generic" із nuget, оскільки він включає і ManagedEsent, і ISAM.
VoteCoffee

15

XML простий у використанні за допомогою серіалізації. Використовуйте ізольоване сховище .

Див. Також Як вирішити, де зберігати стан кожного користувача? Реєстр? Дані програми? Ізольоване сховище?

public class UserDB 
{
    // actual data to be preserved for each user
    public int A; 
    public string Z; 

    // metadata        
    public DateTime LastSaved;
    public int eon;

    private string dbpath; 

    public static UserDB Load(string path)
    {
        UserDB udb;
        try
        {
            System.Xml.Serialization.XmlSerializer s=new System.Xml.Serialization.XmlSerializer(typeof(UserDB));
            using(System.IO.StreamReader reader= System.IO.File.OpenText(path))
            {
                udb= (UserDB) s.Deserialize(reader);
            }
        }
        catch
        {
            udb= new UserDB();
        }
        udb.dbpath= path; 

        return udb;
    }


    public void Save()
    {
        LastSaved= System.DateTime.Now;
        eon++;
        var s= new System.Xml.Serialization.XmlSerializer(typeof(UserDB));
        var ns= new System.Xml.Serialization.XmlSerializerNamespaces();
        ns.Add( "", "");
        System.IO.StreamWriter writer= System.IO.File.CreateText(dbpath);
        s.Serialize(writer, this, ns);
        writer.Close();
    }
}

1
Це не дуже портативно та акуратно

3
Це схоже на вирізаний-вставлений код, тому ви можете бути першим плакатом. Краще було б просто дотримуватися своїх посилань.

9
Ну, так, я вирізав це прямо з програми, яку я написав, яка робить це. Робото, в чому проблема?
Cheeso

Він навіть не використовує ін’єкцію залежності! Ви не отримали пам’ятку?
Стів Сміт

Я погоджуюсь з рекомендацією XML, але, спробувавши сам, я досягнув обмеження Isolated Storage - воно створює різні файли, залежно від того, з якої збірки працює код. Закінчився просто за допомогою AppData \ Roaming черезPath.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"{AppName}\{FileName}.XML");
Ory Zaidenvorm

9

Я рекомендую XML-клас читання / запису для файлів, оскільки він легко серіалізується.

Серіалізація в C #

Серіалізація (відома як травлення в python) - це простий спосіб перетворити об’єкт у двійкове представлення, яке потім можна, наприклад, записати на диск або надіслати по дроту.

Це корисно, наприклад, для простого збереження налаштувань у файл.

Ви можете серіалізувати власні класи, якщо позначити їх [Serializable] атрибутом. Це серіалізує всіх членів класу, крім тих, хто позначений як [NonSerialized].

Нижче наведено код, який покаже вам, як це зробити:

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;


namespace ConfigTest
{ [ Serializable() ]

    public class ConfigManager
    {
        private string windowTitle = "Corp";
        private string printTitle = "Inventory";

        public string WindowTitle
        {
            get
            {
                return windowTitle;
            }
            set
            {
                windowTitle = value;
            }
        }

        public string PrintTitle
        {
            get
            {
                return printTitle;
            }
            set
            {
                printTitle = value;
            }
        }
    }
}

Тоді ви, можливо, в ConfigForm, зателефонуєте до свого класу ConfigManager і серіалізуєте його!

public ConfigForm()
{
    InitializeComponent();
    cm = new ConfigManager();
    ser = new XmlSerializer(typeof(ConfigManager));
    LoadConfig();
}

private void LoadConfig()
{     
    try
    {
        if (File.Exists(filepath))
        {
            FileStream fs = new FileStream(filepath, FileMode.Open);
            cm = (ConfigManager)ser.Deserialize(fs);
            fs.Close();
        } 
        else
        {
            MessageBox.Show("Could not find User Configuration File\n\nCreating new file...", "User Config Not Found");
            FileStream fs = new FileStream(filepath, FileMode.CreateNew);
            TextWriter tw = new StreamWriter(fs);
            ser.Serialize(tw, cm);
            tw.Close();
            fs.Close();
        }    
        setupControlsFromConfig();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

Після його серіалізації ви можете викликати параметри конфігураційного файлу за допомогою cm.WindowTitle тощо.


5
Тільки для уточнення: серіалізовані та несеріалізовані не впливають на XmlSerializer; вони використовуються лише для System.Runtime.Serialization (наприклад, двійкова серіалізація). XmlSerializer серіалізує загальнодоступні поля та властивості (читання-запис), а не внутрішній стан: атрибут не потрібен для класу, а XmlIgnore замість NonSerialized для виключення поля або властивості.
itowlson

@itowlson: Правильно. Серіалізація XML використовує відображення для створення спеціальних класів для виконання серіалізації.

Це допомогло б при читанні коду, якби він був з відступами без випадкового розміру ...
Лассе В. Карлсен,

@Lasse: Не знаю, що ти маєш на увазі, але якщо це занадто важко читати, ти можеш його редагувати

8

Якщо ваша колекція стає занадто великою, я виявив, що серіалізація Xml стає досить повільною. Іншим варіантом серіалізації словника було б "розгорнути свій власний" за допомогою BinaryReader та BinaryWriter.

Ось декілька зразків коду лише для початку. Ви можете зробити ці загальні методи розширення для обробки будь-якого типу Словника, і це працює досить добре, але занадто багатослівно, щоб розміщувати його тут.

class Account
{
    public string AccountName { get; set; }
    public int AccountNumber { get; set; }

    internal void Serialize(BinaryWriter bw)
    {
        // Add logic to serialize everything you need here
        // Keep in synch with Deserialize
        bw.Write(AccountName);
        bw.Write(AccountNumber);
    }

    internal void Deserialize(BinaryReader br)
    {
        // Add logic to deserialize everythin you need here, 
        // Keep in synch with Serialize
        AccountName = br.ReadString();
        AccountNumber = br.ReadInt32();
    }
}


class Program
{
    static void Serialize(string OutputFile)
    {
        // Write to disk 
        using (Stream stream = File.Open(OutputFile, FileMode.Create))
        {
            BinaryWriter bw = new BinaryWriter(stream);
            // Save number of entries
            bw.Write(accounts.Count);

            foreach (KeyValuePair<string, List<Account>> accountKvp in accounts)
            {
                // Save each key/value pair
                bw.Write(accountKvp.Key);
                bw.Write(accountKvp.Value.Count);
                foreach (Account account in accountKvp.Value)
                {
                    account.Serialize(bw);
                }
            }
        }
    }

    static void Deserialize(string InputFile)
    {
        accounts.Clear();

        // Read from disk
        using (Stream stream = File.Open(InputFile, FileMode.Open))
        {
            BinaryReader br = new BinaryReader(stream);
            int entryCount = br.ReadInt32();
            for (int entries = 0; entries < entryCount; entries++)
            {
                // Read in the key-value pairs
                string key = br.ReadString();
                int accountCount = br.ReadInt32();
                List<Account> accountList = new List<Account>();
                for (int i = 0; i < accountCount; i++)
                {
                    Account account = new Account();
                    account.Deserialize(br);
                    accountList.Add(account);
                }
                accounts.Add(key, accountList);
            }
        }
    }

    static Dictionary<string, List<Account>> accounts = new Dictionary<string, List<Account>>();

    static void Main(string[] args)
    {
        string accountName = "Bob";
        List<Account> newAccounts = new List<Account>();
        newAccounts.Add(AddAccount("A", 1));
        newAccounts.Add(AddAccount("B", 2));
        newAccounts.Add(AddAccount("C", 3));
        accounts.Add(accountName, newAccounts);

        accountName = "Tom";
        newAccounts = new List<Account>();
        newAccounts.Add(AddAccount("A1", 11));
        newAccounts.Add(AddAccount("B1", 22));
        newAccounts.Add(AddAccount("C1", 33));
        accounts.Add(accountName, newAccounts);

        string saveFile = @"C:\accounts.bin";

        Serialize(saveFile);

        // clear it out to prove it works
        accounts.Clear();

        Deserialize(saveFile);
    }

    static Account AddAccount(string AccountName, int AccountNumber)
    {
        Account account = new Account();
        account.AccountName = AccountName;
        account.AccountNumber = AccountNumber;
        return account;
    }
}

Дякую, це виглядає найкращим рішенням на сьогодні. Що ви маєте на увазі під синхронізацією з десериалізацією / серіалізацією? Як при оновленні файлу при його зміні? Ця функція використовуватиметься лише під час запуску та виходу програми для збереження дикту, тож, будь ласка, поясніть це? Інакше велике спасибі.
Джордж

Трохи задумавшись, я зрозумів, що це означає, що логіка серіалізації та десериалізації повинна бути однаковою. Це все.
Джордж

Так, це все, що це означає. Отже, якщо ви додаєте іншу властивість для серіалізації / десеріалізації, просто майте на увазі, що вам доведеться додати код як до методу серіалізації / десеріалізації, так і зберігати їх у тому ж порядку. Трохи підтримання, але продуктивність над серіалізацією Xml не є порівнянням (кілька хвилин для десеріалізації за допомогою xml, до декількох секунд за допомогою BinaryReader, з кількома сотнями тисяч словникових елементів).
GalacticJello

Дякую, це ідеальне рішення
Sarath Vuyyuru

7

Четвертим варіантом для тих, кого ви згадали, є двійкові файли . Хоча це звучить загадково і складно, але за допомогою API серіалізації в .NET це дуже просто.

Незалежно від того, обираєте ви двійкові файли або файли XML, ви можете використовувати один і той же API серіалізації, хоча ви б використовували різні серіалізатори.

Для двійкової серіалізації класу він повинен бути позначений атрибутом [Серіалізація] або реалізувати ISerializable.

Ви можете зробити щось подібне з XML , хоча там інтерфейс називається IXmlSerializable, а атрибутами є [XmlRoot] та іншими атрибутами у просторі імен System.Xml.Serialization.

Якщо ви хочете використовувати реляційну базу даних, SQL Server Compact Edition є безкоштовною і дуже легкою і базується на одному файлі.


1
Плоский файл! = Текстовий файл. Я вважаю, що це підпадає під категорію "плоский файл".
Адам Робінсон

2
Ви можете двійково серіалізувати клас незалежно від того, маєте справу з XML-файлами чи ні

2
якщо вам не потрібно, щоб серіалізований об’єкт був зручним для читання, це найнадійніший шлях. Він серіалізується до крихітного файлу і завжди здавався найшвидшим способом зробити це, з точки зору того, як швидко працював код. І Марк має рацію, здається незвичним і складним, але це зовсім не так. А бінарна серіалізація фіксує ЦІЛИЙ об’єкт, навіть його приватні члени, чого серіалізація XML не робить.
CubanX

6

Щойно закінчив кодування даних для мого поточного проекту. Ось мої 5 центів.

Я почав з бінарної серіалізації. Це було повільно (близько 30 с для завантаження 100 000 об’єктів), і це також створювало досить великий файл на диску. Однак мені знадобилося кілька рядків коду для реалізації, і я покрив усі свої потреби у сховищі. Для кращої продуктивності я перейшов до користувацької серіалізації. Знайдено фреймворк FastSerialization від Тіма Хейнса в програмі Code. Дійсно, це в кілька разів швидше (12 секунд для завантаження, 8 секунд для збереження, 100 тис. Записів) і займає менше місця на диску. Структура побудована на техніці, викладеній GalacticJello у попередньому дописі.

Потім я перейшов до SQLite і зміг отримати в 2 рази швидше продуктивність - 6 секунд для завантаження та 4 секунди для збереження, 100 000 записів. Він включає аналіз таблиць ADO.NET на типи програм. Це також дало мені набагато менший файл на диску. У цій статті пояснюється, як отримати найкращу продуктивність від ADO.NET: http://sqlite.phxsoftware.com/forums/t/134.aspx . Створення операторів INSERT - дуже погана ідея. Ви здогадуєтесь, як я дізнався про це. :) Справді, впровадження SQLite зайняло у мене досить багато часу плюс ретельне вимірювання часу майже кожним рядком коду.


5

Перше, на що я б подивився, - це база даних. Однак серіалізація - це варіант. Якщо ви підете на бінарну серіалізацію, то я б цього уникнув BinaryFormatter - вона має тенденцію злитися між версіями, якщо ви змінюєте поля тощо. Xml via XmlSerialzierбуде чудовим і може бути сумісним поруч (тобто з тими ж визначеннями класів) з protobuf-net, якщо ви хочете спробувати двійкову серіалізацію на основі контракту (надаючи вам серіалізатор плоских файлів без будь-яких зусиль).


4

Якщо ваші дані складні, великі за кількістю або вам потрібно запитати їх локально, тоді об’ємні бази даних можуть бути допустимим варіантом. Я б запропонував поглянути на Db4o або Karvonite .


3

Багато відповідей у ​​цій темі намагаються переробити рішення. Якщо я помиляюся, ви просто хочете зберегти налаштування користувача.

Для цього використовуйте файл .ini або файл App.Config.

Якщо я помиляюся, і ви зберігаєте дані, які є не просто налаштуваннями, використовуйте плоский текстовий файл у форматі CSV. Це швидко і легко, без накладних витрат на XML. Люди люблять качати їх, оскільки вони не такі елегантні, не гарно масштабуються і не так добре виглядають у резюме, але це може бути найкращим рішенням для вас, залежно від того, що вам потрібно.


app.config проти призначених для користувача XML: stackoverflow.com/questions/1565898 / ...

Я роблю щось дещо складніше, ніж просто налаштування. Кожен користувач може мати кілька "облікових записів", пов'язаних із своїм іменем. Словник пов'язує це ім'я (рядок) зі списком пов'язаних з ними облікових записів. Я б зберігав купу облікових записів для кожного користувача. Це може працювати з xml, але я не зовсім впевнений, як це робити.
Джордж

У такому випадку я б використовував клас XmlSerializer, як згадано. Якщо ви добре розумієте ООП, це має бути легко. Ось хороший приклад: jonasjohn.de/snippets/csharp/xmlserializer-example.htm
Джеймс

2

Не знаючи, як виглядають ваші дані, тобто складність, розмір тощо ... XML простий в обслуговуванні і легко доступний. Я б НЕ використовував базу даних Access, а плоскі файли важче підтримувати протягом довгого часу, особливо якщо ви маєте справу з кількома полями / елементами даних у вашому файлі.

Я маю справу з великими стрічками даних плоских файлів у великих кількостях щодня, і навіть незважаючи на крайній приклад, дані плоских файлів набагато складніше підтримувати, ніж канали даних XML, які я обробляю.

Простий приклад завантаження даних XML у набір даних за допомогою C #:

DataSet reportData = new DataSet();

reportData.ReadXml(fi.FullName);

Ви також можете перевірити LINQ to XML як опцію для запиту даних XML ...

HTH ...


1

Я зробив кілька "автономних" програм, які мають локальний сховище даних. Я думаю, що найкращим для використання буде SQL Server Compact Edition (раніше відомий як SQLAnywhere).

Це легкий і безкоштовний. Крім того, ви можете дотримуватися написання рівня доступу до даних, який багаторазово використовується в інших проектах, а також якщо додатку коли-небудь потрібно буде масштабуватися до чогось більшого, як повномасштабний SQL-сервер, вам потрібно лише змінити рядок з'єднання.


1

Залежно від гнучкості об’єкта Вашого облікового запису, я рекомендую XML або Flat файл.

Якщо для кожного облікового запису потрібно зберегти лише пару значень, ви можете зберегти їх у файлі властивостей, наприклад:

account.1.somekey=Some value
account.1.someotherkey=Some other value
account.1.somedate=2009-12-21
account.2.somekey=Some value 2
account.2.someotherkey=Some other value 2

... і так далі. Читання з файлу властивостей має бути простим, оскільки воно безпосередньо відображається у словниковому словнику.

Щодо того, де зберігати цей файл, найкращим варіантом буде збереження в папці AppData, у підпапці вашої програми. Це місце, де поточні користувачі завжди матимуть доступ до запису, і сама ОС захищає від інших користувачів.


0

Мій перший нахил - це база даних доступу. Файли .mdb зберігаються локально і можуть бути зашифровані, якщо це буде визнано необхідним. Хоча XML або JSON також працюють для багатьох сценаріїв. Плоскі файли, які я використовував би лише для читання, не шукати інформацію (лише для читання вперед). Я, як правило, віддаю перевагу формату CSV для встановлення ширини.


2
З цікавості, чому б ви користувались Access, якщо він уже не був або вам не потрібен доступ до нього з, ну, Access? В іншому випадку здається, що полегшений механізм SQL був би більш доцільним, особливо з наявними в процесі функціями, такими як SQLite та SQL Server CE.
Адам Робінсон

Я вважаю, що механізм JET, який дозволяє використовувати файли .MDB, встановлений у вікнах, що робить використання файлів .MDB привабливим як рішення, це та той факт, що їх легко вкопати з доступом, якщо ви потребую. Однак це передує поточному втіленню SQL Server CE, яке може бути розгортанням "xcopy" .DLL і, отже, кращим способом досягнення подібного результату.
Мерф

15
Друзі не дозволяють друзям використовувати Access

@Murph: Так, JET зараз є компонентом Windows, але (як ви зазначаєте) розгортання XCOPY (і хост у процесі) SQL Server CE, здається, усуває будь-які переваги, які має JET, зберігаючи недоліки (обмежені та дивні Підтримка синтаксису SQL, багато ORM цього не підтримують тощо). Отже ... Я думаю, моє питання все ще стоїть, чому ви його рекомендуєте :)
Адам Робінсон

1
Як заявили майже всі мої вчителі: Доступ не є справжньою базою даних :)
Флоріан К

0

Це залежить від обсягу даних, які ви хочете зберегти. Насправді немає різниці між площими файлами та XML. XML, мабуть, був би кращим, оскільки він забезпечує структуру документа. На практиці,

Останній варіант, і зараз використовується багато програм - це реєстр Windows. Я особисто не рекомендую (здуття реєстру, корупція, інші потенційні проблеми), але це варіант.


Одна область, де плоскі файли відрізняються від XML, представляє ієрархічні дані. Звичайно, ви можете представляти ієрархії в плоских файлах, але це простіше зробити в XML.
itowlson

0

Якщо ви йдете двійковим шляхом серіалізації, враховуйте швидкість, з якою потрібно отримати доступ до певного елемента даного. Якщо це лише невелика колекція, завантаження всього файлу матиме сенс, але якщо він буде великим, ви також можете розглянути індексний файл.

Відстеження властивостей облікового запису / полів, розташованих за певною адресою у файлі, може допомогти вам пришвидшити час доступу, особливо якщо ви оптимізуєте цей індексний файл на основі використання ключа. (можливо навіть під час запису на диск.)


0

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

Це передбачає, що ви правильно проаналізували свої вимоги. Я б пропустив серіалізацію як крок XML, надмір для простого словника. Те саме для бази даних.


0

З мого досвіду, у більшості випадків достатньо JSON у файлі (здебільшого потрібно зберігати масив або об’єкт, або лише одне число або рядок). Мені рідко потрібен SQLite (якому потрібно більше часу на його налаштування та використання, більшість випадків це надмірно).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.