Блочное сохранение в типизированный файл

Уважаемый Сергей ! Добрый день !

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

Писать можно (нужно) director@ces.co.cu С уважением, Игорь К ЛЕОНОВ

1 лайк

BlockFileOfT в целом готов, но если чего то не хватает - могу добавить в любой момент, только скажите чего.

А почему не сюда писать? И - для начала объясните при чём тут энергия, хоть зелёная, хоть красная. А то звучит подозрительно.

ДД, Сергей Контакт взят тут

поэтому и пишу сюда. Давайте через director@ces.co.cu.

  1. Я уже поднимал данный вопрос, но Issue с ним была очень быстро закрыта. Пример кода:
    private static constructor :=
    try
      TestForRefT(typeof(T));
      sz := Marshal.SizeOf&<T>;
    except
      on e:Exception do
      begin
        MessageBox(new System.IntPtr(nil),
          e.ToString,
          $'BlockFileOf<{typeof(T)}> не может инициализироваться:',
          $10
        );
        Halt(-1);
      end;
    end;

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

  1. И ещё. Цитата отсюда:

Только file of T не используйте, он устарел.

Насколько мне известно, разработчики этого не говорили публично. Максимум - тут было сказано:

Добавлен экспериментальный модуль для быстрой работы с типизированными файлами BlockFileOfT (разработчик Латченко Сергей aka @Sun_Serega)

Как экспериментальный модуль может что-то заменить? На мой взгляд, решать за разработчиков ещё до их оглашения реальной ситуации публично - наглость. Это - их проект и им решать когда что-то созданное ими устаревает. Даже если у Вас действительно лучше, чем у них, получилось что-то реализовать. Впрочем, не первый раз уже. Сообщать пользователям о том, что какой-то компонент устарел - обязанность разработчиков и они (и только они) ответственны за это.

Потому что статический конструктор. Попробуйте вызвать исключение в нём. Ловить неудобно (потому что вызваться может вообще много где). И даже если ловить - статический конструктор будет вызываться ещё и несколько раз, что ещё больше всё усложняет.

В теории - вроде как можно всё же использовать магию доменов чтоб ловить такие исключения. Но это лишнее усложнение, когда надо донести простую информацию. Обычно это сообщение будет показывать тогда, когда человек ещё не знает что ссылочные типы недопустимы, как в теме куберфорума на которую вы кинули ссыль дальше.
Поэтому информация должна быть максимально просто досягаема.

И в данном случае исключение не даёт преимуществ. Обычно основное преимущество - исключение можно поймать и обработать. Но если в шаблонный параметр передан неправильный (содержащий ссылки/указатели) тип - весь код принципиально неправильный и работать правильно не будет, даже если скипнуть ошибку.
Поэтому, хоть обычно это и было бы плохо - в этом случае показывать месседж бокс однозначно того стоит.

Ну и если уже давать кусок кода - лучше приводить сразу и вызываемые от туда подпрограммы:

    private static sz: integer;
    
    private static procedure TestForRefT(tt: System.Type);
    begin
      if tt = typeof(System.IntPtr) then exit; // IntPtr содержит 1 поле типа pointer. Но IntPtr это не указатель а число, с размером как у pointer
      
      if tt.IsClass then raise new System.InvalidOperationException($'Тип {tt} ссылочный.{#10}Ссылочные типы нельзя сохранять в типизированный файл');
      
      foreach var fi in tt.GetFields(
        System.Reflection.BindingFlags.GetField or
        System.Reflection.BindingFlags.Instance or
        System.Reflection.BindingFlags.Public or
        System.Reflection.BindingFlags.NonPublic
      ) do
        if not fi.IsLiteral then
          if fi.FieldType <> tt then // тип integer имеет поле типа integer, без этой строчки StackOverflowException
            TestForRefT(fi.FieldType);
    end;
    
    private static constructor :=
    try
      TestForRefT(typeof(T));
      sz := Marshal.SizeOf&<T>;
    except
      on e:Exception do
      begin
        MessageBox(new System.IntPtr(nil),
          e.ToString,
          $'BlockFileOf<{typeof(T)}> не может инициализироваться:',
          $10
        );
        Halt(-1);
      end;
    end;

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

Ну, добавлять данные на сайт я не могу, но (даже если не считать что я лучше знаю, когда моё творение готово), тесты доказывающие что BlockFileOf<T> лучше справляется со своей задачей (быть быстрым) выложены в общий доступ.

А в той теме куберфорума - производительность была очень важна. Поэтому цитата меня была вырвана из контекста.

Ошибка - есть ошибка, в любом случае программа либо бы падала, либо отображалось бы окно. В любом случае - пользователь бы увидел, что что-то пошло не так. Если же не увидел (или не захотел посмотреть) - это не Ваша проблема.

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

Покажите мне где об этом на сайте сказано или на форуме. Если не найдёте, то, извините, это Ваше личное мнение.

И всё-же, каким бы ни был хорошим Ваш модуль, пока официальной информации от разработчиков не было, что он - замена для file of T, то не надо вводить пользователей форума в заблуждение. Вы - сторонний разработчик, а не руководитель проекта, чтобы решать что устарело, а что - нет. Когда станете руководителем или официально будете признаны как член команды разработчиков, то тогда, уже, возможно, сможете так утверждать.

То, что Вы знаете - это лично Ваше дело, как разработчика модуля, и Ваше мнение, до тех пор пока оно не будет официально подтверждено. Представьте себе - к Вам в проект пришёл хороший разработчик и начал гнуть свою линию. Как бы Вы к этому отнеслись?

Единственное - Вы можете попросить разработчиков обратить внимание на данную проблему, чтобы они подтвердили или опровергнули, что Ваш модуль - замена file of T.

Более того, даже добившись официального признания file of T устаревшим, Вы не измените мир. Учебники, выходящие по Pascal не будут подстраиваться под Вас специально. На счёт книги @RAlex - не знаю, возможно, там есть упоминание о Вашем модуле, но в целом, это ни на что не повлияет, по крайней мере быстро ничего не изменится. Точнее - Вы будете настаивать на использовании своего модуля, а в школах и университетах будут давать совсем другое, это создаст некоторые проблемы для тех, кто будет применять Ваше творение. Это - относится не только к Вашему модулю, но и вообще к подобным “изобретениям”. И проблема вовсе не Вашем модуле, а в том, что учителя зачастую не хотят переучиваться и легче рассказывать уже отработанный материал. Но, разумеется, иметь козыря в кармане - хорошо.

Если действительно интересно, Вы всегда можете ее скачать, там формат - “правильный адобовский PDF” (он сделан при помощи Adobe Acrobat), так что в любом просмотрщике работает полноценный контекстный поиск. Набираете “экспериментальный” или “Serega” - и сразу Вам все станет ясно.

1 лайк

У меня ничего не нашлось. Искал также “BlockFileOf”. Просматривал в Adobe Acrobat Reader DC.

Верно. Потому что ничего там такого и нет. У меня информация только о том, что написано разработчиками и собственная библиотека NumLibABC. Иначе мне пришлось бы просить проверять и высказывать свое мнение разработчика каждого пакета и все бы тянулось еще дольше. То, что искали по имени метода - это правильно, потому что в книге приводятся тексты всех программ, поиск идет и в них.

1 лайк

Это звучит прикольно только если говорить про себя “это уже не моя проблема”. В данном случае я вижу что происходит на куберфоруме и отталкиваясь от моего опыта там - делаю так чтоб все, в том числе новички, могли сразу понять в чём проблема. А те кто будут знать что так нельзя - никогда и не получат эту ошибку.

Это уже додумывания. И исключение и месседжбокс - досягаемы.

Но исключения пишет в 1 строчке и внизу экрана, при чём большинство текста оказывается за-...-енным.

А месседжбокс суёт себя прямо в лицо, в середине экрана. Это более досягаемо.

Тесты которые может запустить чтоб удостоверится каждый желающий - это как раз не личное мнение.

То что я говорю что BlockFileOf<T> готов - это тоже не личное мнение. То что релиз проекта входит в стандартные модули - не значит что разработчики паскаля могут лучше меня знать о состоянии модуля.
Если я, как его главный и единственный разработчик не могу сказать что он готов, не согласовав с разработчиками паскаля - то разработчики паскаля так же не могут сказать что билд №n не может называться билдом №n, не согласовав с тем, у кого они покупали хостинг, куда заливали установщики билда. Это бред.

В итоге реальная придирка только к слову “устаревший”. Но о своём негативном отношении к file of T разработчики говорили ещё когда я делал BlockFileOf<T> (или, может, прямо до того… не помню). Поэтому ничего плохого в этом не вижу.

