1
votes

I have some large files I need to process and would like to indicate to the user the file size as the processing may take a long time.

I am using David Heffernan's function (a BIG thanks there David) to get the size and it works just great.

function GetFileSize3(const FileName: string): Int64;
var
  fad: TWin32FileAttributeData;
begin
  if not GetFileAttributesEx(PChar(FileName), GetFileExInfoStandard, @fad) then
    RaiseLastOSError;
  Int64Rec(Result).Lo := fad.nFileSizeLow;
  Int64Rec(Result).Hi := fad.nFileSizeHigh;
end;

I then convert that to a string and store it and others in a StringList for later use.

When I try to convert it back to an Int64 value (myInt64:=StrToInt(slSize[j])) I get an error, "xxx is not an Integer" or something very close to that error.

I guess I should have used an Array of Record with Filename:String; Size:Int64; etc in the Record instead of using StringLists. Hindsight is wonderful, and it would now take a major re-write to use an Array of Records at this point.

I need a cheater's way to convert the very large StringList values back to an Int64 for the few files that are going to be outside the normal StrToInt( function that causes the error.

Anyone care to save my bacon? Thank you.

1

1 Answers

10
votes

Use StrToInt64 instead. (The link is to the current documentation, but the function exists in Delphi 7 as well, in the SysUtils unit.)

myInt64 := StrToInt64(slSize[j]);

Better yet, don't store it in a string in the first place. Store it in an Int64, and only convert it to a string when you need it in one (such as for displaying in a label). If you plan on using it as a number, store it as a number.

You can always create a small class that just contains an Int64, and store that in the TStringList.Objects along with the string that has the file name, and read it back from the Objects when you need the size. You could even add a property to that small class that handles the conversion to a string for when you need it.

type
  TFileSizeInfo = class(TObject)
  private
    FFileSize: Int64;
    function GetFileSizeAsString: string;
  public
    constructor Create(TheFileSize: Int64);
    property AsInt64: Int64 read FFileSize write FFileSize;
    property AsString: string read GetFileSizeAsString;
  end;

implementation

constructor TFileSizeInfo.Create(TheFileSize: Int64);
begin
  inherited Create;
  FFileSize := TheFileSize;
end;

function TFileSizeInfo.GetFileSizeAsString: string;
begin
  Result := IntToStr(FFileSize);
end;

Using it:

// Add to stringlist
var
  FileSizeInfo: TFileSizeInfo;
begin
  FileSizeInfo := TFileSizeInfo.Create(GetFileSize3(TheFleName);
  slSize.AddObject(TheFileName, FileSizeInfo);
end;

// Reading it back
var
  SizeAsInt64: Int64;
  SizeAsString: string;
begin
  SizeAsInt64 := TFileSizeInfo(slSize.Objects[Index]).AsInt64;
  SizeAsString := TFileSizeInfo(slSize.Objects[Index]).AsString;
end;

// Clearing your `TStringList` and its `Objects`
procedure ClearFileList(TheList: TStringList);
var
  i: Integer;
begin
  for i := 0 to TheList.Count - 1 do
    TheList.Objects[i].Free;
  TheList.Clear;
end;