文件时间到 __int64

发布于 2024-08-07 22:47:26 字数 48 浏览 8 评论 0原文

将 FILETIME 结构转换为 __int64 的正确方法是什么?你能告诉我吗?

What is the proper way to convert a FILETIME structure into __int64? Can you please tell me?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

千里故人稀 2024-08-14 22:47:26

我认为您不应该:“不要将指向 FILETIME 结构的指针转换为 ULARGE_INTEGER*__int64*值,因为它可能会导致 64 位 Windows 上的对齐错误。”

来源。

如果你真的想要的话,那就是类似:

__int64 to_int64(FILETIME ft)
{
    return static_cast<__int64>(ft.dwHighDateTime) << 32 | ft.dwLowDateTime;
}

FILETIME ft = // ...
__int64 t = to_int64(ft);

但类似:

FILETIME ft = // ...
__int64 t = *reinterpet_cast<__int64*>(&ft);

很糟糕。

I don't think you're suppose to: "Do not cast a pointer to a FILETIME structure to either a ULARGE_INTEGER* or __int64* value because it can cause alignment faults on 64-bit Windows."

Source.

If you really wanted it would be something like:

__int64 to_int64(FILETIME ft)
{
    return static_cast<__int64>(ft.dwHighDateTime) << 32 | ft.dwLowDateTime;
}

FILETIME ft = // ...
__int64 t = to_int64(ft);

But something like:

FILETIME ft = // ...
__int64 t = *reinterpet_cast<__int64*>(&ft);

Is bad.

凹づ凸ル 2024-08-14 22:47:26

无需使用按位或来恢复神秘的结构。 Windows API 拥有执行此操作所需的一切。

unsigned __int64    convert( const FILETIME & ac_FileTime )
{
  ULARGE_INTEGER    lv_Large ;

  lv_Large.LowPart  = ac_FileTime.dwLowDateTime   ;
  lv_Large.HighPart = ac_FileTime.dwHighDateTime  ;

  return lv_Large.QuadPart ;
}  

或者如果你想直接转到 __int64 。

__int64 convert_to_int64( const FILETIME & ac_FileTime )
{
  return static_cast< __int64 > ( convert( ac_FileTime ) ) ;
}

There is no need to revert to arcane constructs using bitwise OR's. The Windows API has got everything you need to do this.

unsigned __int64    convert( const FILETIME & ac_FileTime )
{
  ULARGE_INTEGER    lv_Large ;

  lv_Large.LowPart  = ac_FileTime.dwLowDateTime   ;
  lv_Large.HighPart = ac_FileTime.dwHighDateTime  ;

  return lv_Large.QuadPart ;
}  

Or if you want to go to __int64 directly.

__int64 convert_to_int64( const FILETIME & ac_FileTime )
{
  return static_cast< __int64 > ( convert( ac_FileTime ) ) ;
}
俯瞰星空 2024-08-14 22:47:26

尝试

(__int64(filetime.dwHighDateTime)<<32) | __int64(filetime.dwLowDateTime)

Try

(__int64(filetime.dwHighDateTime)<<32) | __int64(filetime.dwLowDateTime)
一袭水袖舞倾城 2024-08-14 22:47:26

当然,您可以只传递一个 __int64 转换为文件时间,如下所示 *(FILETIME*)&int64Val。这在 Visual C++ 下可以正常工作。

IE

__int64 createTime = 0;
__int64 accessTime = 0;
__int64 writeTime = 0;
GetFileTime( hFile, *(FILETIME*)&createTime, *(FILETIME*)&accessTime, *(FILETIME*)&writeTime );

Of course you could just pass in an __int64 casted to a filetime as follows *(FILETIME*)&int64Val. This will work fine under Visual C++.

ie

__int64 createTime = 0;
__int64 accessTime = 0;
__int64 writeTime = 0;
GetFileTime( hFile, *(FILETIME*)&createTime, *(FILETIME*)&accessTime, *(FILETIME*)&writeTime );
表情可笑 2024-08-14 22:47:26

你可以尝试下面的代码。该代码来自 chromium 项目

template <class Dest, class Source>
inline Dest bit_cast(const Source& source) {
    Dest dest;
    memcpy(&dest, &source, sizeof(dest));
    return dest;
}

//FILETIME to __int64

__int64 FileTimeToMicroseconds(const FILETIME& ft) {
    return bit_cast<__int64, FILETIME>(ft) / 10;
}

void MicrosecondsToFileTime(__int64 us, FILETIME* ft) {
    *ft = bit_cast<FILETIME, __int64>(us * 10);
}

int _tmain(int argc, _TCHAR* argv[])
{
    __int64 nTmpUint64 = 13060762249644841;

    time_t unixtime;
    FILETIME nTmpFileTm;
    MicrosecondsToFileTime(nTmpUint64,&nTmpFileTm);

    return 0;
}

you can try the code follow. the code is from chromium project

