我的问题很简单,但我有一个很难找到关于这个网上的任何信息。
是否有可能使用ifstream的打开使用的Android NDK的资产和/或资源文件?
例如,将在/资产的test.txt文件,尝试以下不工作:
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的运营商进入资产或资源文件?
你不能。 资源存储的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
正确的做法是性病:: ifstream的不能用,但我们可以创造一种可以以类似的方式被使用的assetistream。 例如:
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);
}
改进是非常受欢迎的。