[win32/c++] File operations en timing problemen *

Pagina: 1
Acties:

  • Peetman
  • Registratie: Oktober 2001
  • Laatst online: 21-08 17:18
Voor een bepaalde Lotus Notes toepassing heb ik een DLL geschreven die in Lotus Notes hooked.
De DLL voert een aantal bewerkingen uit op bestanden, namelijk renamen en verwijderen.
Het doel is als volgt. Als Notes opstart moet er een nieuwe file worden gebruikt. Dit doe ik door:
- een mogelijk aanwezige oude backup (file.bak) renamen naar .tmp
- deze .tmp weggooien
- het oude bestand te backuppen: renamen van file.cur naar file.bak
- het nieuwe bestand renamen van file.new naar file.bak

Nu gaat dit vaak goed. Maar soms lijkt de programmacode sneller te lopen dan het I/O en kan ik niet backuppen omdat er nog een oud bestand staat. Dit gebeurt soms als de bestanden groter dan 10 mb zijn (kan vaak voorkomen).

Is er een manier om te wachten totdat windows klaar is met de rename/verwijder actie? Een loop met een aantal checks op aanwezigheid is niet echt een optie, omdat het "altijd" moet werken, zonder dat ik foutmeldingen kan geven aan de gebruiker.

Mijn rename functie ziet er als volgt uit:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
int CopyFile(char* OldFile, char* NewFile, char* BackupFile)
{
  char TempFile[MAXENVVALUE];
  char buff[MAXENVVALUE];

  // check voor de nieuwe file (.new)
  if(_access(NewFile, 0) != 0){
        return 3;
  }
    
  // check voor een oude backup file en verwijder eventueel
  if(_access(BackupFile, 0) != -1){
        strncpy(TempFile, BackupFile, strlen(BackupFile)-3);
        strcat(TempFile, "tmp");

        if (OSGetEnvironmentString("$Debugdll", buff, sizeof(buff)))
        {
            MessageBox(NULL, TempFile, "Error", MB_OK);
        }
        
        if(rename(BackupFile, TempFile) != 0){
                return 2;
        }
        else{
            Sleep(500);
            remove(TempFile);
        }
  }

  // rename de huidige file naar backup file
  if(rename(OldFile, BackupFile) != 0){
        return 4;
  }
  else{
    Sleep(500); 
  }
            
  // hernoem nieuwe file naar oude huidige file
  if(rename(NewFile, OldFile) != 0){
        if(rename(BackupFile, OldFile) != 0){
               return 5;
        }
        else{
               return 6;
        }
  }
  Sleep(500);
  return 0;
}

Zoals jullie zien, heb ik er al een aantal delays ingebouwd, maar dat is natuurlijk niet een hele nette optie.

[ Voor 4% gewijzigd door Peetman op 09-09-2003 13:38 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Nu gaat dit vaak goed. Maar soms lijkt de programmacode sneller te lopen dan het I/O en kan ik niet backuppen omdat er nog een oud bestand staat. Dit gebeurt soms als de bestanden groter dan 10 mb zijn (kan vaak voorkomen).
raar, een bestand renamen of verwijderen zou niet lang moeten duren, ongeacht de lengte van het bestand. Het is gewoon een kwestie van de file allocation tabellen wijzigen

Maar goed, gebruik ipv rename () MoveFileEx, met als flags MOVEFILE_WRITE_THROUGH. Dat zorgt ervoor dat de functie pas retourneert als de file daadwerkelijk gemoved is

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Peetman
  • Registratie: Oktober 2001
  • Laatst online: 21-08 17:18
Helaas werkt MoveFileEx alleen onder Windows NT3.1>, 2K en XP en niet onder Win 95/98. En daarop moet het ook goed werken.
raar, een bestand renamen of verwijderen zou niet lang moeten duren, ongeacht de lengte van het bestand. Het is gewoon een kwestie van de file allocation tabellen wijzigen
Dat lijkt mij ook. Daarom rename ik bijvoorbeeld ook eerst de .bak naar .tmp zodat daar zo min mogelijk vertraging in zit. Het gebeurt ook niet altijd. Bij het testen komt het maar op een machine voor (en dat is niet de langzaamste).

[ Voor 65% gewijzigd door Peetman op 09-09-2003 13:48 ]


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 01:56
Ik had eigenlijk verwacht dat Windows de nieuwe situatie wel zou weergeven, zodra je het bestand verplaatst hebt. Dat 'ie ondertussen de wijziging nog niet op de harde schijf doorgevoerd heeft, zou dan niet uitmaken, zolang de situatie naar applicaties toe maar consistent is. Blijkbaar is de werkelijkheid anders.
peetman schreef op 09 September 2003 @ 13:29:
Een loop met een aantal checks op aanwezigheid is niet echt een optie, omdat het "altijd" moet werken, zonder dat ik foutmeldingen kan geven aan de gebruiker.
Waarom werkt een lusje niet "altijd"? Ik kan me trouwens voorstellen dat je huidige oplossing ook alleen werkt als je vertraging toevallig lang genoeg is, terwijl een lusje juist wel "altijd" de executie kan uitstellen totdat het bestand echt verdwenen is.

  • Peetman
  • Registratie: Oktober 2001
  • Laatst online: 21-08 17:18
Soultaker schreef op 09 September 2003 @ 14:01:
Waarom werkt een lusje niet "altijd"? Ik kan me trouwens voorstellen dat je huidige oplossing ook alleen werkt als je vertraging toevallig lang genoeg is, terwijl een lusje juist wel "altijd" de executie kan uitstellen totdat het bestand echt verdwenen is.
Die vertraging is idd geen structurele oplossing.
Bij een lus zal je uit veiligheidsoverwegingen ook een moment moeten vastellen dat het niet goed is gegaan met het renamen, want oneindige loops zijn natuurlijk geen optie.

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 01:56
Tja, het is sowieso een hack. Zelf zou ik denken dat als de rename functie succesvol uitgevoerd kon worden, het bestand vroeger of later ook verplaatst zou moeten zijn.

  • Peetman
  • Registratie: Oktober 2001
  • Laatst online: 21-08 17:18
Dat lijkt me ook inderdaad. Dan zal het wel nog een paar leuke loopjes worden.
En om nou te zeggen dat ik me altijd verre houdt van hacks.... >:)

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Ik had eigenlijk verwacht dat Windows de nieuwe situatie wel zou weergeven, zodra je het bestand verplaatst hebt.
Dat doet ie dan ook... ik heb zelfs met files van 80~200Mb in al die tijd dat ik Windows programmeer de beschreven problemen nooit gezien, en vermoed dan ook een probleem elders in de code.... :?

