дисковое хранилище массивов и т. д. - PullRequest
1 голос
/ 05 ноября 2010

У кого-нибудь есть опыт хранения данных на диске? У меня есть приложение для моделирования в памяти, которое может выполнять вычисления и т. Д. В основном данные хранятся в виде списков объектов, которые имеют вложенные коллекции значений ключей, такие как Dictionary >.

Сейчас я использую SQL-Server в качестве слоя персистентности, но я использую его очень мало. Поэтому я думаю, что могу записать / прочитать данные на диск самостоятельно, чтобы уменьшить зависимости и упростить установку.

Итак, я написал небольшую процедуру, которая записывает каждый массив на диск примерно в таком формате, где слова «ObjId», «Type», «Valid» и «Count» на самом деле не находятся в файле, они , 2nd, 3rd и 4th int в byte [], затем идут пары . 52 происходит от 4 * 4 + 3 * (4 + 8). (4 байта для int, 8 для двойного)

Bytes: 52

ObjId: 123 
Valid: 234  
Type: double
Count: 3
    1 .23
    2 .34
    3 .45

В реальной жизни нет отступов и т. Д., Все они представляют собой последовательные байты в длинном потоке.

Это нормально, написать один раз. Но когда я хочу написать дополнительное значение где-то посередине, я должен переписать все это. Также я не могу легко обновить одно значение.

Одна альтернатива - записать каждый объект в отдельный файл, поэтому мне нужно будет только переписать это. Но это кажется довольно неэффективным, потому что я получаю файлы размером 1 КБ, но 4 КБ на диске, так что я бы тратил на них место.

Так что мне нужно сделать, чтобы иметь возможность постепенно записывать этот файл на диск? Я знаю, что у SqlServer есть «страницы», куда он записывает данные, это путь?

Есть ли какая-либо библиотека, готовая для решения этой проблемы? Может быть, какой-нибудь виртуальный файл, который позволит мне обрабатывать их как отдельный байт [], но обрабатывает хранилище как один физический файл? Идеально сжатый .. (толкает его, но кто знает .. Я был удивлен раньше: -)

Заранее спасибо,

Герт-Ян

Ответы [ 4 ]

2 голосов
/ 05 ноября 2010

Если вам не нужны служебные данные СУБД, вы можете использовать базу данных значений ключей, такую ​​как Berkeley DB.Здесь есть интерфейс C #:

Berkeley DB для .NET

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

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

1 голос
/ 05 ноября 2010

Существует тысяча и один способ хранения информации на диске. У вас уже были предложения о базах данных. Вы также можете рассмотреть структурированные форматы файлов, такие как HDF5 , которые имеют привязки для языков, включая C # Одной из сильных сторон HDF5 является поддержка хранения n-мерных массивов.

1 голос
/ 05 ноября 2010

Вы не сможете обойтись, имея по 1 файлу на объект или переписывая весь список объектов при внесении изменений. Вы можете использовать SQLite . Это встроенная в один файл база данных, которая очень быстрая и эффективная. Это означает, что ваше приложение не имеет внешних зависимостей от БД.

Если вы пишете свои данные напрямую, вы должны прочитать и записать их в двоичном формате . Вы будете хранить свои целые числа в одном байте вместо их представления ASCII (1234 = 4 байта, но 1 байт int).

Это ускорит чтение и запись в файл.

Какой-то код из статьи:

    Hashtable addresses = new Hashtable();
    addresses.Add("Jeff", "123 Main Street, Redmond, WA 98052");
    addresses.Add("Fred", "987 Pine Road, Phila., PA 19116");
    addresses.Add("Mary", "PO Box 112233, Palo Alto, CA 94301");

    // To serialize the hashtable and its key/value pairs,  
    // you must first open a stream for writing. 
    // In this case, use a file stream.
    FileStream fs = new FileStream("DataFile.dat", FileMode.Create);

    // Construct a BinaryFormatter and use it to serialize the data to the stream.
    BinaryFormatter formatter = new BinaryFormatter();
    try 
    {
        formatter.Serialize(fs, addresses);
    }
    catch (SerializationException e) 
    {
        Console.WriteLine("Failed to serialize. Reason: " + e.Message);
        throw;
    }
0 голосов
/ 05 ноября 2010

В дополнение к другим предложениям, сделанным здесь, вы можете попробовать MongoDB с NORM как отличный, не требующий трения (нет базы данных для настройки, нет реляционного отображения объекта для создания) способ хранения данных без дополнительных затрат / затрат на SQL-сервер.

...