Nit*_*nai 5 resources android assets ifstream android-ndk
我的问题非常简单,但我很难在网上找到任何关于此的信息.
是否可以使用ifstream使用Android NDK从资产和/或资源中打开文件?
例如,将test.txt文件放在/ assets中并尝试以下操作不起作用:
char pLine[256];
std::ifstream fin("/assets/test.txt");
if(!fin.fail())
{
LOGD( "test.txt opened" );
while( !fin.eof() )
{
fin.getline( pLine, 256 );
LOGD(pLine);
}
}
else
{
LOGD( "test.txt FAILED TO OPEN!" );
}
fin.close();
Run Code Online (Sandbox Code Playgroud)
也没有任何变量:
std::ifstream fin("assets/test.txt");
std::ifstream fin("test.txt");
Run Code Online (Sandbox Code Playgroud)
等等......而不是把它放在/ res中.
那么,是否可以使用普通的ifstream运算符来访问资产和/或资源文件?
不能使用 std::ifstream 是正确的,但是可以创建一个可以以类似方式使用的资产流。例如:
class asset_streambuf: public std::streambuf
{
public:
asset_streambuf(AAssetManager* manager, const std::string& filename)
: manager(manager)
{
asset = AAssetManager_open(manager, filename.c_str(), AASSET_MODE_STREAMING);
buffer.resize(1024);
setg(0, 0, 0);
setp(&buffer.front(), &buffer.front() + buffer.size());
}
virtual ~asset_streambuf()
{
sync();
AAsset_close(asset);
}
std::streambuf::int_type underflow() override
{
auto bufferPtr = &buffer.front();
auto counter = AAsset_read(asset, bufferPtr, buffer.size());
if(counter == 0)
return traits_type::eof();
if(counter < 0) //error, what to do now?
return traits_type::eof();
setg(bufferPtr, bufferPtr, bufferPtr + counter);
return traits_type::to_int_type(*gptr());
}
std::streambuf::int_type overflow(std::streambuf::int_type value) override
{
return traits_type::eof();
};
int sync() override
{
std::streambuf::int_type result = overflow(traits_type::eof());
return traits_type::eq_int_type(result, traits_type::eof()) ? -1 : 0;
}
private:
AAssetManager* manager;
AAsset* asset;
std::vector<char> buffer;
};
class assetistream: public std::istream
{
public:
assetistream(AAssetManager* manager, const std::string& file)
: std::istream(new asset_streambuf(manager, file))
{
}
assetistream(const std::string& file)
: std::istream(new asset_streambuf(manager, file))
{
}
virtual ~assetistream()
{
delete rdbuf();
}
static void setAssetManager(AAssetManager* m)
{
manager = m;
}
private:
static AAssetManager* manager;
};
void foo(AAssetManager* manager)
{
assetistream::setAssetManager(manager);
assetistream as("text/tmp.txt");
std::string s;
std::getline(as, s);
}
Run Code Online (Sandbox Code Playgroud)
改进是非常受欢迎的。
你不能。资产存储在 apk(一个 zip 文件)中。ifstream 无法读取 zip 文件内的内容。
要访问这些文件,您需要在 java 中访问它们并将它们保存在其他地方,或者提取 apk 的内容以获取资产。
这是执行前者的示例。
http://www.itwizard.ro/android-phone-installing-assets-how-to-60.html
这是执行后者的示例。
http://www.anddev.org/ndk_opengl_-_loading_resources_and_assets_from_native_code-t11978.html
归档时间: |
|
查看次数: |
7289 次 |
最近记录: |