[ofstream] timestamp aktualisieren



  • wie kann man am elegantesten (also ohne close und open) den Zeitstempel einer Datei aktualisieren?

    Windowsbeispiel

    std::ofstream logFile("log.txt");
    
    ::Sleep(7000);
    logFile << "logInfo1\n";
    logFile.flush(); //<- Datei wird aktualisiert, Zeitstempel leider nicht
    
    ::Sleep(7000);
    logFile.close(); //<- Zeitstempel wird aktualsiert
    

    Im Dateiexplorer wird erst bei close die aktuelle Zeit angegeben.
    Problem ist, dass ich via Dateimonitor die Logs betrachte, die jedoch anstelle eines "Reload" den Zeitstempel der Datei zur Dateiänderung betrachten.

    Gibt es einen Weg OHNE close und open dieses Problem zu lösen?

    --SirAnn



  • Plattformabhängig geht das auf jeden Fall (unter Windows z.B. SetFileTime).
    Plattformunabhängig ohne externe Bibliotheken bezweifle ich aber, da im Standard gar nicht davon ausgegangen wird, dass Dateien überhaupt einen Zeitstempel haben.

    Wahrscheinlich ist aber ein reopen hier das einfachste.



  • ok. Danke für die Antwort. Ich besorge mir nun mit Create_File einen Handle und ändere über diesen dann den Zeitstempel.



  • Ein Projekt dass ich vor langer Zeit programmiert habe:

    // std::
    #include <iostream> 
    #include <ctime>
    #include <string>
    #include <cstring>
    #include <cstdio>
    // Windows::
    #include <windows.h>
    #include <wincon.h>
    #include <shlwapi.h>
    #include <conio.h>
    void askInformations();
    void getFilesInDir(const std::string&, const SYSTEMTIME&);
    void setFileTime(const std::string&, const SYSTEMTIME&);
    void handleError(const std::string&);
    
    int main()
    {
    
    	// BOOL WINAPI SetConsoleTitle(
    	//   __in  LPCTSTR lpConsoleTitle
    	//   ); -> http://msdn.microsoft.com/en-us/library/ms686050(v=VS.85).aspx
    	if(!SetConsoleTitle("Die Zeitmaschine für Dateien"))
    		handleError("SetConsoleTitle");
    
    	// HANDLE WINAPI GetStdHandle(
    	//  __in  DWORD nStdHandle
    	//  ); -> http://msdn.microsoft.com/en-us/library/ms683231(v=VS.85).aspx
    	HANDLE outHandle = GetStdHandle(STD_OUTPUT_HANDLE);
    
    	if(outHandle == INVALID_HANDLE_VALUE)	
    		handleError("GetStdHandle");
    	// BOOL WINAPI SetConsoleTextAttribute(
    	//   __in  HANDLE hConsoleOutput,
    	//   __in  WORD wAttributes
    	//  ); -> http://msdn.microsoft.com/en-us/library/ms686047(v=VS.85).aspx
    	if(!SetConsoleTextAttribute(outHandle, FOREGROUND_GREEN))
    	       handleError("SetConsoleTextAttribute");
    
    	askInformations();
    	fflush(stdin);
    	std::cin.get();
    	return 0;
    }
    
    void askInformations()
    {
    	std::string pathToFiles;
    	char answer;
    	do
    	{
    		std::wcout << L"Pfad zum Ordner eingeben (C:\\Users\\...) : ";
    		std::getline(std::cin, pathToFiles, '\n');
    		fflush(stdin);
    		// BOOL PathIsDirectory(__in LPCTSTR pszPath); -> http://msdn.microsoft.com/en-us/library/bb773621(VS.85).aspx
    		//if(!PathIsDirectory(pathToFiles.c_str())) {
    		//	std::cerr << "Error: \"" << pathToFiles << "\" ist kein Ordner.\nBitte Pfad zum Ordner neu eingeben." << std::endl;
    		//	continue;
    		//}
    		// PathIsDirectory has a bug under Win7, so I don't use it...
    
    		std::cout << "Ist dieser Pfad richtig \"" << pathToFiles << "\" (J/N) ?" << std::endl;
    		std::cin.get(answer);
    		fflush(stdin);
    	}while(answer != 'J' && answer != 'j');
    
    	SYSTEMTIME newTime_sysTime = { 0 };
    	do
    	{
    		std::cout << "Zur welcher Zeit soll das Erstelldatum gesetzt werden?" << std::endl;
    		std::cout << "Tag: ";
    		std::cin >> newTime_sysTime.wDay;
    		fflush(stdin);
    		std::cout << "Monat: ";
    		std::cin >> newTime_sysTime.wMonth;
    		fflush(stdin);
    		std::cout << "Jahr: ";
    		std::cin >> newTime_sysTime.wYear;
    		fflush(stdin);
    		std::cout << "\n\nIst das Datum richtig \"" << newTime_sysTime.wDay << "."
    							<< newTime_sysTime.wMonth << "."
    							<< newTime_sysTime.wYear << "\" (J/N)?" << std::endl;
    		std::cin.get(answer);
    		fflush(stdin);
    	}while(answer != 'J' && answer != 'j');
    
    	getFilesInDir(pathToFiles, newTime_sysTime);	
    }
    
    void getFilesInDir(const std::string& pathToFiles, const SYSTEMTIME& newTime_sysTime)
    {
    
    	HANDLE handle;  
    	// typedef struct _WIN32_FIND_DATA {
    	//   DWORD    dwFileAttributes;
    	//   FILETIME ftCreationTime;
    	//   FILETIME ftLastAccessTime;
    	//   FILETIME ftLastWriteTime;
    	//   DWORD    nFileSizeHigh;
    	//   DWORD    nFileSizeLow;
    	//   DWORD    dwReserved0;
    	//   DWORD    dwReserved1;
    	//   TCHAR    cFileName[MAX_PATH];
    	//   TCHAR    cAlternateFileName[14];
    	//   } WIN32_FIND_DATA, *PWIN32_FIND_DATA, *LPWIN32_FIND_DATA; -> http://msdn.microsoft.com/en-us/library/aa365740(VS.85).aspx
    	WIN32_FIND_DATA findHandle;
    	// HANDLE WINAPI FindFirstFile(
    	//   __in   LPCTSTR lpFileName,
    	//   __out  LPWIN32_FIND_DATA lpFindFileData
    	//   ); -> http://msdn.microsoft.com/en-us/library/aa364418(VS.85).aspx
    	handle=FindFirstFile((pathToFiles + std::string("\\*")).c_str(), &findHandle);  
    	// BOOL WINAPI FindNextFile(
    	//   __in   HANDLE hFindFile,
    	//   __out  LPWIN32_FIND_DATA lpFindFileData
    	//  ); -> http://msdn.microsoft.com/en-us/library/aa364428(v=VS.85).aspx
    	FindNextFile(handle,&findHandle);  
    	while (FindNextFile(handle,&findHandle))  
    		if (!(findHandle.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
    		{
    			std::cout << "[DEBUG-getFilesInDir] " << findHandle.cFileName << std::endl;
    			setFileTime(pathToFiles + std::string("\\") + std::string(findHandle.cFileName), newTime_sysTime);
    		}
      	// BOOL WINAPI CloseHandle(
    	//   __in  HANDLE hObject
    	//   ); -> http://msdn.microsoft.com/en-us/library/ms724211(VS.85).aspx
    	FindClose(handle); 
    }
    
    void setFileTime(const std::string& fileName, const SYSTEMTIME& newFileTime_sysTime)
    {
    	std::cout << "[DEBUG-setFileTime] " << fileName << std::endl;
    	// HANDLE WINAPI CreateFile(
    	//   __in      LPCTSTR lpFileName,
    	//   __in      DWORD dwDesiredAccess,
    	//   __in      DWORD dwShareMode,
    	//   __in_opt  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    	//   __in      DWORD dwCreationDisposition,
    	//   __in      DWORD dwFlagsAndAttributes,
    	//   __in_opt  HANDLE hTemplateFile
    	//   ); -> http://msdn.microsoft.com/en-us/library/aa363858(v=VS.85).aspx
    	HANDLE fileHandle = CreateFile(
    					fileName.c_str(),
    					GENERIC_READ | GENERIC_WRITE,
    					FILE_SHARE_READ | FILE_SHARE_WRITE,
    					NULL,
    					OPEN_EXISTING,
    					FILE_ATTRIBUTE_NORMAL,
    					NULL
    				      );
    	if(fileHandle == INVALID_HANDLE_VALUE)
    		handleError("CreateFile");	
    
    	// typedef struct _FILETIME {
    	//   DWORD dwLowDateTime;
    	//   DWORD dwHighDateTime;
    	//   } FILETIME, *PFILETIME; -> http://msdn.microsoft.com/en-us/library/ms724284(v=VS.85).aspx
    	FILETIME creationTime_fileTime;
    
    	// BOOL WINAPI GetFileTime(
    	//   __in       HANDLE hFile,
    	//   __out_opt  LPFILETIME lpCreationTime,
    	//   __out_opt  LPFILETIME lpLastAccessTime,
    	//   __out_opt  LPFILETIME lpLastWriteTime
    	//   ); -> http://msdn.microsoft.com/en-us/library/ms724320(v=VS.85).aspx
    	if(!GetFileTime(fileHandle, &creationTime_fileTime, NULL, NULL))
    		handleError("GetFileTime");
    
    	// typedef struct _SYSTEMTIME {
    	//   WORD wYear;
    	//   WORD wMonth;
    	//   WORD wDayOfWeek;
    	//   WORD wDay;
    	//   WORD wHour;
    	//   WORD wMinute;
    	//   WORD wSecond;
    	//   WORD wMilliseconds;
    	//   } SYSTEMTIME, *PSYSTEMTIME; -> http://msdn.microsoft.com/en-us/library/ms724950(v=VS.85).aspx
    	SYSTEMTIME creationTime_sysTime;
    
    	// BOOL WINAPI FileTimeToSystemTime(
    	//   __in   const FILETIME *lpFileTime,
    	//   __out  LPSYSTEMTIME lpSystemTime
    	//   ); -> http://msdn.microsoft.com/en-us/library/ms724280(v=VS.85).aspx
    	if(!FileTimeToSystemTime(&creationTime_fileTime, &creationTime_sysTime))
    	       handleError("FileTimeToSystemTime");
    
    	std::cout << "Die Datei \"" << fileName.c_str() << "\" wurde am: \"" 
    		<< creationTime_sysTime.wDay 
    		<< "." << creationTime_sysTime.wMonth
    		<< "." << creationTime_sysTime.wYear << "\" erstellt." << std::endl;
    
    	// BOOL WINAPI SystemTimeToFileTime(
    	//   __in   const SYSTEMTIME *lpSystemTime,
    	//   __out  LPFILETIME lpFileTime
    	//   ); -> http://msdn.microsoft.com/en-us/library/ms724948(VS.85).aspx
    	if(!SystemTimeToFileTime(&newFileTime_sysTime, &creationTime_fileTime))
    		handleError("SystemTimeToFileTime");
    
    	// BOOL WINAPI SetFileTime(
    	//   __in      HANDLE hFile,
    	//   __in_opt  const FILETIME *lpCreationTime,
    	//   __in_opt  const FILETIME *lpLastAccessTime,
    	//   __in_opt  const FILETIME *lpLastWriteTime
    	//   ); -> http://msdn.microsoft.com/en-us/library/ms724933(v=VS.85).aspx
    	if(!SetFileTime(fileHandle, &creationTime_fileTime, NULL, NULL))
    		handleError("SetFileTime");
    
    	std::wcout << L"Erfolgreich geändert in: "  
    	        << newFileTime_sysTime.wDay 
    		<< L"." << newFileTime_sysTime.wMonth
    		<< L"." << newFileTime_sysTime.wYear << std::endl;
    
    	CloseHandle(fileHandle);
    }
    
    void handleError(const std::string& functionCall)
    {
    	std::cerr << "[FUNCTION] " << functionCall << std::endl;
    	// DWORD WINAPI GetLastError(void); -> http://msdn.microsoft.com/en-us/library/ms679360(v=VS.85).aspx
    	int ErrorCode = GetLastError();
    	std::wcerr << L"\nErrorcode: " << ErrorCode 
    				<< L"\nBitte rufen Sie den Entwickler „“ an " 
    				<< L"oder schicken Sie ihm eine E-Mail an „“ "
    				<< L"und teilen Sie ihm den Errorcode mit. - Danke.\n" << std::endl;
    
    	std::wcout << L"Bitte betätigen Sie eine Taste um das Programm zu schließen..." << std::endl;
    	std::cin.get();
    	exit(ErrorCode);
    }
    

    Ziemlich hässlich wie ich jetzt finde. aber bin der winapi näher gekommen.
    €dit: Für dich wird wahrscheinlich nur die setFileTime-Funktion von Bedeutung sein.


Anmelden zum Antworten