FindFirstFile / FindNextFile auf Netzlaufwerk findet nicht alles
-
Ja, Telnet geht. Die Attribute unterscheiden sich nicht von den Dateien, die gefunden werden.
Ich werde dann erstmal alle Filenamen holen und dann selbst filtern.
Danke Dir für deine Mühe!Grüße,
mathi
-
mathi schrieb:
Ja, Telnet geht. Die Attribute unterscheiden sich nicht von den Dateien, die gefunden werden.
Ich werde dann erstmal alle Filenamen holen und dann selbst filtern.
Danke Dir für deine Mühe!Grüße,
mathiDa fällt mir noch was ein, was Du prüfen kannst. Gibt es vielleicht führende oder folgende Leerzeichen im Namen? Die werden gerne übersehen.
mfg Martin
-
Leider nein, Leerzeichen oder Sonderzeichen, welche evtl. nicht dargestellt werden gibt es nicht im Namen.
Ich habe die Find Funktionen auch schon explizit dynamisch gegen die aktuelle Kernel32.dll gelinkt, falls irgendwas am SDK faul sein sollte. Und die dreambox hat heute auch nochmal das aktuellste Software Image bekommen.
-
mgaeckler schrieb:
Unicodezeichen iom Dateinamen? FindClose vergessen?
So sieht meine aus:
bool findFiles( const STRING &path, DIRECTORY_LIST &dirlist ) { doEnterFunction("findFiles"); doLogString( path ); bool success = false; #if defined( _Windows ) WIN32_FIND_DATAW findDataW; STRING file; uSTRING wPath, tmpBuff; ...
Ich habe bis jetzt immer alle Dateien bekommen. Egal ob Netzlaufwerk oder nicht.
mfg Martin
Netter Ansatz das Problem sowohl für UNIX als auch für Windows zu lösen. Leider kann man (zumindest unter Windows)
mit dem vorgeschlagenen Code garnichts anfangen, da diverse Deklarationen fehlen:STRING DIRECTORY_LIST DIRECTORY_ENTRY uSTRING newElement doEnterFunction( ) doLogString( ) doShowLog()
wäre es möglich die Deklarationen noch "beizulegen" ?
Microsofts Vorschlag zu dem Thema sieht so aus:
Listing the Files in a Directory
http://msdn.microsoft.com/de-de/library/windows/desktop/aa365200.aspx
-
merano schrieb:
mgaeckler schrieb:
Unicodezeichen iom Dateinamen? FindClose vergessen?
So sieht meine aus:
bool findFiles( const STRING &path, DIRECTORY_LIST &dirlist ) { doEnterFunction("findFiles"); doLogString( path ); bool success = false; #if defined( _Windows ) WIN32_FIND_DATAW findDataW; STRING file; uSTRING wPath, tmpBuff; ...
Ich habe bis jetzt immer alle Dateien bekommen. Egal ob Netzlaufwerk oder nicht.
mfg Martin
Netter Ansatz das Problem sowohl für UNIX als auch für Windows zu lösen. Leider kann man (zumindest unter Windows)
mit dem vorgeschlagenen Code garnichts anfangen, da diverse Deklarationen fehlen:STRING DIRECTORY_LIST DIRECTORY_ENTRY uSTRING newElement doEnterFunction( ) doLogString( ) doShowLog()
wäre es möglich die Deklarationen noch "beizulegen" ?
Microsofts Vorschlag zu dem Thema sieht so aus:
Listing the Files in a Directory
http://msdn.microsoft.com/de-de/library/windows/desktop/aa365200.aspxIch überlege mir schon seit geraumer Zeit die Bibliothek zu veröffentlichen. Allerdings entspricht die Qualität meiner Dokumentation der Lib nicht meinen Vorstellungen. Genauer gesagt die Quantität. Sie ist nämlich derzeit praktisch 0. Deshalb tue ich mich schwer, diese zu veröffentlichen.
Hier im konkreten Fall sollte es aber einfach sein, das erforderliche selbst zu erstellen:
STRING entspricht im wesentlichen std:string. Keine Ahnung ob std:string das auch kann aber meine STRING-klasse weiß halt auch, ob die aktuelle Kodierung ASCII, ANSI oder UTF-8 ist.
DIRECTORY_LIST ist einfach nur ein ARRAY von DIRECTORY_ENTRY. entspricht also im wesentlichen std::vector<DIRECTORY_ENTRY>.
DIRECTORY_ENTRY sieht bei mir so aus:
struct DIRECTORY_ENTRY { STRING fileName; uint64 fileSize; GAK_DATE_TIME creationDate, modifiedDate; bool directory; }
GAK_DATE_TIME ist einfach nur ein Zeitstempel, kannste auch time_t benutzen.
uSTRING ist ein wchar_t array, das eine Funktion zu Konvertierung in UTF-8 mitbringt.
die drei Funktionen, die mit do beginnen, sind Debuggingfunktionen und werden ausgeblendet, wenn release code generiert wird.
Miitlerweile habe ich die Funktion auch ein wenig geändert:
findFiles ist jetzt ein Member von DIRECTORY_LIST. Das Element fileSize von DIRECTORY_ENTRY ist jetzt auch ein 64-Bit Integer und keine Struktur mehr. Der Array-Container hat jetzt auch eine Memberfunktion createElement. Die Unix-Version füllt nun auch alle Felder:bool DIRECTORY_ENTRY::findFile( const STRING &fileName ) { bool success; #ifdef __BORLANDC__ struct stati64 buf; if( !strStat64( fileName, &buf ) ) #else struct stat buf; if( !strStat( fileName, &buf ) ) #endif { this->fileName = fileName; directory = S_ISDIR( buf.st_mode ); fileSize = buf.st_size; creationDate = buf.st_ctime; modifiedDate = buf.st_mtime; success = true; } else { this->fileName = ""; directory = false; fileSize = 0; creationDate = 0; modifiedDate = 0; success = false; } return success; } bool DIRECTORY_LIST::findFiles( const STRING &path ) { doEnterFunction("findFiles"); doLogString( path ); bool success = false; #if defined( _Windows ) WIN32_FIND_DATAW findDataW; STRING file; uSTRING wPath, tmpBuff; wPath.fromString( path ); HANDLE fs = FindFirstFileW( wPath.getDataBuffer(), &findDataW ); ; if( fs != INVALID_HANDLE_VALUE ) { clear(); do { DIRECTORY_ENTRY &newElement = createElement(); tmpBuff.fromWstring( findDataW.cFileName ); newElement.fileName = tmpBuff.toString(); newElement.fileSize = (findDataW.nFileSizeHigh << 32) | findDataW.nFileSizeLow; newElement.creationDate.setFileTime( findDataW.ftCreationTime ); newElement.modifiedDate.setFileTime( findDataW.ftLastWriteTime ); newElement.directory = findDataW.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; } while( FindNextFileW( fs, &findDataW ) ); FindClose( fs ); resort(); success = true; } #elif defined( __MACH__ ) || defined( __unix__ ) size_t slashPos = path.searchRChar( DIRECTORY_DELIMITER ); STRING myPath = slashPos != -1 ? path.leftString( slashPos ) : STRING(".") ; STRING pattern = path + (size_t)(slashPos +1); struct dirent *file; DIR *dir = opendir( myPath ); STRING name; STR_CHARSET charSet; if( pattern == "*.*" ) pattern = "*"; if( dir ) { clear(); while( (file = readdir( dir )) != NULL ) { doLogString( file->d_name ); name = file->d_name; if( name.match( pattern ) ) { DIRECTORY_ENTRY &newElement = createElement(); charSet = name.testCharSet(); if( charSet == STR_ANSI ) charSet = STR_UTF8; name.setCharSet( charSet ); newElement.findFile( myPath + DIRECTORY_DELIMITER + name ); newElement.fileName = name; newElement.directory = (file->d_type == DT_DIR); } } closedir( dir ); resort(); success = true; } #else # error "Unkown OS" #endif doShowLog(); return success; }
Hier noch eine Anmerkung:
strStat ist unter Nixen einfach nur ein Makro auf stat. Unter Nixen werden Dateinamen UTF-8 kodiert und das versteht auch stat und STRING. Windows benutzt entweder ANSI oder UNICODE wenn strStat im übergebenen STRING eine UTF-8 Kodierung findet, wird der String in UNICODE gewandelt und die entsprechenden Funktionen benutzt. Ansonsten wird die ganz normale Funktion stat verwendet. Allerding hab ich die auch schon patchen müssen, weil die Runtime-Libs von Borland und Kleinweich falsche Zeiten liefern, wenn die Dateien im Winter erstellt bzw. geändert wurden und stat im Sommer aufgerufen wird und umgekehrt. Angeblich machen die das absichtlich wegen dem alten FAT-Dateisystem, das ja lokale Zeit speichert statt UTC.
mfg Martin
-
Vielen Dank mgaeckler fuer die Beschreibung der Zutaten.
Nachdem man VS einiges nun "schmackhaft" gemacht hat mit:
typedef std::basic_string<TCHAR> STRING; typedef unsigned __int64 uint64; struct DIRECTORY_ENTRY { STRING fileName; uint64 fileSize; time_t creationDate, modifiedDate; // ein Zeitstempel bool directory; }; typedef std::vector<DIRECTORY_ENTRY> DIRECTORY_LIST; void doEnterFunction(char *txt) {}; void doLogString( const STRING ) {};
fehlt immer noch die komplette Klasse uSTRING.
Wäre es nicht besser das ganze mit C++-Standard zu erschlagen ?
-
merano schrieb:
Vielen Dank mgaeckler fuer die Beschreibung der Zutaten.
fehlt immer noch die komplette Klasse uSTRING.
Wäre es nicht besser das ganze mit C++-Standard zu erschlagen ?
Die Definition von uSTRING wird Dir nicht gefallen:
class uSTRING : public ARRAY<wchar_t> { public: const wchar_t *getString( void ) { return getDataBuffer(); } void decodeUTF8( const STRING &src ); STRING encodeUTF8( void ); STRING toString( void ); void fromString( const STRING &src ); void fromWstring( const wchar_t *src ); };
Die ganze Bibliothek ist eine gewachsende Lib, deren Ursprünge 1988 auf einem Atari ST mit Turbo C angelegt wurden. 1990 wurde dann angefangen vielen Sachen nach Turbo C++ zu migrieren und Mitte der 90er auf Gnu C++ unter Linux (in der Zeit habe ich dann auch angefangen die C bzw. Atarikompatibilität nicht mehr zu verfolgen) und Anfang 2000 kam dann MACH dazu.
Viele Klassen, insbesonders STRING, ARRAY etc wurden angelegt als es halt noch keinen Standard gab.
mfg Martin
-
mgaeckler schrieb:
Die Definition von uSTRING wird Dir nicht gefallen:
Stimmt. Egal, danke für die Infos. Ich frag nicht weiter ...
mgaeckler schrieb:
Viele Klassen, insbesonders STRING, ARRAY etc wurden angelegt als es halt noch keinen Standard gab.
Ich weiss nur zu gut wovon Du du berichtest, war live dabei. Turbo Pascal, Turbo C, Assembler und manchmal gemixt im selben Programm. War halt so ...
Und der gute alte 68000 - das waren Zeiten ...
-
merano schrieb:
Ich weiss nur zu gut wovon Du du berichtest, war live dabei. Turbo Pascal, Turbo C, Assembler und manchmal gemixt im selben Programm. War halt so ...
Und der gute alte 68000 - das waren Zeiten ...
Turbo Pascal auf dem Atari? Soweit ich weiß wurde die Auslieferung gestoppt noch bevor der erste Diskettensatz verschickt wurde. Damit dürfte es außer mir nicht sehr viele Leute gegeben haben, die das gesehen haben.
mfg Martin
-
Hallo,
als alter TP-Programmierer möchte ich auch gerne noch etwas beitragen.
Auch wenn das hier C++ ist - Auch ich träume von alten ATARI-ST-Zeiten ...Wenn FindFirstFile / FindNextFile nicht alles findet,
könnte es vielleicht ein Problem mit der Übertragung geben?
Wie ist denn die DreamBox an das System angeschlossen?
Über USB vielleicht? Oder FireWire?
Könnte es vielleicht sein, daß das System einige der Informationen
"verschluckt", bevor sie beim Programm ankommen ?Ich hatte das Problem auch schon unter DOS & Windows unter TP -
ich weiß jetzt aber nicht mehr, woran das seinerzeit lag ...Mit freundlichem Gruß,
Guenni60
-
@mathi
Was bekommst du denn wenn du ne Konsole (cmd.exe
) aufmachst und dortdir \\Pfad\zum\NAS\Verzeichnis\*.mp4
eingibst?
Explorer ist mMn. ziemlich uninteressant, denn der wird kaum direktFindFirstFile/FindNextFile
verwenden. Bei der "dir
" Implementierung incmd.exe
gehe ich aber davon aus dass die im Endeffekt nix anderes macht.
Und wenn die Files da auch fehlen, dann ist vermutlich einfach die SMB Implementierung in der NAS fehlerhaft.@Guenni60
Guenni60 schrieb:
Wie ist denn die DreamBox an das System angeschlossen?
Über USB vielleicht? Oder FireWire?Gar nicht direkt, Zugriff über's Netzwerk.
Das Verzeichnis ist von einer dreambox (müsste also linux, samba mount sein) unter Windows 7 32Bit als Laufwerk hinzugefügt.
Und Samba ist die (bzw. eine) SMB Implementierung für Linux. Und SMB == Das Protokoll welches Windows für "Netzwerkfreigaben" verwendet.