DataSet.WriteXML при закрытии приложения и выключении PC
От: Aogore Россия no
Дата: 01.07.08 19:35
Оценка:
Есть реальное приложение, в котором XML файлы используются как база данных. Данные записываются при помощи DataSet.WriteXML. При закрытии приложения или выключении компьютара в момент записи данных данные повреждаются. Ниже написал тестовое приложение на эту тему. Как можно сделать так, чтобы данные либо записывались полностью, либо оставался старый файл? Помогите, пожалуйста, ничего не могу найти на эту тему, все уже обыскал.

class Program
{
static void Main(string[] args)
{
MyDataSet myDataSet = new MyDataSet();
int max = 100000;
Console.WriteLine("Writing...");
for (int i = 0; i < max; i++)
{
MyDataSet.MyDataTableRow newRow =
myDataSet.MyDataTable.NewMyDataTableRow();
newRow.Id = i;
myDataSet.MyDataTable.Rows.Add(newRow);
}
myDataSet.WriteXml(@"C:\Temp\1.xml");
Console.WriteLine("Writing completed!");
}
}
Re: DataSet.WriteXML при закрытии приложения и выключении PC
От: Александр Кузнецов Россия  
Дата: 02.07.08 04:54
Оценка: 3 (2) +1
Здравствуйте, Aogore, Вы писали:

A>Есть реальное приложение, в котором XML файлы используются как база данных. Данные записываются при помощи DataSet.WriteXML. При закрытии приложения или выключении компьютара в момент записи данных данные повреждаются. Ниже написал тестовое приложение на эту тему. Как можно сделать так, чтобы данные либо записывались полностью, либо оставался старый файл? Помогите, пожалуйста, ничего не могу найти на эту тему, все уже обыскал.


Пиши во временный файл, а потом переименовывай его в тот, который является основным файлом базы. Тогда даже если питание отключится в момент записи, оригинальный файл останется целым.
"Пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живете". (с) Макконнелл, "Совершенный код".
Re: DataSet.WriteXML при закрытии приложения и выключении PC
От: _FRED_ Черногория
Дата: 02.07.08 06:59
Оценка: 3 (1)
Здравствуйте, Aogore, Вы писали:

A>Есть реальное приложение, в котором XML файлы используются как база данных. Данные записываются при помощи DataSet.WriteXML. При закрытии приложения или выключении компьютара в момент записи данных данные повреждаются. Ниже написал тестовое приложение на эту тему. Как можно сделать так, чтобы данные либо записывались полностью, либо оставался старый файл? Помогите, пожалуйста, ничего не могу найти на эту тему, все уже обыскал.


Пусть есть файл A.txt со старыми данными
  1. Сохраняешь новые данные в файл A_temp.txt /* названия файлов, конечно же, условные */
  2. Переименовываешь оригинальный файл A.txt в A_backup.txt
  3. Переименовываешь файл с новыми данными A_temp.txt в файл с нужным именем A.txt
  4. Удаляешь бэкап A_backup.txt
... << RSDN@Home 1 alpha 3 rev. 0>>
Help will always be given at Hogwarts to those who ask for it.
Re: DataSet.WriteXML при закрытии приложения и выключении PC
От: Аноним  
Дата: 02.07.08 17:25
Оценка:
Написал extension методы для DataSet-a, может кому сгодится:

public static class DataSetExtension
{
public static void WriteSafely(this DataSet dataSet, string dataSetPath)
{
string extension = Path.GetExtension(dataSetPath);
if (extension == ".tmp" || extension == ".bak")
{
throw new ArgumentException(string.Format("Extension {0} is not supported", extension));
}
string tempPath = Path.ChangeExtension(dataSetPath, ".tmp");
string bakPath = Path.ChangeExtension(dataSetPath, ".bak");
if (File.Exists(tempPath))
{
File.Delete(tempPath);
}
dataSet.WriteXml(tempPath);
if (File.Exists(bakPath))
{
File.Delete(bakPath);
}
if (File.Exists(dataSetPath))
{
File.Move(dataSetPath, bakPath);
}
File.Move(tempPath, dataSetPath);
File.Delete(bakPath);
}

public static void ReadSafely(this DataSet dataSet, string dataSetPath)
{
string extension = Path.GetExtension(dataSetPath);
if (extension == ".tmp" || extension == ".bak")
{
throw new ArgumentException(string.Format("Extension {0} is not supported", extension));
}
if (File.Exists(dataSetPath) == false)
{
string bakPath = Path.ChangeExtension(dataSetPath, ".bak");
string tempPath = Path.ChangeExtension(dataSetPath, ".tmp");
if (File.Exists(bakPath))
{
File.Copy(bakPath, dataSetPath);
File.Delete(bakPath);
}
if (File.Exists(tempPath))
{
File.Delete(tempPath);
}
}
dataSet.ReadXml(dataSetPath);
}
}
Re[2]: DataSet.WriteXML при закрытии приложения и выключении
От: _FRED_ Черногория
Дата: 02.07.08 17:41
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Написал extension методы для DataSet-a, может кому сгодится:


Извини, не удержался

Во-первых, код надо выделять тегами
[c#]
А>    public static class DataSetExtension
А>    {
А>        public static void WriteSafely(this DataSet dataSet, string dataSetPath)
А>        {
А>            string extension = Path.GetExtension(dataSetPath);
              // Строковые литералы, тем более, повторённые несколько раз, так и напрашиваются в константы
А>            if (extension == ".tmp" || extension == ".bak") 
А>            {
А>                throw new ArgumentException(string.Format("Extension {0} is not supported", extension));
А>            }
А>            string tempPath = Path.ChangeExtension(dataSetPath, ".tmp");
А>            string bakPath = Path.ChangeExtension(dataSetPath, ".bak");
              // Старые "времянки" я бы попробовал поудалять ещё до сохранения - если удаление не пройдёт, то и сохранять не надо
А>            if (File.Exists(tempPath))
А>            {
А>                File.Delete(tempPath);
А>            }
А>            dataSet.WriteXml(tempPath);
А>            if (File.Exists(bakPath))
А>            {
А>                File.Delete(bakPath);
А>            }
А>            if (File.Exists(dataSetPath))
А>            {
А>                File.Move(dataSetPath, bakPath);
А>            }
А>            File.Move(tempPath, dataSetPath);
А>            File.Delete(bakPath);
А>        }

А>        public static void ReadSafely(this DataSet dataSet, string dataSetPath)
А>        {
А>            string extension = Path.GetExtension(dataSetPath);
А>            if (extension == ".tmp" || extension == ".bak")
А>            {
А>                throw new ArgumentException(string.Format("Extension {0} is not supported", extension));
А>            }
              // Не красиво сравнивать выражение, имеющее логический с одним из литералов true\false
              // Достаточно простого "if (File.Exists(dataSetPath))"
А>            if (File.Exists(dataSetPath) == false)
А>            {
А>                string bakPath = Path.ChangeExtension(dataSetPath, ".bak");
А>                string tempPath = Path.ChangeExtension(dataSetPath, ".tmp");
А>                if (File.Exists(bakPath)) // А, вообще, про чтение, см. ниже
А>                {
А>                    File.Copy(bakPath, dataSetPath);
А>                    File.Delete(bakPath);
А>                }
А>                if (File.Exists(tempPath))
А>                {
А>                    File.Delete(tempPath);
А>                }
А>            }
А>            dataSet.ReadXml(dataSetPath);
А>        }
А>    }
[/c#]

Мне кажется не очень хорошей идея "молчаливого" чтения некоего ".bak"-а и замена им основной версии файла. хорошей практикой тут было бы сказать пользователю "Возможно последнее сохранение было не успешным. Сделать то-то и то-то?" (На что именно заменить "Сделать то-то и то-то" лучще спросить в usability) и заменять что-то на что-то только по явной команде человека.
Help will always be given at Hogwarts to those who ask for it.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.