0

我正在为 Chrome 开发 NaCl 插件,并尝试将 URL 资源文件在本地下载到 Chrome 的临时缓存中,但没有成功。

这是我如何进行的:

// I indicate that I want the resource to be downloaded to a file
m_URLRequestInfo.SetStreamToFile( true );

// I open the request:
m_URLLoader.Open( m_URLRequestInfo, m_CCFactory.NewCallback( &MyClass::OnOpen ) );

...    
// My callback (OnOpen) is eventually called.
// I then check to make sure the status code is 200 using this call:
m_URLLoader.GetResponseInfo().GetStatusCode()

// Then I ask to download the whole file:
m_URLLoader.FinishStreamingToFile( m_CCFactory.NewOptionalCallback( &MyClass::OnFileDownloaded ) );

...
// My other callback (OnFileDownloaded) gets eventually called,
// and again the status code is 200.
// Then I query the FileRef using this call:
pp::FileRef l_FileRef = m_URLLoader.GetResponseInfo().GetBodyAsFileRef();

返回的 pp::FileRef 似乎没问题,但是 pp::FileRef::GetFileSystemType() 返回 PP_FILESYSTEMTYPE_EXTERNAL,然后对 pp::FileRef::GetPath() 的调用失败(它返回一个 UNDEFINED pp::Var)。

所以从这一点开始,我迷路了。我不知道我应该做些什么来获得一个有效的 pp::FileRef 指向浏览器缓存中的本地文件。我的最终目标是使用像 fopen() 这样的标准系统文件 IO 打开这个本地文件(在我的例子中是一个图像文件)。

谢谢你的光!

4

2 回答 2

0

在更彻底地阅读了文档并运行了更多测试之后,我终于弄清楚了我做错了什么。

当我们调用 pp::URLLoader::FinishStreamingToFile 时,文件被下载到浏览器的缓存中,但无法使用 fopen、fread 等常规 stdio 服务打开/读取。我们需要使用 pp::FileIO 类服务打开获得的pp::FileRef并读取文件的内容。

所以这就是我成功加载和读取浏览器为我下载的文件所做的工作。基本上,我继续使用 C++ PPAPI 服务。

(1) 在从 m_URLLoader->FinishStreamingToFile 回调后,我们调用 m_FileIO->Open 使用获取的 FileRef 打开下载的文件;

(2) 在从 m_FileIO->Open 回调后,我们调用 m_FileIO->Query 来获取下载文件的大小(以及其他一些文件属性);

(3) 在从 pp::FileIO::Query 回调时,我们检查文件属性类型(例如不是文件夹),分配足够大的内存缓冲区以容纳整个文件内容,并开始调用 pp::FileIO: :Read 获取文件内容;

(4) 在 pp::FileIO::Read 回调时,如果得到的 nResult 参数为 0,那么我们到达了 EOF,我们完成了将文件内容读入内存缓冲区;如果得到的nResult > 0,则表示成功读取字节数,我们再次调用m_FileIO->Read继续读取字节,并将它们存储在不同的偏移位置到我们的内存缓冲区中;如果获得的 nResult < 0 则发生错误,我们必须终止读取过程。

许多步骤和许多回调要管理,但最终这很顺利。

于 2013-10-30T16:18:23.227 回答
0

您是否有理由不能使用该nacl_io库?有了它,您可以编写如下内容:

#include <stdio.h>
#include <sys/mount.h>

// Mount an HTTP filesystem that reads files from "http://example.com/path/...".
mount("http://example.com/path/", "/mnt/http", "httpfs", 0, "");

// Performs a URL Request of "http://example.com/path/my_image.png".
FILE* file = fopen("/mnt/http/my_image.png", "r");
...

看看 SDK 中的 nacl_io 演示。它位于$NACL_SDK_ROOT/examples/demo/nacl_io

于 2013-10-25T22:57:09.343 回答