Удалить запись из сериализованного файла? - PullRequest
1 голос
/ 30 ноября 2011

Я открываю сериализованный файл, в котором хранятся все мои записи.Код находит соответствие между свойством идентификатора объекта текущей записи и номером в соответствующем текстовом поле.Я хочу удалить запись, если есть совпадение.Лучший способ сделать это?

Item readItem = new Item();
BinaryFormatter bFormatter = new BinaryFormatter();
FileStream inFile = new FileStream(@"C:\file.dat", FileMode.Open, FileAccess.Read);

while (inFile.Position < inFile.Length)
    readItem = (Item)bFormatter.Deserialize(inFile);
    if (readItem.ID.ToString() == IDTextBox.Text)
{

    ??????

 }

Ответы [ 2 ]

2 голосов
/ 30 ноября 2011

Вам необходимо десериализовать файл, удалить элемент из списка, а затем заново выполнить всю сериализацию. Было бы лучше использовать файловую базу данных, такую ​​как SQLLite, и просто сериализовать записи в BLOB-объекты внутри строки.

1 голос
/ 30 ноября 2011

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

Записи переменного размера

Что вам нужно сделать, это переместить все содержимое файла послезапись, от которой вы хотите избавиться, перезаписать часть, которую вы хотите удалить, а затем обрезать файл.Это немного сложно сделать на месте (т. Е. Внутри одного и того же файла), поскольку вы можете только прочитать достаточно данных, чтобы избежать перезаписи остальной части файла при каждой итерации цикла перемещения вверх.

AБолее простой метод, который создаст новый файл из старого, выглядит следующим образом:

  1. Запишите положение потока перед тем, как десериализовать элемент
  2. Если элемент соответствует, сделайтепримечание о позиции потока в том виде, в каком оно есть сейчас (теперь эти две позиции обозначают область файла, в которой находится запись, от которой вы хотите избавиться)
  3. Создайте новый файл и первую копию изначало, то же число байтов, что и в первой позиции, от старого потока (в котором вы нашли запись) до нового потока
  4. Позиция старого потока в позиции, которую вы отметили после найденную вами запись и скопируйте все, что вы можете найти, в новый поток

Это создаст новый файл с тем же содержимым, что и старый, за исключением того, что вы катаетесь на лыжах.p запись, от которой вы хотите избавиться.

Если вы можете перебрать все записи и просто определить, хотите ли вы сохранить их или нет, вот еще более простой метод:

  1. Открыть новый поток
  2. Десериализовать элемент из старого потока
  3. Если вы хотите сохранить его, сериализовать его обратно в новый поток
  4. И так далее дляостальные элементы.

Записи фиксированного размера

Просто прочитайте последнюю запись файла, поместите файл обратно в положение записи, которую вы хотите удалить, и перезапишите еес содержимым последней записи, которую вы только что прочитали, затем обрежьте файл непосредственно перед последней записью файла.

...