FILETIME GetModificationTime(const WCHAR *filePath) { FILETIME lastMod = { 0 }; ScopedHandle h(OpenReadOnly(filePath)); if (h != INVALID_HANDLE_VALUE) GetFileTime(h, NULL, NULL, &lastMod); return lastMod; }
// buf must be at least toRead in size (note: it won't be zero-terminated) bool ReadN(const WCHAR *filePath, char *buf, size_t toRead) { ScopedHandle h(OpenReadOnly(filePath)); if (h == INVALID_HANDLE_VALUE) return false; DWORD nRead; BOOL ok = ReadFile(h, buf, (DWORD)toRead, &nRead, NULL); return ok && nRead == toRead; }
void IBMemStream::FlushTo(IBStream& out_stream) { OpenReadOnly("none"); long size = GetSize(); long ntransferred = 0, nbytes, bufsize = 512*1024; boost::scoped_array<uchar> tempbuf(new uchar [bufsize]); // Read from memstream and write to it while (ntransferred < size) { nbytes = Read(tempbuf.get(), bufsize); if (nbytes == 0) ThrowError("MemStream::FlushTo failed, unexpected internal error, nbytes==0"); out_stream.WriteExact(tempbuf.get(), nbytes); ntransferred += nbytes; } }
// returns -1 on error (can't use INVALID_FILE_SIZE because it won't cast right) int64 GetSize(const WCHAR *filePath) { CrashIf(!filePath); if (!filePath) return -1; ScopedHandle h(OpenReadOnly(filePath)); if (h == INVALID_HANDLE_VALUE) return -1; // Don't use GetFileAttributesEx to retrieve the file size, as // that function doesn't interact well with symlinks, etc. LARGE_INTEGER size; BOOL ok = GetFileSizeEx(h, &size); if (!ok) return -1; return size.QuadPart; }