1

我需要枚举 MTP android 设备的内容并将文件从设备传输到 Windows PC。

按照此处找到的将内容从设备传输到 PC的指南,我尝试将简单的文本文档传输到指定目录。但是,输出文件始终为空,即使返回值表明X number of bytes have been written.

我只使用推荐的 Windows API 调用创建了一个 SSCCE,以轻松重现该问题。我使用了 API 文档和官方示例项目作为参考。

主文件

Qt项目文件

为了测试,我有一个通过 MTP 连接的 android 手机,在根目录上有一个名为的文件夹testFolder,里面有一个testfile.txt带有文本的文件hello world。运行此应用程序时,输出表明已写入 11 个字节,但文件为空。请你自己试试?

我似乎无法理解为什么文件总是空的。有任何想法吗?

谢谢你的时间。

4

1 回答 1

2
  hr = SHCreateStreamOnFile(strOriginalFileName, STGM_CREATE|STGM_WRITE, &finalFileStream);

它通常有助于识别常见的编码模式。每当您创建文件时,您必须始终关闭该文件。在 C 语言中你有 fopen(),你必须调用 fclose()。在winapi中你有CreateFile(),你必须调用CloseHandle()。即使在很多资源管理都是自动执行的运行时环境中,例如 .NET,当您创建 FileStream 时,您也必须调用 Close() 或使用using语句。

该代码对显式关闭没有任何作用finalFileStream

这有后果,你找到了。除了内存泄漏之外,SHCreateStreamOnFile 的实现不知道何时将任何缓冲但尚未写入的数据刷新到文件中。所以你最终得到一个没有内容的文件。

任何接口指针的约定IStream是您始终必须显式调用其 Release() 函数。请注意,代码忘记对其使用的所有接口指针始终执行此操作。不是唯一的问题,当您调用 CoInitialize/Ex() 时,您必须调用 CoUninitialize()。只需使用黄金法则,您总是必须在这样的代码中明确地进行清理。

使固定:

  hr = StreamCopy(finalFileStream, ...);
  if (FAILED(hr)) saysomething(hr);          // Forgotten in original code
  finalFileStream->Release();                // Now it is good.

您可以在 C++ 中使用智能指针类型,例如CComPtr<>来自动完成它。

于 2017-03-02T00:17:52.357 回答