TextFile

lvilvi
отредактировано 16:15 Раздел: FastScript
Я реализовал работу со структурой TextFile следующим образом

unit Un_FsTextFile;

interface

implementation

uses SysUtils, Classes,
fs_iinterpreter, fs_itools;

type

TFunctions = class(TObject)
private
function CallMethod(Instance: TObject; ClassType: TClass;
const MethodName: String; var Params: Variant): Variant;
public
constructor Create;
destructor Destroy; override;
end;

PTextFile = ^TextFile;

var
Functions: TFunctions;
TextFileList: TList;

{ TFunctions }

constructor TFunctions.Create;
begin
TextFileList:= TList.Create;
with fsGlobalUnit do
begin
AddedBy:= Self;
AddType('TextFile',fvtInt);
AddMethod('proceudre AssignFile(var F: TextFile,FileName: string)',CallMethod,'ctFile');
AddMethod('procedure Rewrite(var F: TextFile)',CallMethod,'ctFile');
AddMethod('procedure CloseFile(var F: TextFile)',CallMethod,'ctFile');
AddMethod('procedure WriteLn(var F: TextFile;StrLine: string)',CallMethod,'ctFile');
AddedBy:= nil;
end;
end;

destructor TFunctions.Destroy;
begin
TextFileList.Free;
if fsGlobalUnit <> nil then
fsGlobalUnit.RemoveItems(Self);
inherited;
end;

function TFunctions.CallMethod(Instance: TObject; ClassType: TClass;
const MethodName: String; var Params: Variant): Variant;
var
ATextFile: PTextFile;
begin
if ClassType=nil then
begin
if MethodName='ASSIGNFILE' then
begin
New(ATextFile);
Params[0]:= TextFileList.Add(ATextFile);
AssignFile(ATextFile^,String(Params[1]))
end
else if MethodName='REWRITE' then
begin
ATextFile:= TextFileList.Items[Integer(Params[0])];
Rewrite(ATextFile^);
end
else if MethodName='CLOSEFILE' then
begin
ATextFile:= TextFileList.Items[Integer(Params[0])];
CloseFile(ATextFile^);
Dispose(ATextFile);
end
else if MethodName='WRITELN' then
begin
ATextFile:= TextFileList.Items[Integer(Params[0])];
WriteLn(ATextFile^,String(Params[1]));
end
end
end;

initialization
Functions := TFunctions.Create;

finalization
Functions.Free;

end.



Может есть другой вариантик , потому что , хоть и не сильно (практически нет), но засоряется лишними элементами TList , после закрытия файла - удалить не могу , так как работаю по номеру в TList

Комментарии

  • отредактировано 16:15
    Hi, lvi!
    А зачем тебе вообще эта экзотика с AssignFile и прочим WriteLn? Я, например, ей не пользовался кажись со времени ТурбоПаскаля. ИМХО TStringList и TxxxStream должно вполне хватать и гораздо удобнее. Обертки на все это в FS есть, если чего не хватает можно довернуть. Поправь меня, если я ошибаюсь ;)
  • lvilvi
    отредактировано 16:15
    Да экзотика - но ведь конечный эзвер - не экзотика - хорошо , если он прочитал хоть про эти методы - а чтобы ему ещё с потоками разобраться .
    Поправь если не такать.
  • lvilvi
    отредактировано 16:15
    И ещё - данная проблема с типами (например с TSearchRec в FindFirst) её пока вижу тоже только так обойти.
  • отредактировано 16:15
    Hi, lvi! Если такая необходимость искать файлы, почему не сделать обертку вроде:
     TSearchObj = class(TObject)
      private
        FSearchRec: TSearchRec;
        function GetDateTime: TDateTime;
        function GetTime: Integer;
        procedure SetDateTime(const Value: TDateTime);
        procedure SetTime(const Value: Integer);
      public
        function FindFirst(const Path: string; Attr: Integer): Integer;
        function FindNext: Integer;
        procedure FindClose;
        property Time: Integer read GetTime write SetTime;
        property DateTime: TDateTime read GetDateTime write SetDateTime;
    //аналогично остальные св-ва и методы необходимые и полезные,
    //например DateTime, да там еще кажись заморочка с локальным временем
      end;
    ...
    procedure TSearchObj.FindClose;
    begin
      SysUtils.FindClose(FSearchRec);
    end;
    function TSearchObj.FindFirst(const Path: string; Attr: Integer): Integer;
    begin
      Result := SysUtils.FindFirst(Path, Attr, FSearchRec);
    end;
    function TSearchObj.FindNext: Integer;
    begin
      Result := SysUtils.FindNext(FSearchRec);
    end;
    function TSearchObj.GetDateTime: TDateTime;
    begin
      Result := FileDateToDateTime(FSearchRec.Time);
    end;
    function TSearchObj.GetTime: Integer;
    begin
      Result := FSearchRec.Time;
    end;
    procedure TSearchObj.SetDateTime(const Value: TDateTime);
    begin
      FSearchRec.Time := DateTimeToFileDate(Value);
    end;
    procedure TSearchObj.SetTime(const Value: Integer);
    begin
      FSearchRec.Time := Value;
    end;
    
    Сделать соответствующую обертку для скрипта и выглядеть код скрипта может примерно так:
    var
      S: TSearchObj;
      FileAttrs: Integer;
    begin
      S := TSearchObj.Create;
      try
        FileAttrs := faAnyFile; // или что там нужно...
        if S.FindFirst('*.*', FileAttrs) = 0 then
        begin
          repeat
            if (S.Attr and FileAttrs) = S.Attr then
            begin
    //          S.Name ...
    //          S.Size ...
            end;
          until S.FindNext <> 0;
          S.FindClose;
        end;
      finally
        S.Free;
      end;
    
    Можно сделать предопределенный обьект в скрипте, чтоб не напрягать КОНЧЕННОГО(С) пользователя его созданием и уничтожением. Это неопробованное предложение, но думаю если понравится - ты доработаешь ;)
  • lvilvi
    отредактировано 16:15
    Спасибо за совет , что через класс сделать собственный я знаю , вся проблема состоит то в том , что потом писать на скрипте то буду не я , мне надо описать свои обьекты и методы. А юзвер как обычно читать не будет , а тока доставать как ?. Весь смысл , сделать кк можно приближённее к стандарту паскаля , чтобы если что его перенаправить к первоисточникам.
  • отредактировано 16:15
    Ну это тема философическая...
    Давай разберемся, что действительно нужно? Я не думаю, что у тебя стоит задача обучать юзеров стандартному паскалю, да и скажи на милость, что на нем можно сделать без добавления библиотечных ф-ций? Добавь необходимость минимального документирования этих ф-ций и отними отутствие струтур и прочие ограничения ФС...
    Скорей всего нужно решение задач из какой-то конкретной предметной области. Мы даем специалисту в данной области предметно-ориентированное, сверхвысокоуровневое, интуитивно понятное ему средство и все ОК. Пример - бизнесмену нужно узнать сколько получено прибыли за период, и он пишет на SQL почти как он писал бы на родном английском:
    select sum(profit) from sales where sales_date beween '01.01.04' and '31.03.04'
    Другой пример - бухгалтеру нужно развернутое сальдо и он пишет в 1С, почти как на родном русском:
    БухИтоги = СоздатьОбъект( "БухгалтерскиеИтоги);
    ДебСальдоНаНач = БухИтоги.СНДР("68");
    ДебСальдоНаКон = БухИтоги.СКДР("68");
    КрСальдоНаНач = БухИтоги.СНКР("68");
    КрСальдоНаКон = БухИтоги.СККР("68");
    
    Правда здорово? Ни хрена не здорово!!! Потому что, как только запрос чуть сложнее чем select * from приходится обращаться к программисту БД, а бухгалтера, прошедшие курсы программирования 1С рисуют процедуры ПриПроведении документа в 1000(!) строк, в которых черт ногу сломит на вложенных Если... Это кстати т.н. сверхвысокоуровневое программирование, да профи на ассемблере написал бы более компактный и структурированный код. Какой же выход? На деле имеем жесткое разделение труда - каждый должен заниматься своим делом и внятно ставить задачи для специалистов в других областях. Таким образом на стороне конечного пользователя видится 2 крайних варианта - 1) нашим софтом никто не занимается по причине отсутствия подходящих кандидатур, или же софт настолько безобразен в обслуживании 2) этим занимается вменяемый человек с алгоритмическим мышлением, понимающий суть проблем - по сути ПРОГРАММИСТ.
    В 1м случае или нас постоянно дергают или софт умирает сам собой, во 2м случае, при добротно написаном софте и минимальной поддержке с нашей стороны программист прекрасно со всем справится. 1 случай не рассматриваем, как писать для 2го? Да так, чтобы самим в 1ю очередь было удобно этим пользоваться, тогда есть шанс на долгую жизнь софта. Вот фаст-репортовцы молодцы - насколько я знаю ФР писался для своих нужд, и с ним работать можно, по крайней мере лучше, чем с кривым QuickReport'ом или Rave'ом. Таких примеров много - тот же РНР, UNIX вообще вырос из написания игры ;)
    Ну я нафлудил однако - накипело...))
    Возвращаясь к топику, ИМНО попытка калькирования в лоб стандартных паскалевских рутин, а тем более WinAPI не есть хорошо, да и средствами ФС не решаемо, а вот хорошо продуманные удобные обьекты-обертки облегчат жизнь и себе и ПОЛЬЗОВАТЕЛЯМ КОНЦА(С).
    (все права на вольный перевод end-user принадлежат автору, т.е мне - в т.ч варианты: ПОЛЬЗОВАТЕЛИ-ТЕРМИНАТОРЫ и просто ВРЕДОВАТЕЛИ 8-) )

Оставить комментарий

Многофункциональный текстовый редактор. Чтобы отредактировать стиль параграфа, нажмите TAB, чтобы перейти к меню абзаца. Там вы можете выбрать стиль. По умолчанию не выбран ни один стиль. Когда вы выберете текст, появится встроенное меню форматирования. Нажмите TAB, чтобы войти в него. Некоторые элементы, такие как многофункциональные вставки ссылок, картинок, индикаторов загрузки и сообщений об ошибок могут быть вставлены в редактор. Вы можете перемещаться по ним, используя стрелки внутри редактора и удалять с помощью клавиш delete или backspace.