Professionele website nodig?


  • Peetman
  • Registratie: Oktober 2001
  • Laatst online: 21-08 17:18
Ik begin het vermoeden te krijgen dat sommige files niet vrijgegeven zijn door notes. De client wordt in principe namelijk opnieuw opgestart en dan vind de kopieeractie plaats.

Hier is nog het stuk code dat de functie aanroept + "errorhandling":
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
char OldFile[MAXENVVALUE];
char NewFile[MAXENVVALUE];
char BakFile[MAXENVVALUE];

// parameters worden uit de ini uitgelezen
        OSGetEnvironmentString("$OldFile", OldFile, sizeof(OldFile));
        OSGetEnvironmentString("$NewFile", NewFile, sizeof(NewFile));
        OSGetEnvironmentString("$BackupFile", BakFile, sizeof(BakFile));

// voer de copyfunctie uit en handle errors
        retVal = CopyFile(OldFile, NewFile, BakFile);
        switch (retVal){
        case 1:
            CloseNotesSplash();
            MessageBox(NULL, "Failed to remove old File backup\nErrorcode: 1", dialogTitle, MB_OK);
            break;
        case 2:
            CloseNotesSplash();
            MessageBox(NULL, "Failed to remove old File\nErrorcode: 2", dialogTitle, MB_OK);
            break;
        case 3:
            CloseNotesSplash();
            MessageBox(NULL, "Failed to find new File\nErrorcode: 3", dialogTitle, MB_OK);
            break;
        case 4:
            CloseNotesSplash();
            MessageBox(NULL, "Failed to create File backup\nErrorcode: 4", dialogTitle, MB_OK);
            break;
        case 5:
            CloseNotesSplash();
            MessageBox(NULL, "Failed to enable new File\nFailed to restore File backup\nErrorcode: 5", dialogTitle, MB_OK);
            break;
        case 6:
            CloseNotesSplash();
            MessageBox(NULL, "Failed to enable new File\nErrorcode: 6", dialogTitle, MB_OK);
            break;
        case 7:
            CloseNotesSplash();
            MessageBox(NULL, "Failed to create File backup\nErrorcode: 7", dialogTitle, MB_OK);
            break;
        case 8:
            CloseNotesSplash();
            MessageBox(NULL, "Failed to enable new File\nErrorcode: 8", dialogTitle, MB_OK);
            break;
        }

Er zitten uiteraard nog wat checks in of de parameters gevuld zijn enzo.

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Een file renamen gebeurt in de directory structuren, en niet op de inhoud. De grootte van de file is irrelevant (uitzondering: <4K op NTFS is bijzonder). Wat wel een verschil maakt is het File System: NTFS/FAT/FAT23/HPFS/SMB(netwerk).

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • D2k
  • Registratie: Januari 2001
  • Laatst online: 09-01 11:25

D2k

in dit geval zal het zowel FAT/FAT32 als NTFS zijn (als collega van peetman kan ik dat rustig melden ;) )

Doet iets met Cloud (MS/IBM)


  • Peetman
  • Registratie: Oktober 2001
  • Laatst online: 21-08 17:18
Het kan ook SMB zijn, het is namelijk mogelijk dat de files op een netwerkschijf staan in iemand zijn userdir bijvoorbeeld. De problemen die ik tot nu toe gezien hebt waren op een toshiba laptop met de files gewoon op de schijf.
Pagina: 1