Нет, правильно - выдавать исключения, у Вас - ошибка. И «сувать прямо в лицо» - вообще не повод отказываться от исключения. Исключения тоже «суются прямо в лицо». Более того, внизу или нет - зависит от того как пользователь запускает программу и где находится окно с запущенной программой. Так что это - лишь слабая попытка оправдать ошибку в коде.

Почему тогда Microsoft не делает так, как Вы? У них, поверьте, больше источников информации, чем у Вас, и сил больше, чтобы решать данные вопросы. Если бы то, что Вы говорите действительно было доводом сделать MessageBox, то Microsoft, и не только так бы сделали.

Про тесты я ничего не говорил.

Сказать, что он готов - Вы можете, но говорить, что он замена file of T - нет, так что не надо передергивать. В данном случае Ваш модуль всего лишь альтернатива стандартному функционалу.

Говорили - но, что с того? Это - их право, но, пока они не сказали официально, что file of T - устаревший, он таковым не является.

Я уже сказал что это отдельный случай. Обычно месседжбокс плохо. Тут оправданно.

Вовсе нет. Если бы это было оправдано, то это использовалось бы не только у Вас. Приведите мне пример более менее серьёзного проекта, где это используется. Найдёте - Ваша взяла, так уж и быть, если нет, то извините. Не зря ведь разработчики при создании своих приложений могут ориентироваться на исходные коды иных проектов,к которым имеют доступ.

Другие проекты это как раз то что вообще ничего не значит. Как минимум потому что всё бывает первый раз.

Доказательство почему оправданно - приведено выше. Если не согласны, но можете только тыкать в другие проекты, а не объяснить конкретно - это таки лично ваши проблемы.

1 лайк

Вы далеко не первый, кто программирует. До Вас это делали уже много людей, и Вы скажете, что все они настолько глупые, что не догадались использовать MessageBox, вместо исключений? Более того, на что ссылаться, если не на работы других программистов? Когда мы пишем код мы должны опираться на опыт других программистов, сравнивать наше решение с другими и тогда мы многому научимся.

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

Пример проекта, пожалуйста. Вы заявили, что это правильно и оправдано, так покажите, что это не только у Вас. Иначе закрадываются сомнения о «правильности» Вашего решения. А сейчас всё выглядит так, что Вам просто лень менять код.

Я переписывал ту часть раза 3-5. В итоге провёл нормальное тестирование, что как выглядит, и закончил на том что сейчас.

Мне - без разницы, сколько и чего Вы там переписывали - это Ваше личное дело. Я жду ссылку на любой более-менее серьёзный и известный проект (не Ваш).

Блочное сохранение - авторский проект SunSerega - он может делать в нём всё что считает нужным.

Разумеется, единственный универсальный способ возбуждения и обработки ошибок в .NET - это исключения. Это одно из канонических главных достоинств .NET, которое было анонсировано в момент возникновения платформы в 2000 г. как единственная универсальная замена многочисленным способам реакции на ошибки, присутствовавшим в других API.

2 лайка

Разумеется, может. Только, file of T - Ваша разработка. Именно поэтому я указал на тот факт, что без Вашего слова решать за Вас устарел ли file of T он не может. Поэтому, если Вы проясните ситуацию обычным смертным - будет хорошо. Возможно, хорошо бы было также об этом написать на официальном сайте, всё-же быстрее найдут, чем среди множества сообщений.

1 лайк

Морально он вроде как бы устарел, поскольку на современных персоналках файлы любых мыслимых размеров, которые разумно в Паскале обрабатывать, проще прочитать в оперативную память целиком и обработать там. Но, с другой стороны, внутренняя организация таких файлов понятна, а альтернатива хранения данных - это только сериализация. Вот сериализацию объяснить новичку, да еще убедить его проштудировать .NET-документацию так, чтобы он смог воспользоваться этим. В текстовые файлы разгрузить в виде строк - это бредовая идея, вспоминая про различные кодировки: перенести файл куда-то может элементарно не получиться.Если вместо типизированных файлов разработчики включат в язык простые и понятные средства чтения-записи с сериализацией в UNICODE - вот тогда можно с чистой совестью записывать file of T в категорию “obsolete”

P.S. И да, если убрать file of T - после этого не получится решать в РАВС все еще предлагаемые старшеклассникам и студентам задачки на работу с типизированными файлами.

2 лайка