2008-10-20 3 views

답변

10

그냥 웃음을 위해 ... 당신은 또한 스트림으로 이것을 할 수있다. 코드의 2 라인을 약간 넘는다. 일반적으로 경로를 포함하는 응용 프로그램 파일 이름은 Paramstr (0)에도 저장됩니다.

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

멋지게 완료되었습니다. 나는 당신의 대답이 모하메드 나스 만이나 저보다 더 읽기 쉽다고 생각합니다. – JosephStyons

2

불행히도 라이브러리를 사용하지 않고 한 줄 또는 두 줄의 코드만으로는 그렇게 할 수 없습니다.

쉬운 부분은 응용 프로그램의 exe 파일을 가져 오는 중입니다. 당신은 파일 크기를 검색하기위한 몇 가지 가능성이 있습니다 그것은 일반적으로

Application.ExeName에서 찾을 수 있습니다

  1. 열기 파일 및 스트림의 크기를 참조하십시오. 이것은 '이전'델파이 함수 FileOpenFileSize, 또는 TFileStream (size 속성 사용) 또는 Win32 API 함수 CreateFileGetFileSize 함수를 사용하여 수행 할 수 있습니다. (플랫폼 의존!) 읽기 전용 액세스로 파일을 열 었는지 확인하십시오.
  2. 순수 Win32 환경에서는 FindFirst을 사용하여 파일 크기를 가져올 수 있습니다. TSearchRec.FindData.nFileSizeLow에서 읽을 수 있습니다. 2GB가 넘는 파일을 준비하려면 nFileSizeHigh 부분을 사용해야합니다.
  3. Delphi.NET에서이 같은 System.IO.FileInfo을 사용할 수 있습니다 FileInfo.Create(filename).Length (한 줄)
  4. 리눅스에서 당신이 lstat64 기능 (단위 Libc)를 사용할 수 있습니다 및 TStatBuf64.st_size에서 크기를 얻을. 에서

을 (두 라이너는 변수 선언을 계산하지 않는 경우) JCL library 주어진 파일 이름의 파일 크기를 반환하는 간단한 기능을 포함하여 많은 유용한 기능을 찾을 수 있습니다. 당신이 시도 할 수

+0

이 최상위 투표 대답 왜 몰라하여. 이 게시물에는 네이티브 Delphi VCL 명령 만 사용하여이를 수행하는 방법에 대한 몇 가지 예가 포함되어 있습니다. – JosephStyons

2

(그것은 주어진 플랫폼에 맞는 방법을 사용) :
네프 탈리

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

===============을

+2

"try..finally"의 처음 두 줄을 래핑하고 FindClose를 "finally"부분에 넣으십시오. 그게 더 안정적입니다. – onnodb

2

스트림은 또한 TFileStream을 변수없이 사용할 수 있습니다

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

이 미운 네.

DSiWin32에서 DSiFileSize를 사용하는 것이 좋습니다. 내부적으로 CreateFile을 사용합니다.

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

크기는 작지만 핸들이 필요하지 않습니다. 나는 이것을 자신의 크기를 알아야하는 모든 "SFX"아카이브와 프로그램에서 사용합니다. IIRC는 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

왜 다른 접근 방식보다 더 나아야합니까? Windows에는 핸들이 부족하지 않습니다 ... – gabr

+1

Simple. 핸들은 이미 할당되어 있습니다 (지점 1). 응용 프로그램의 데이터 뒤에 데이터가 추가 된 경우에도 응용 프로그램의 크기를 알 수 있습니다. 이것은 매우 중요 할 수 있습니다! –

+0

두 번째 요점이 유효합니다. 동의합니다. – gabr

4

향후 호환성을 위해 가능한 경우 포인터 또는 Windows API 함수가 필요없는 구현을 선택해야합니다. skamradt가 제공하는 TFileStream 기반 솔루션은 나에게 잘 어울립니다.

하지만 ... 루틴의 코드가 1 행인지 10 행인지는 걱정하지 않아도됩니다. 어쨌든 파일 이름을 매개 변수로 사용하고 Int64를 반환하는 함수에 캡슐화 할 것이므로, 다시 사용할 수있는 코드의 개인 라이브러리에 저장하십시오. 그러면 다음과 같이 호출 할 수 있습니다.

GetMyFileSize (Application.ExeName);

0

내가 skamradt에서 제공하는 코드를 수정하고 싶습니다 만들기 위해 그것을하기 때문에, 당신이 ;-)

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

을 요청하지만 skamradt 쓴 로 코드를 사용하는 것을 선호하는 것처럼 두 줄의 코드 더 안전하다.

0

나는 할 수있다. 크기는 바이트로 설정되어 있으므로, 킬로바이트, 분할에 대한 1024

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

체크 아웃 this link.

+0

이것이 왜 부정 투표를 정당화했는지 확신 할 수 없습니다. 누군가이 코드와 관련된 특정 문제를 지적 할 수 있습니까? – JosephStyons

+2

TFileStream을 다시 해제하지 않았기 때문일 수 있습니다. – Jeff

2
uses IdGlobalProtocols; 

var 
    ExeSize: Int64; 
begin 
    ExeSize := FileSizeByName(ParamStr(0)); 
    // or 
    ExeSize := FileSizeByName(Application.ExeName); 
end; 
관련 문제