2012-01-08 2 views
3

Как я могу лучше всего определить размер класса из памяти?Получение размера класса или объекта в том же формате, что и размер файла?

Вот базовый класс образца для работы с - Обратите внимание, что переменные не служат никакой другой цели, чем для примера:

type 
    TMyClass = class 
    public 
    fString1: string; 
    fString2: string; 
    fInteger1: Integer; 
    fInteger2: Integer; 

    constructor Create; 
    destructor Destroy; override; 
    end; 

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

Так что если я сохранил файл TMyClass в файле, а размер файла был 2.4kb, например, я хотел бы получить это значение, даже если файл не был на диске (получение размера из памяти).

Я искал и читал, прежде чем спрашивать здесь, это то, что я пытался до сих пор со смешанными результатами:

  • InstanceSize

    Использование TMyClass.InstanceSize в моем классе только когда-либо возвращается значение 12.

  • SizeOf

    Использование SizeOf (TMyClass) в моем классе только когда-либо возвращает значение 4.

Независимо возвращаемые значения I будет отформатирован в формат FileSize, такие как килобайт и мегабайт и т.д.

я должен делать что-то не так, потому что я знаю, что в моем классе используется более 12 (или 4) байтов данных. Я также знаю, что я ссылаюсь на правильный класс, это тот же класс, который я создаю и освобождаю в событиях Create Create and Destroy, а также во время выполнения.

Я пытаюсь сделать правильный путь, и если да, то должны ли мои примеры работать? Если они будут работать, я знаю, что мне нужно ближе взглянуть на мои фактические классы и объекты.

Грязный способ добиться этого - это сохранить мои классы объектов в файле, прочитать размер файла и затем удалить временный файл. Но мне не нравятся такие подходы, я думаю, что они грязные и быстрые. Цель состоит в том, чтобы прочитать размер моих классов из памяти, не прибегая к файлам сохранения и временного хранения и т. Д.

Я с нетерпением жду ваших советов и предложений.

+2

Пожалуйста, объясните, как сохранить файл на диск. Кроме того, 'TMyClass.InstanceSize' никогда не сможет вернуть 12 для кода в вопросе. Убедитесь, что код в вопросе совпадает с кодом, который вы используете. –

+0

публикуйте свои поля, и вы можете использовать RTTI и на основе типа (целое число, строка и т. Д.) Поля вы можете рассчитать размер, который класс будет использовать на диске. – ComputerSaysNo

+0

Если вы хотите (и имеете версию) использовать расширенный RTTI, это должно быть возможно сделать «из памяти». Тем не менее вам придется найти способ решить, следует ли подсчитывать (рекурсивно) ссылку на другой (агрегированный) экземпляр или нет. Если вы не можете или не хотите использовать расширенный RTTI, мы придумали структуру, в которой каждый класс регистрирует процесс SizeCalculation для использования «Калькулятор размера памяти». Просектор SizeCalculation знает, как обращаться со строками и какие экземпляры/интерфейсы ссылаются на подсчет (рекурсивно). –

ответ

9

Не знаете, как вы получили 12 для своего InstanceSize на таком классе. Это должно быть 20 (до D2009) или 24 (D2009 и более поздние). Причина, по которой она намного меньше фактического размера сохраненного файла, заключается в том, что строки не удерживаются в самом объекте; они являются ссылочными типами, реализованными как указатели на фактические строковые данные.

Ваш «грязный подход» находится на правильном пути. Практически единственный способ узнать, сколько дискового пространства вам нужно для такого объекта, это фактически сериализовать его. Но вам не нужно сохранять его на диск. Если вы в настоящее время сохраняете объект с помощью TFileStream (и вы должны быть, если это не так), вместо этого используйте TMemoryStream, который будет «сохранять» его в буфер памяти. Затем получите Size потока, и это сериализованный размер вашего объекта, без необходимости создавать и затем удалять временный файл.

+0

Я заработал, используя твою идею Мейсон. Мои объекты и классы являются потоковыми, поэтому используйте TMemoryStream .Size, как вы предлагали. благодаря –