template <class Dest, class Source>
inline Dest bit_cast(const Source& source) {
    Dest dest;
    memcpy(&dest, &source, sizeof(dest));
    return dest;
}

//FILETIME to __int64

__int64 FileTimeToMicroseconds(const FILETIME& ft) {
    return bit_cast<__int64, FILETIME>(ft) / 10;
}

void MicrosecondsToFileTime(__int64 us, FILETIME* ft) {
    *ft = bit_cast<FILETIME, __int64>(us * 10);
}

int _tmain(int argc, _TCHAR* argv[])
{
    __int64 nTmpUint64 = 13060762249644841;

    time_t unixtime;
    FILETIME nTmpFileTm;
    MicrosecondsToFileTime(nTmpUint64,&nTmpFileTm);

    return 0;
}
乖不如嘢 2024-08-14 22:47:26

我遇到了完全相同的问题,用谷歌搜索,然后来到这里。但我还发现了一个有用的 Microsoft 支持页面:
https://support.microsoft. com/en-gb/help/188768/info-working-with-the-filetime-struct

它说:


用文件时间执行算术

通常需要对文件时间。例如,您可能需要知道文件的有效期为 30 天。要对文件时间执行算术,您需要将 FILETIME 转换为四字(64 位整数),执行算术,然后将结果转换回 FILETIME。

假设 ft 是一个包含文件创建时间的 FILETIME 结构,以下示例代码将时间添加 30 天:

   ULONGLONG qwResult;

   // Copy the time into a quadword.
   qwResult = (((ULONGLONG) ft.dwHighDateTime) << 32) + ft.dwLowDateTime;

   // Add 30 days.
   qwResult += 30 * _DAY;

   // Copy the result back into the FILETIME structure.
   ft.dwLowDateTime  = (DWORD) (qwResult & 0xFFFFFFFF );
   ft.dwHighDateTime = (DWORD) (qwResult >> 32 );

编辑:我意识到这只是证实了其他一些答案,但我认为值得添加以进行澄清。

I had exactly the same issue, googled for it, and came here. But I also found a useful Microsoft support page at
https://support.microsoft.com/en-gb/help/188768/info-working-with-the-filetime-structure

It says:


Performing Arithmetic with File Times

It is often necessary to perform a simple arithmetic on file times. For example, you might need to know when a file is 30 days old. To perform an arithmetic on a file time, you need to convert the FILETIME to a quadword (a 64-bit integer), perform the arithmetic, and then convert the result back to a FILETIME.

Assuming ft is a FILETIME structure containing the creation time of a file, the following sample code adds 30 days to the time:

   ULONGLONG qwResult;

   // Copy the time into a quadword.
   qwResult = (((ULONGLONG) ft.dwHighDateTime) << 32) + ft.dwLowDateTime;

   // Add 30 days.
   qwResult += 30 * _DAY;

   // Copy the result back into the FILETIME structure.
   ft.dwLowDateTime  = (DWORD) (qwResult & 0xFFFFFFFF );
   ft.dwHighDateTime = (DWORD) (qwResult >> 32 );

Edit: I realise this merely confirms some of the other answers, but I thought it was worth adding for clarification.

寄离 2024-08-14 22:47:26

具有最佳性能的三种方法(一种汇编指令)。仅在 Visual C++ 2022 x64 中测试。

auto u = std::bit_cast<std::uint64_t>(ft)

最好的办法。

auto u = *reinterpret_cast<std::uint64_t _UNALIGNED*>(&ft)

缺点:_UNALIGNED 宏(和__unaligned 修饰符)是非标准的。但几乎每个编译器都有某种形式的这个修饰符。

memcpy(&u, &ft, sizeof(u))

缺点:只有打开“Enable Intrinsic Functions”C++ 编译器选项,此代码才会得到很好的优化。

其他答案有一些开销。

(static_cast<std::uint64_t>(ft.dwHighDateTime) << 32) | ft.dwLowDateTime

生成按位运算。

ULARGE_INTEGER{ft.dwLowDateTime, ft.dwHighDateTime}.QuadPart

生成两个 32 位操作,而不是一个 64 位操作。

Three ways that have best performance (one assembler instruction). Tested only in Visual C++ 2022 x64.

auto u = std::bit_cast<std::uint64_t>(ft)

The best way.

auto u = *reinterpret_cast<std::uint64_t _UNALIGNED*>(&ft)

Disadvantage: _UNALIGNED macro (and __unaligned modifier) is non-standard. But almost every compiler has this modifier in some form.

memcpy(&u, &ft, sizeof(u))

Disadvantage: this code will be well optimized only if you turn on “Enable Intrinsic Functions” C++ compiler option.

Other answers have some overheads.

(static_cast<std::uint64_t>(ft.dwHighDateTime) << 32) | ft.dwLowDateTime

Generates bitwise operations.

ULARGE_INTEGER{ft.dwLowDateTime, ft.dwHighDateTime}.QuadPart

Generates two 32-bit operations instead of one 64-bit one.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文