2008-10-20 21 views

Respuesta

10

Justo para sonreír ... también puedes hacer esto con transmisiones Solo un poco más de 2 líneas de código. En general, el nombre del archivo de la aplicación, incluida la ruta, también se almacena en Paramstr (0).

var 
    fs : tFilestream; 
begin 
    fs := tFilestream.create(paramstr(0),fmOpenRead or fmShareDenyNone); 
    try 
    result := fs.size; 
    finally 
    fs.free; 
    end; 
end; 
+0

Bien hecho. Creo que tu respuesta es más legible que la de Mohammed Nasman o la mía. – JosephStyons

2

Desafortunadamente no es posible hacer eso con solo una o dos líneas de código sin usar alguna biblioteca.

La parte fácil es obtener el archivo exe de la aplicación. Lo puede encontrar en Application.ExeName

En general hay varias posibilidades para recuperar el tamaño de archivo:

  1. Abrir el archivo y lee el tamaño de la secuencia. Esto se puede lograr usando las 'viejas' funciones Delphi FileOpen y FileSize, o con TFileStream (use la propiedad size) o con las funciones de API de Win32 CreateFile y GetFileSize función. (¡Depende de la plataforma!) Asegúrese de abrir el archivo con acceso de solo lectura.
  2. En un entorno Win32 puro, puede usar FindFirst para obtener el tamaño del archivo. Puede leerlo desde TSearchRec.FindData.nFileSizeLow. Si desea estar preparado para archivos de más de 2 GB (debe serlo), también debe usar la parte nFileSizeHigh.
  3. En Delphi.NET puede utilizar el System.IO.FileInfo, así: FileInfo.Create(filename).Length (de una sola línea)
  4. en Linux Puede utilizar la función lstat64 (Unidad Libc) y obtener el tamaño de TStatBuf64.st_size. (Revestimiento de dos si no cuentan la declaración de variables)

En el JCL library se pueden encontrar muchas funciones útiles, incluyendo una simple función que devuelve el tamaño de archivo de un nombre de archivo dado. (Se utiliza un método que se adapte a la plataforma dada)

+0

No sé por qué esta es la respuesta con más votos. Esta publicación contiene varios ejemplos de cómo hacerlo utilizando solo comandos Delphi VCL nativos. – JosephStyons

2

Puede probar esto:

if FindFirst(ExpandFileName(Application.exename), faAnyFile, SearchRec) = 0 then 
    MessageDlg(Format('Tamaño: <%d>',[SearchRec.Size]), mtInformation, [mbOK], 0); 
    FindClose(SearchRec); 

===============
Neftalí

+2

Intenta envolver las dos primeras líneas en un "try..finally" y coloca FindClose en la parte "finally". Eso es más confiable. – onnodb

2

corrientes también se puede utilizar sin una variable TFileStream:

with TFilestream.create(paramstr(0), fmOpenRead or fmShareDenyNone) do 
    aFileSize := Size; 
    Free; 
end; 

feo, sí.

Prefiero usar DSiFileSize desde DSiWin32. Utiliza CreateFile internamente:

function DSiFileSize(const fileName: string): int64; 
var 
    fHandle: DWORD; 
begin 
    fHandle := CreateFile(PChar(fileName), 0, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 
    if fHandle = INVALID_HANDLE_VALUE then 
    Result := -1 
    else try 
    Int64Rec(Result).Lo := GetFileSize(fHandle, @Int64Rec(Result).Hi); 
    finally CloseHandle(fHandle); end; 
end; { DSiFileSize } 
5

No es tan pequeño como desee, pero no necesita asas. Utilizo esto en todos mis archivos y programas "SFX" que deben conocer su tamaño. IIRC requiere la unidad de Windows.

function GetExeSize: cardinal; 
var 
    p: pchar; 
    i, NumSections: integer; 
const 
    IMAGE_PE_SIGNATURE = $00004550; 
begin 
    result := 0; 
    p := pointer(hinstance); 
    inc(p, PImageDosHeader(p)._lfanew + sizeof(dword)); 
    NumSections := PImageFileHeader(p).NumberOfSections; 
    inc(p,sizeof(TImageFileHeader)+ sizeof(TImageOptionalHeader)); 
    for i := 1 to NumSections do 
    begin 
    with PImageSectionHeader(p)^ do 
     if PointerToRawData+SizeOfRawData > result then 
     result := PointerToRawData+SizeOfRawData; 
    inc(p, sizeof(TImageSectionHeader)); 
    end; 
end;
+0

¿Por qué debería ser mejor que otros enfoques? No hay escasez de controladores en Windows ... – gabr

+1

Simple. El identificador ya está asignado, punto 1, y aún mejor, esto le indica el tamaño de la aplicación, incluso si tiene datos agregados detrás de los datos de la aplicación. ¡Esto puede ser extremadamente importante de saber! –

+0

El segundo punto es válido, estoy de acuerdo. – gabr

4

Por razones de compatibilidad en el futuro, usted debe elegir una aplicación que no requiere punteros o funciones API de Windows siempre que sea posible. La solución basada en TFileStream proporcionada por skamradt se ve bien para mí.

Pero ... No debe preocuparse demasiado si la rutina es de 1 o 10 líneas de código, porque de todos modos va a encapsularlo en una función que toma un nombre de archivo como parámetro y devuelve un Int64, y póngalo en su biblioteca personal de código reutilizable. Entonces puede llamarlo así:

GetMyFileSize (Application.ExeName);

0

quisiera modificar el código proporcionado por skamradt, para que sea dos líneas de código como usted pidió ;-)

with tFilestream.create(paramstr(0),fmOpenRead or fmShareDenyNone) do 
    ShowMessage(IntToStr(size)); 

pero yo preferiría utilizar el código como skamradt escribió, porque es más seguro

0

Lo más corto que pude hacer. Tenga en cuenta que la Clasifique es en bytes, por lo que para kilobytes, se divide por 1024.

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    with TFileStream.Create(Application.ExeName,fmShareDenyNone) do 
    ShowMessage(FloatToStr(Size/1024)); 
end; 

Salida this link.

+0

No estoy seguro de por qué esto justificó un voto negativo; ¿Alguien puede señalar un problema específico con este código? – JosephStyons

+2

Podría ser porque no está liberando el TFileStream nuevamente. – Jeff

2
uses IdGlobalProtocols; 

var 
    ExeSize: Int64; 
begin 
    ExeSize := FileSizeByName(ParamStr(0)); 
    // or 
    ExeSize := FileSizeByName(Application.ExeName); 
end; 
Cuestiones relacionadas