Ошибка записи содержимого json в xrecord

Автор Тема: Ошибка записи содержимого json в xrecord  (Прочитано 2220 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн AtomohodАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 462
  • Карма: 1
Здравствуйте. Столкнулся с проблемой что после отработки метода записи содержимого json в xrecord файл при повторном открытии выдает сообщение о необходимости восстановления. Но почему так ума не приложу. Json 813 кб, 23000 строк.
Мой код:
Код - C# [Выбрать]
  1. public class JsonXRecordCommands
  2. {
  3.     [CommandMethod("StoreJsonInXRecord")]
  4.     public void StoreJsonInXRecord()
  5.     {
  6.    
  7.         string jsonFilePath = @"G:\DevProjects\a62488f5-29fe-4525-b6e2-eb8ac404e237.json";
  8.  
  9.         try
  10.         {
  11.             // Чтение JSON-файла и преобразование в байты
  12.             string jsonString = File.ReadAllText(jsonFilePath);
  13.             byte[] fullData = Encoding.UTF8.GetBytes(jsonString);
  14.             int chunkSize = 100 * 1024; // 100 КБ
  15.  
  16.             // Создание списка для хранения частей данных
  17.             List<TypedValue> typedValues = new List<TypedValue>();
  18.             for (int i = 0; i < fullData.Length; i += chunkSize)
  19.             {
  20.                 int length = Math.Min(chunkSize, fullData.Length - i);
  21.                 byte[] chunk = new byte[length];
  22.                 Array.Copy(fullData, i, chunk, 0, length);
  23.                 typedValues.Add(new TypedValue((int) DxfCode.BinaryChunk, chunk));
  24.             }
  25.  
  26.             // Создание ResultBuffer из списка частей
  27.             ResultBuffer rb = new ResultBuffer(typedValues.ToArray());
  28.             Database db = Application.DocumentManager.MdiActiveDocument.Database;
  29.  
  30.             // Сохранение в XRecord
  31.             using (Transaction tr = db.TransactionManager.StartTransaction())
  32.             {
  33.                 DBDictionary nod = (DBDictionary) tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForWrite);
  34.                 string key = "MyJsonData";
  35.  
  36.                 ObjectId xrecId;
  37.                 if (nod.Contains(key))
  38.                 {
  39.                     xrecId = nod.GetAt(key);
  40.                 }
  41.                 else
  42.                 {
  43.                     Xrecord xrec = new Xrecord();
  44.                     nod.SetAt(key, xrec);
  45.                     tr.AddNewlyCreatedDBObject(xrec, true);
  46.                     xrecId = xrec.ObjectId;
  47.                 }
  48.  
  49.                 Xrecord xrec1 = (Xrecord) tr.GetObject(xrecId, OpenMode.ForWrite);
  50.                 xrec1.Data = rb;
  51.                 tr.Commit();
  52.             }
  53.         }
  54.         catch (Exception ex)
  55.         {
  56.             Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage($"Ошибка: {ex.Message}\n");
  57.         }
  58.     }
  59.  
  60.     [CommandMethod("RetrieveJsonFromXRecord")]
  61.     public void RetrieveJsonFromXRecord()
  62.     {
  63.         Database db = Application.DocumentManager.MdiActiveDocument.Database;
  64.         using (Transaction tr = db.TransactionManager.StartTransaction())
  65.         {
  66.             DBDictionary nod = (DBDictionary) tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead);
  67.             string key = "MyJsonData";
  68.  
  69.             if (nod.Contains(key))
  70.             {
  71.                 ObjectId xrecId = nod.GetAt(key);
  72.                 Xrecord xrec = (Xrecord) tr.GetObject(xrecId, OpenMode.ForRead);
  73.                 ResultBuffer rb = xrec.Data;
  74.  
  75.                 // Сбор всех частей данных
  76.                 List<byte> fullData = new List<byte>();
  77.                 foreach (TypedValue tv in rb.AsArray())
  78.                 {
  79.                     if (tv.TypeCode == (int) DxfCode.BinaryChunk)
  80.                     {
  81.                         byte[] chunk = (byte[]) tv.Value;
  82.                         fullData.AddRange(chunk);
  83.                     }
  84.                 }
  85.  
  86.                 // Преобразование в строку JSON
  87.                 string jsonString = Encoding.UTF8.GetString(fullData.ToArray());
  88.                 Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage($"JSON: {jsonString}\n");
  89.             }
  90.             else
  91.             {
  92.                 Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("XRecord не найден.\n");
  93.             }
  94.         }
  95.     }
  96. }


лог Автокад:
Подстановка [simplex.shx] вместо [CS_Gost2304.shx].
Выполняется регенерация модели.

Идет проверка объектов в таблице меток.
Правильных объектов: 237    Неправильных объектов: 0
Проверка объектов на правильность окончена.

    База данных чертежа спасена.

Проверка заголовка
Проверка таблиц
Проверка объектов, проход 1

Проход 1: проверено объектов: 200    AcDbXrecord(535)                  восстановлен.
Проверка объектов, проход 2
Проход 2: проверено объектов: 200
Проверка блоков
 Проверено блоков: 8

Проверка AcDsRecords


Всего найдено ошибок: 1, исправлено: 1

Стерто 0 объектов

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 563
  • Карма: 121
Но почему так ума не приложу
1. Попробуй добавить блокировку документа. Она нужна, если редактируешь Database.
2. ResultBuffer rb = new ResultBuffer(typedValues.ToArray()); возможно переполнение для Xrecord, ограничение вроде есть, поищи темы на форуме.
3. Если первые 2 пункта не помогли, можно попробовать следующее. Иногда бывает так, что если объект создан в транзакции, и транзакция не закрыта, то что-то не срабатывает при его модификации. Как правило это для множественного действия, когда в одной транзакции создал стиль таблицы, создал таблицу и пытаешься назначить ей новый стиль.
И если в какой-то версии автокада ошибка, можно попробовать разделить транзакции, в первой транзикции создать стиль, во второй таблицу и назначить стиль.

так ты добавляешь Xrecord, если его нет. tr.AddNewlyCreatedDBObject(xrec, true); а потом его открываешь в этой-же транзакции Xrecord xrec1 = (Xrecord) tr.GetObject(xrecId, OpenMode.ForWrite); можно попробовать после добавления tr.AddNewlyCreatedDBObject(xrec, true) закрыть транзацию tr.Commit(); сохранить ObjectId xrecId и затем открыть новую транзакцию на модификацию. Маловероятно, но если другое не помогло, можно попробовать.

Отмечено как Решение Atomohod 01-06-2025, 20:28:37

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13922
  • Карма: 1793
  • Рыцарь ObjectARX
  • Skype: rivilis
Длина DxfCode.BinaryChunk если мне не изменяет память 256 байт (байт длины и 255 байт данных). А ты пытаешься загнать в него 100K. Само собой будет ошибка.
https://adndevblog.typepad.com/autocad/2013/02/dxf-files-binary-chunk-interpretation.html
И еще мне непонятно зачем преобразовывать json в BinaryChank. Это же чисто текстовые данные, а не двоичные.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн AtomohodАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 462
  • Карма: 1
И еще мне непонятно зачем преобразовывать json в BinaryChank. Это же чисто текстовые данные, а не двоичные.
Я пытался сначала через Asciistring, но по неведомой причине при обратном извлечении из xrecord у меня постоянно не возвращались два последних знака json. На разных json. Загадка.