[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 aktualsiertIm 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.