Zu Hauptinhalt springen

 none
Fehlende Daten beim Schreiben mit CFile RRS feed

  • Frage

  • Hallo,

    Ich konnte eine Problem identifizieren, das Auftritt, wenn mit CFile auf ein Netzlaufwerk geschrieben wird. Kann aber die Ursache nicht finden.

    Ich schreibe X Blöcke a 128 Bytes. Dabei wird jedes mal die Datei geöffnet, geschrieben und wieder geschlossen (das ist nicht performant, aber nur so kann man das Problem nachvollziehen)

    Wenn ich die gleiche Funktion so umschreiben, dass mit fopen, fwrite usw. gearbeitet wird, funktioniert alles.

    Das Problem entsteht, wenn ich von Windows 10 (1803) auf ein gemapptes Laufwerk eines Windows 7 Systems schreibe. Hier kann ich es immer nachvollziehen.
    Schreibe ich von Windows 10 auf Windows 8 oder 10 (Server), tritt der Fehler nicht immer auf (nur ca. jedes 4 Mal)

    Hier die Funktion mit CFile:

    CFile* WRITE_TEST_CFILE(CString file, CString buffer, CFile* cf, bool keepFileOpen, bool flush) {
    
    	CString		csOutBuffer;
    	int			nOpenFlags;
    	long		nBytesToWrite;
    
    	csOutBuffer = buffer;
    	nOpenFlags = CFile::modeCreate | CFile::modeReadWrite | CFile::shareExclusive | CFile::modeNoTruncate;
    
    	CFileException ex;
    	if (cf == NULL || (cf->m_hFile == CFile::hFileNull))
    	{
    		bool bOpenSucceeded = false;
    		cf = new CFile();
    		CFileException ex;
    		for (int ii = 0; ii < 30; ii++) {
    			if (cf->Open(file, nOpenFlags, &ex)) {
    				bOpenSucceeded = true;
    				break;
    			}
    			Sleep(20);
    		}
    
    		if (!bOpenSucceeded) {
    			TCHAR szError[1024];
    			ex.GetErrorMessage(szError, 1024);	
    
    			std::cout << szError;
    			std::cout << "\n";
    			return NULL;
    		}
    	}
    
    	cf->SeekToEnd();
    	nBytesToWrite = csOutBuffer.GetLength();
    
    	cf->Write(csOutBuffer.GetBuffer(nBytesToWrite), nBytesToWrite);
    	csOutBuffer.ReleaseBuffer(-1);
    	if (flush)
    		cf->Flush();
    	if (keepFileOpen == false)
    		cf->Close();
    
    	return cf;
    }

    Die aufrufende Funktion tut folgendes:

    CString buffer = "_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_1234567";

    CString filepath = "Z:\test.txt";
    FILE* file = NULL; BOOL keepFileOpen = false; BOOL flush = false;
    int count = 1000; for (int i = 0; i < count; i++) { std::cout << "Block "; std::cout << i+1; std::cout << "\n"; if (i == count - 1) keepFileOpen = false; file = WRITE_TEST_CFILE(filepath, buffer, file, keepFileOpen, flush);


    Das Ergebnis:

    Statt 128.000 Bytes, sind es immer ein vielfaches von 128 Bytes weniger, z.B. 127.360 Bytes

    Es spielt auch kein Rolle, wenn ich flush=true setzte. Wenn ich allerdings keepFileOpen=true setzte, funktioniert es. Ich weiß, dass man das sowieso so machen sollte, aber der andere Weg muss ja prinzipiell funktionieren.



    • Bearbeitet gun_slinger Mittwoch, 16. Oktober 2019 08:56
    Mittwoch, 16. Oktober 2019 08:09