![]() |
Dateigröße auf Netzlaufwerk ermitteln
Hallo alle...
es ist ja bald Weihnachten und ich gebe Euch mal eine Nuß zu knacken... :-D Vorraussetzungen: -Firebird Datenbank auf Netzlaufwerk -vorhanden: Hostname -vorhanden: Pfad und Dateiname der Datenbank (lokaler Pfad) Ergebnis soll sein: -Dateigröße der Datenbank zu Infozwecken... versucht habe ich...
Delphi-Quellcode:
...funktioniert aber nur mit lokalen Pfadangaben. Das gleiche gilt für FileSize. :gruebel:
function GetFileSizeA(const FileName: String): Integer;
var SR: TSearchRec; begin Result := -1; if FindFirst(FileName, faAnyFile and not faDirectory, SR) = 0 then try Result := SR.Size; finally SysUtils.FindClose(SR) end; end; ...alle Beispiele und Lösungen, welche ich gefunden habe, beziehen sich alle auf FileSize oder GetFileSize. Welche Richtung würdet Ihr vorschlagen ? |
Re: Dateigröße auf Netzlaufwerk ermitteln
Hi,
wie kommst Du denn darauf, dass das nur mit lokalen Pfadangaben geht ? Allerdings hat Delphi 5 nur ein 32bit Cardinal im tSearchrecord für die Size. Könnte das für deine Datenbank zu klein sein ? Dann wirst Du auf die darin enthaltene Win32FindData zugreifen müssen, wo 64 bit zur Verfügung stehen. Schau dir mal den tSearchRecord und das darin enthaltene Win32FindData an. Gruss |
Re: Dateigröße auf Netzlaufwerk ermitteln
Wie hast du denn den Dateipfad angegeben?
\\Hostname\Drive:\Path\Filename.ext oder \\?\UNC\Hostname\Drive:\Path\Filename.ext |
Re: Dateigröße auf Netzlaufwerk ermitteln
...ich glaubs ja nicht... :wall:
ich hatte den Dateinamen mit \\Host\Freigabe\Pfad\Datei angegeben... Ergebnis 0 ...jetzt habe ich mal \\Hostname\Drive:\Path\Filename.ext ausprobiert... funktioniert :shock: ...warum geht das mit dem Freigabenamen nicht ? :gruebel: Danke an alle... :thumb: [edit] ... nehme alles zurück ! ...ich hatte im Quelltext zu Testzwecken noch statisch einen lokalen Pfad eingetragen. ---> auch \\Hostname\Drive:\Path\Filename.ext...Ergebnis 0 PS: ich habe gelesen, das FileSize nur lokal funktioniert. [/edit] |
Re: Dateigröße auf Netzlaufwerk ermitteln
... ich habe noch einmal verschiedene Beispiele ausprobiert... gleiches Ergebnis.
bei lokaler Pfadangabe wie c:\tmp\daten\test.fdb --> richtiges Ergebnis bei Padangabe wie \\server\system\tmp\daten\test.fdb oder \\server\c:\tmp\daten\test.fdb --> Ergebnis 0 Fazit: die Pfadangabe ist falsch :gruebel: :gruebel: aber ich seh´s nicht :roll: [edit] Zitat:
|
Re: Dateigröße auf Netzlaufwerk ermitteln
Was sagt denn GetLastError?
|
Re: Dateigröße auf Netzlaufwerk ermitteln
also...
bei der Funktion ...mit \\localhost\c:\tmp\avdb.fdb
Delphi-Quellcode:
... nach if direkt zu finaly ---> also Datei nicht gefunden. :wall:
function GetFileSizeA(const FileName: String): Integer;
var SR: TSearchRec; begin Result := -1; if FindFirst(FileName, faAnyFile and not faDirectory, SR) = 0 then try Result := SR.Size; finally SysUtils.FindClose(SR) end; end; bei der Funktion ...mit \\localhost\c:\tmp\avdb.fdb
Delphi-Quellcode:
... nach if not FileExists direkt exit ---> also Datei nicht gefunden. :wall:
function GetFileSize1(const szFile: String): Int64;
var fFile: THandle; wfd: TWIN32FINDDATA; begin result := 0; if not FileExists(szFile) then exit; fFile := FindFirstfile(pchar(szFile),wfd); if fFile = INVALID_HANDLE_VALUE then exit; result := (wfd.nFileSizeHigh*(MAXDWORD))+wfd.nFileSizeLow; windows.FindClose(fFile); end; ... mit c:\tmp\avdb.fdb ... bekomme ich den richtigen Wert. :wall: :?: ich weiß nicht weiter... :gruebel: [edit] GetLastError = 0 [/edit] |
Re: Dateigröße auf Netzlaufwerk ermitteln
GetLastError bringt bei FindFirst nichts, da diese Funktion bei Mißerfolg selbst intern GetLastError aufruft und dieses somit zurücksetzt.
Das ergebnis von GetLastError wird als Result zurückgeliefert, also was sagt denn FindFirst? |
Re: Dateigröße auf Netzlaufwerk ermitteln
Egal, jeden falls sollte der Rückgabewert mal ausgewertet werden.
|
Re: Dateigröße auf Netzlaufwerk ermitteln
...53 ---> Datei nicht gefunden.
...die Funktion kann mit dem Netzlaufwerkpfad nichts anfangen oder ? :gruebel: |
Re: Dateigröße auf Netzlaufwerk ermitteln
Also das sagt das DK dazu:
Zitat:
|
Re: Dateigröße auf Netzlaufwerk ermitteln
...was ist DK ? :oops:
..vieleicht ist es ja schon zu spät.. :wink: ich verstehe das Zitat nicht wirklich... :roll: Danke für Eure Hilfe... |
Re: Dateigröße auf Netzlaufwerk ermitteln
SDK / PSDK
> ![]() Nja, das Zitat sagt daß es eigentlich gehn sollte. Du könntest es nochmal mit der Unicode-Version der WinAPI-Funktion FindFistFile (FindFistFileW) versuchen. Vorallem bei den UNC-Namen arbeitet diese etwas anders als die ANSI-Version (FindFistFile/FindFistFileA). |
Re: Dateigröße auf Netzlaufwerk ermitteln
...nun ja ich sehe das genauso...
100 mal schon mit Netzlaufwerken, VPN via IP gearbeitet...keine Probleme. :???: ...darum :wiejetzt: ...aus Spaß habe ich mal eine FileListBox auf die Form gesetzt. Mit der Directory Angabe \\localhost\c:\tmp bekomme ich auch Fehler 53... :mrgreen: ...ist schon so traurig, daß es wieder zum Lachen ist... |
Re: Dateigröße auf Netzlaufwerk ermitteln
hatte grad nochwas in Beitrag #13 nachgetragen,
wie gesagt, du könntest es nochmals mit Unicode versuchen (direkt über die WinAPI oder eine UnicodeCodesammlung) Oder hast du mal vesucht andere/alle Dateien auf dem Zielrechner zu finden? z.B. \\host\c:\tmp\*.* |
Re: Dateigröße auf Netzlaufwerk ermitteln
...alles das gleiche in grün. :roll:
egal wie ich den File String zusammensetze. :( FindFirstFileW... damit muß ich mich erst etwas näher beschäftigen... :roll: |
Re: Dateigröße auf Netzlaufwerk ermitteln
Kurzfassung/Test:
Delphi-Quellcode:
Var FileName: WideString;
H: THandle; D: TWIN32FindDataW; Begin FileName := 'deine Datei oder ein Suchmuster'; H := FindFirstFileW(PWideChar(FileName), D); If H = INVALID_HANDLE_VALUE Then GetLastError_auswerten; {sonst alles ok} CloseHandle(H); |
Re: Dateigröße auf Netzlaufwerk ermitteln
... habe mir noch eimal die Namenskonvention angeschaut.
![]() ...eigentlich ist das richtig, was ich getrieben hab... :mrgreen: :wiejetzt: |
Re: Dateigröße auf Netzlaufwerk ermitteln
Ja wie gesagt: die ANSI-Dateifunktionen sind halt in einigen Dingen etwas eingeschränkt
und wenn du Glück hast, dann liegt es nur an soeiner Beschränkung. Wenn nicht, dann sieht es schon schwerer aus, da dieses ja eigentlich funktionieren sollte. |
Re: Dateigröße auf Netzlaufwerk ermitteln
...erst einmal Danke,Danke,Danke... :-D
Habe Deinen Tipp wie folgt angepaßt.
Delphi-Quellcode:
...Datei wird gefunden...aber die Größe stimmt nicht. :gruebel:
function GetFileSize2(const FileName: String): Int64;
var H: THandle; D: TWIN32FindDataW; begin H := FindFirstFileW(PWideChar(FileName), D); If H <> INVALID_HANDLE_VALUE then exit; //GetLastError_auswerten; result := (d.nFileSizeHigh*(MAXDWORD))+d.nFileSizeLow; CloseHandle(H); end; |
Re: Dateigröße auf Netzlaufwerk ermitteln
wie groß ist denn die Datei?
Delphi-Quellcode:
PS: * und + sind etwas langsam/unoptimal
function GetFileSize2(const FileName: String): Int64;
var H: THandle; D: TWIN32FindDataW; begin H := FindFirstFileW(PWideChar(FileName), D); If H = INVALID_HANDLE_VALUE then exit; //GetLastError_auswerten; result := (Int64(d.nFileSizeHigh)*(MAXDWORD + 1))+d.nFileSizeLow; CloseHandle(H); end; und bevor du versuchst einen Integer/Cardinal [d.nFileSizeHigh] (also 4 Byte) auf einen Int64 (8 Byte) zu erweitern, mußt die dessen Größe erstmal ändern (Int64)
Delphi-Quellcode:
oder
Function GetFileSizeA(Const FileName: String): Int64;
Var FileNameW: WideString; H: THandle; D: TWIN32FindDataW; Begin Result := -1; FileName := FileNameW; H := FindFirstFileW(PWideChar(FileName), D); If H = INVALID_HANDLE_VALUE Then Exit; If D.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY = 0 Then Result := (Int64(D.nFileSizeHigh) shl 32) or D.nFileSizeLow; CloseHandle(H); End;
Delphi-Quellcode:
PSS: was micht wundert ist, daß bei PWideChar(FileName) nicht gemeckert wird, vonwegen AnsiString-PWideChar-Konvertierung :shock:
Function GetFileSizeA(Const FileName: String): Integer;
Var FileNameW: WideString; H: THandle; D: TWIN32FindDataW; Begin Result := -1; FileName := FileNameW; H := FindFirstFileW(PWideChar(FileName), D); If H = INVALID_HANDLE_VALUE Then Exit; If (D.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY = 0) and (D.nFileSizeHigh = 0) and (D.nFileSizeLow < $80000000) Then Result := D.nFileSizeLow; CloseHandle(H); End; |
Re: Dateigröße auf Netzlaufwerk ermitteln
... 1.07 MB oder 1.122.304 Byte
|
Re: Dateigröße auf Netzlaufwerk ermitteln
hmmm, 1 MB paßt ja locker in einen Integer :gruebel: ,
was kommt denn raus? Zitat:
|
Re: Dateigröße auf Netzlaufwerk ermitteln
... 3.04 MB
PS: alles was du so als Lösungen hast mögen funktionieren...wenn ich die Details verstehen würde wäre es besser... :oops: |
Re: Dateigröße auf Netzlaufwerk ermitteln
...Guten Morgen alle... :hi:
...das hat mir alle keine Ruhe gelassen. ...inzwischen habe ich durch Zufall herausgefunden das mit folgendem Code
Delphi-Quellcode:
das Ergebnis immer gleich ist...(unterschiedliche Dateien/FileName) ! -5.41 MB... obwohl die kpl. Prozedur durchlaufen wird.
function GetFileSize2(const FileName: String): Integer;
var H: THandle; D: TWIN32FindDataW; begin H := FindFirstFileW(PWideChar(FileName),D); If H <> INVALID_HANDLE_VALUE then exit; //GetLastError_auswerten; result := (d.nFileSizeHigh*(MAXDWORD))- d.nFileSizeLow; CloseHandle(H); end; Warnung: Rückgabewert der Funktion könnte undefiniert sein... damit hat Delphi Recht !? :???: [edit] ich habe mit Set8087ControlWord($133F) den Gleitkommaüberlauf während der Ausführung meines Programmes ausgeschaltet. ...hat das in diesem Zusammenhang eine Relevanz ? ... Suche nach Strohhalm... :roll: [/edit] |
Re: Dateigröße auf Netzlaufwerk ermitteln
...mich wundert gar nichts mehr. :roll:
...die gleichen Probleme mit: DeleteFile('\\localhost\system\tmp\avdb.fdb'); FileExists('\\localhost\system\tmp\avdb.fdb'); :wall: ...Kann es wirklich sein, das diese Funktionen nicht mit Netzwerk umgehen können ? :gruebel: |
Re: Dateigröße auf Netzlaufwerk ermitteln
Zitat:
Also entweder am Anfang mit initialisieren:
Delphi-Quellcode:
Oder beim Verlassen der Funktion setzen:
H := FindFirstFileW(PWideChar(FileName),D);
If H = INVALID_HANDLE_VALUE then exit; //GetLastError_auswerten; result := ...
Delphi-Quellcode:
Result := Standard-/Fehlerwert;
H := FindFirstFileW(PWideChar(FileName),D); If H = INVALID_HANDLE_VALUE then begin Result := Standard-/Fehlerwert; exit; end; result := ... Zitat:
du könntest da auch höchstens versuchen Set8087ControlWord vorm Aufruf dieser Funktion zurück und nachher dann wiederauf $133F zu setzen.
Delphi-Quellcode:
Int64(d.nFileSizeHigh) > in einen Int64 konvertieren, damit auch Platz für das Vergrößern des Wertes vorhanden ist.
result := (Int64(d.nFileSizeHigh)*(MAXDWORD + 1))+d.nFileSizeLow;
*(MAXDWORD+1) > MAXDWORD ist nur $FFFFFFFF, aber damit der Wert in das Höherwertige LongWord verschoben wird, muß mit $0000000100000000 multiplizert werden, oder einfach die Bits des Wertes um 32 Bit (LongWord) nach oben verschieben > Int64(d.nFileSizeHigh) shl 32
Delphi-Quellcode:
oder
Function GetFileSizeA(Const FileName: String): Int64;
Var FileNameW: WideString; H: THandle; D: TWIN32FindDataW; Begin Result := -1; // Fehlerwert setzen (damit bei EXIT ein Wert gesetzt wurde) FileName := FileNameW; // Dateiname von String/Ansitring nach WideString übersetzen H := FindFirstFileW(PWideChar(FileName), D); // Datei suchen If H = INVALID_HANDLE_VALUE Then Exit; // im Fehlerfalls Funktion verlassen If D.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY = 0 Then // prüfen ob kein Verzeichnis Result := (Int64(D.nFileSizeHigh) shl 32) or D.nFileSizeLow; // wenn Datei, dann Result neu setzen // Int64(D.nFileSizeHigh) shl 32 > wandelt nFileSizeHigh in einen Int64 um // und verschiebt dessen Wert in das HiLongWord // or D.nFileSizeLow > fügt nFileSizeLow in das Regebnis als LoLongWord ein CloseHandle(H); // Suche schließen (wenn H = INVALID_HANDLE_VALUE, dann wurde sie nicht geöffnet) End;
Delphi-Quellcode:
PWideChar(FileName) > die Funktion FindFirstFileW braucht eine Referenz auf einen UnicodeString
Function GetFileSizeA(Const FileName: String): Integer;
Var FileNameW: WideString; H: THandle; D: TWIN32FindDataW; Begin Result := -1; // Fehlerwert setzen (damit bei EXIT ein Wert gesetzt wurde) FileName := FileNameW; // Dateiname von String/Ansitring nach WideString übersetzen H := FindFirstFileW(PWideChar(FileName), D); // Datei suchen If H = INVALID_HANDLE_VALUE Then Exit; // im Fehlerfalls Funktion verlassen If (D.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY = 0) // prüfen ob kein Verzeichnis and (D.nFileSizeHigh = 0) and (D.nFileSizeLow < $80000000) Then // prüfen ob die Größe in einen Integer reinpaßt Result := D.nFileSizeLow; // Ergebnis setzen (nur als Integer) CloseHandle(H); // Suche schließen (wenn H = INVALID_HANDLE_VALUE, dann wurde sie nicht geöffnet) End; und dafür muß FileName auch schon in Unicode, also als WideString vorliegen. und wenn du den String direkt übergiebst? (ohne Variable)
Delphi-Quellcode:
if not DeleteFileW('\\localhost\system\tmp\avdb.fdb') then
irgendwas := GetLastError; |
Re: Dateigröße auf Netzlaufwerk ermitteln
hab hier eben mal ein Laufwerk freigegeben und
bei DeleteFileW('\\localhost\D:\test.dat'); kommt das raus 83 = Der Netzwerkpfad wurde nicht gefunden. bei DeleteFileW('\\localhost\Daten\test.dat'); kommt 82 = Verbindung wurde nicht hergestellt, weil ein identischer Name bereits im Netzwerk vorhanden ist. Wählen Sie "System" in der Systemsteuerung, um den Computernamen zu ändern, und versuchen Sie es erneut. raus schon komisch, vorallem letzere Meldung versteh ich da irgendwie nicht ... ist doch schön, wenn es vorhanden ist :gruebel: [add] DeleteFileW('\\myPC\Daten\test.dat'); hat die Datei übrigend erfolgreich gelöscht :-D |
Re: Dateigröße auf Netzlaufwerk ermitteln
Hi,
also deine Probleme kann ich überhaupt nicht nachvollziehen
Delphi-Quellcode:
Werf mal ein TEdit ein TMemo und einen TButton auf ein Form.
unit Unit1;
interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) edFilename: TEdit; Button1: TButton; Memo1: TMemo; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.Button1Click(Sender: TObject); var sr: tSearchrec; ierr: integer; begin Memo1.Clear; ierr := FindFirst(edFilename.text, faAnyfile - faDirectory, sr); while ierr = 0 do begin if (sr.name <> '.') and (sr.name <> '..') then begin Memo1.Lines.Add(sr.name + ': sr.size=' + IntToStr(sr.size) + ', w32finddata.size=' + IntToStr(int64(sr.FindData.nFileSizeHigh) shl 32 + sr.FindData.nFileSizeLow)); end; ierr := FindNext(sr); end; FindClose(sr); end; end. Nenn das TEdit edFilename (warum ich das umbenannt hab, keine Ahnung) :-D Dann kannst du im Editfeld deinen Pfad eingeben, und auf den Button klicken, das Memo zeigt das Inhaltsverzeichnis mit den Dateigrößen aus dem Searchrecord und aus den Finddata. Ich hab das bei mir getestet und das funktioniert einwandfrei. Endweder ist deine Freigabe keine Freigabe, oder du hast keine Rechte auf dieser Freigabe. Das würde ich dann mal mit einem einfachen Dir in der Dos-Box testen. Mit \\localhost\ geht das nicht, das ist aber auch klar, da dein Rechner ja nicht localhost heist. Gib den lokalen Rechnernamen an, dann geht das wieder. Und nebenbei: der Laufwerksbuchstabe hat in einem UNC Pfad gar nix zu suchen. Gruss |
Re: Dateigröße auf Netzlaufwerk ermitteln
Moin Himitsu,
[quote)="himitsu"]bei DeleteFileW('\\localhost\D:\test.dat'); kommt das raus 83 = Der Netzwerkpfad wurde nicht gefunden. [/quote] Logisch, denn in dem Beispiel müsste die Freigabe D: lauten. Wenn Du eine UNC-Angabe machst, musst Du den Freigabenamen angeben, was im Falle von Laufwerk D: standardmässig D$ wäre (falls nicht jemand die administrativen Freigaben abgeschaltet hat. Noch was allgemeines: Ich stosse hier immer wieder auf die Zeile:
Delphi-Quellcode:
Das sollte wohl besser
if H <> INVALID_HANDLE_VALUE then exit;
Delphi-Quellcode:
heissen ;-)
if H = INVALID_HANDLE_VALUE then exit;
Sonst wird die Funktion immer verlassen, wenn ein gültiges Handle ermittelt wurde, und das Handle wird nicht wieder freigegeben. |
Re: Dateigröße auf Netzlaufwerk ermitteln
Hallo alle... :hi:
...und siehe da...es bewegt sich doch :-D
Delphi-Quellcode:
...den Vorschlag von Christian angepaßt --> Ergebnis richtig :firejump:
function GetFileSize2(const FileName: String): Integer; { TODO : Dateigröße ermitteln }
var SR: TSearchRec; ierr: integer; begin ierr := FindFirst(FileName, faAnyfile - faDirectory, sr); while ierr = 0 do begin if (sr.name <> '.') and (sr.name <> '..') then begin DGrosse:= SR.Size / 1048576; end; ierr := FindNext(sr); end; FindClose(sr); end; ... FileName Syntax: \\firma-server\system\tmp\avdb.fdb PS: diese Syntax habe ich auch mit den anderen Beispielen probiert... :gruebel: Danke erst einmal... jetzt muß ich mir überlegen, wie ich an den Freigabenamen des lokalen Ordners komme, da der User nur den lokalen DatenbankPfad eingibt. bis bald...Danke :hi: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:00 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz