Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   API de Windows (https://www.clubdelphi.com/foros/forumdisplay.php?f=7)
-   -   Error para obtener el tamaño de archivo (https://www.clubdelphi.com/foros/showthread.php?t=86727)

jars 23-09-2014 15:34:58

Error para obtener el tamaño de archivo
 
Hola amigos.
Hace tiempo que estoy usando esta funcion para obtener el tamaño de un archivo desde un programa que corre como servicio.
El problema lo tengo con un cliente que lo esta ejecutando en una maquina virtual con Windows Server 2008 sp2 y la función en lugar de devolverme el tamaño me esta devolviendo una fecha.
En otras maquinas virtuales con el mismo SO no pasa.
Alguna pista?
Código Delphi [-]
function GetHugeFileSize(const name: string): Integer;
  var   a: TWin32FileAttributeData;
begin
  if (not GetFileAttributesEx(PChar(name), GetFileExInfoStandard, @a))
  or ((a.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) <> 0) then
    Result := -1
  else
    Result := a.nFileSizeLow;
end;
Gracias.

engranaje 23-09-2014 17:03:04

Lo cierto es que en estos casos suelo apuntar a que la api ha cambiado por una actualización del sistema o algo similar. Sin embargo he revisado:
http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx
y
http://msdn.microsoft.com/en-us/library/aa914683.aspx
Eencontrandome que la estructura de datos que devuelve GetFileAttributesEx cuando le pasas GetFileExInfoStandard no ha cambiado y en nFileSizeLowm debe tener lo que esperas.
Lo siento, me veo tan perdido como tu, mi recomendación es que averigues que destas obteniendo en a en el sistema en el que te esta pasando esto, ya que no parece que sea un WIN32_FILE_ATTRIBUTE_DATA

roman 23-09-2014 18:01:38

¿Cómo sabes que te devuelve una fecha? Es decir, tu función devuelve un entero, así que no sé cómo deduces que es una fecha. Por otro lado, esa función que implementaste siempre va a fallar con archivos muy grandes porque te estás olvidando de nFileSizeHigh.

// Saludos

nlsgarcia 23-09-2014 19:14:54

jars,

Cita:

Empezado por jars
...estoy usando esta función para obtener el tamaño de un archivo desde un programa que corre como servicio...un cliente que lo esta ejecutando en una maquina virtual con Windows Server 2008 SP2...en lugar de devolverme el tamaño me esta devolviendo una fecha...

:rolleyes:

Revisa este código:
Código Delphi [-]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  function GetFileSizeEx(hFile: THandle; var FSize: Int64): boolean; stdcall;
                         external 'Kernel32.dll' name 'GetFileSizeEx';

var
  Form1: TForm1;

implementation

{$R *.dfm}

function GetFileSize1(FileName : String) : Int64;
var
   F : File of Byte;
begin
   try
      FileMode := fmOpenRead;
      AssignFile(F, FileName);
      Reset(F);
      Result := FileSize(F);
      CloseFile(F);
   except
      Result := -1;
   end;
end;

function GetFileSize2(FileName : String) : Int64;
var
   F : TFileStream;
begin
   try
      F := TFileStream.Create(FileName,fmOpenRead,fmShareDenyNone);
      Result := F.Size;
      F.Free;
   except
      Result := -1;
   end;
end;

function GetFileSize3(const FileName: string): Int64;
var
   F: THandle;
begin
   try
      F := CreateFile(PChar(FileName), 0, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
      if F = INVALID_HANDLE_VALUE then
      begin
         Result := -1;
         Exit;
      end;
      Result := GetFileSize(F,nil);
      CloseHandle(F);
   except
      Result := -1;
   end;
end;

function GetFileSize4(const FileName: string): Int64;
var
   SR : TSearchRec;
begin
   try
      if FindFirst(FileName, faAnyFile, SR ) <> 0 then
      begin
         Result := -1;
         Exit;
      end;
      Result := SR.Size;
      FindClose(SR);
   except
      Result := -1;
   end;
end;

function GetFileSize5(const FileName: string): Int64;
var
   F : THandle;
begin
   try
      F := FileOpen(FileName, fmOpenRead);
      Result := FileSeek(F,0,2);
      FileClose(F);
   except
      Result := -1;
   end;
end;

function GetFileSize6(const FileName: string): Int64;
var
   F : THandle;
begin
   try
      F := FileOpen(FileName, fmOpenRead);
      if not GetFileSizeEx(F, Result) then
         Result:= -1;
      FileClose(F);
   except
      Result := -1;
   end;
end;

function GetFileSize7(const FileName: string): Int64;
var
   FindData : TWin32FindData;
begin
   Windows.FindClose(FindFirstFile(PChar(FileName), FindData));
   Result := FindData.nFileSizeHigh shl 32 or FindData.nFileSizeLow;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
   openDialog : TOpenDialog;
   FileName : String;
   MsgUser : String;

begin

   openDialog := TOpenDialog.Create(self);
   openDialog.InitialDir := GetCurrentDir;
   openDialog.Options := [ofFileMustExist];
   openDialog.Filter := 'Files |*.*';

   if openDialog.Execute then
   begin
      FileName := openDialog.FileName;

      MsgUser := Format('GetFileSize1 : %s, Size = %d',[FileName, GetFileSize1(FileName)]);
      MessageDlg(MsgUser,mtInformation,[mbOK],0);

      MsgUser := Format('GetFileSize2 : %s, Size = %d',[FileName, GetFileSize2(FileName)]);
      MessageDlg(MsgUser,mtInformation,[mbOK],0);

      MsgUser := Format('GetFileSize3 : %s, Size = %d',[FileName, GetFileSize3(FileName)]);
      MessageDlg(MsgUser,mtInformation,[mbOK],0);

      MsgUser := Format('GetFileSize4 : %s, Size = %d',[FileName, GetFileSize4(FileName)]);
      MessageDlg(MsgUser,mtInformation,[mbOK],0);

      MsgUser := Format('GetFileSize5 : %s, Size = %d',[FileName, GetFileSize5(FileName)]);
      MessageDlg(MsgUser,mtInformation,[mbOK],0);

      MsgUser := Format('GetFileSize6 : %s, Size = %d',[FileName, GetFileSize6(FileName)]);
      MessageDlg(MsgUser,mtInformation,[mbOK],0);

      MsgUser := Format('GetFileSize7 : %s, Size = %d',[FileName, GetFileSize7(FileName)]);
      MessageDlg(MsgUser,mtInformation,[mbOK],0);
   end
   else
   begin
      MsgUser := 'No se Selecciono Ningún Archivo';
      MessageDlg(MsgUser,mtInformation,[mbOK],0);
   end;

   openDialog.Free;

end;

end.
El código anterior en Delphi 7 sobre Windows 7 Professional x32, obtiene el tamaño de un archivo por diferentes métodos.

Nota: El código fue probado en los siguientes entornos

1- Una máquina física con Windows 7 Profesional x32.

2- Una VMware con Windows 8.1 Professional x32.

3- Una VMware con Windows 7 Professional x64.

En todos los casos de prueba, el código del ejemplo funciono correctamente según lo esperado.

Espero sea útil :)

Nelson.

ecfisa 23-09-2014 20:18:23

Hola jars.

También te podría interesar revisar este hilo: Filesize ficheros grandes

Saludos :)


La franja horaria es GMT +2. Ahora son las 05:01:19.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi