我的问题很简单,但我很难在网上找到这方面的任何信息。
是否可以使用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();
也没有任何变量:
std::ifstream fin("assets/test.txt");
std::ifstream fin("test.txt");
等......而不是把它放在/ res中。
那么,是否可以使用普通的ifstream运算符来访问资产和/或资源文件?
答案 0 :(得分:3)
不能使用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);
}
非常欢迎改进。
答案 1 :(得分:1)
要访问这些文件,您需要在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