次のように、C++ で特定のファイル操作を実行する必要があります。
- 特定のディレクトリ内のすべてのファイルを検索して削除します。
- 特定のファイルが存在するかどうかを検索し、存在する場合は削除します。
Android と iOS プラットフォームの両方で動作する C++ ソリューション/ライブラリを教えてください。
C++ を使用すると、ファイルのやり取りを行うことができます。
C++ を使用した C スタイルのファイル処理を少し採用した FileReader クラスを紹介します。
// BEGIN HEADER
#include <stdio.h>
#include <exception>
#include <stdexcept>
#define DISALLOW_COPY(type) \
type(const type&); \
void operator=(const type&)
class FileReader { // RAII applies to file contents
FILE *file; // c-style open/close
DISALLOW_COPY(FileReader);
protected:
unsigned char *data; // local copy
long size;
public:
FileReader(const char *filename);
~FileReader();
unsigned long getSize();
unsigned char *getFileData();
};
// END HEADER
FileReader::FileReader(const char *filename) {
file = NULL; data = NULL;
if (!(file = fopen(filename, "rb"))) { throw std::runtime_error(std::string("File could not be opened: ")+filename); }
fseek(file,0,SEEK_END);
size = ftell(file);
rewind(file);
data = new unsigned char [size];
VERIFY(size == (long)fread(data, 1, size, file)); // debug macro (just ignore it)
fclose(file);
#ifdef DEBUG
PRINT("FileReader opening file "); printf("%s, %ld bytes.\n",filename,size);
#endif
}
FileReader::~FileReader() {
delete[] data;
}
unsigned char *FileReader::getFileData() { return data; }
unsigned long FileReader::getSize() { return size; }
可能であれば、C++ を使用してディレクトリ内のファイルを一覧表示することは避けたいと思われることに注意してください。特定のファイルが存在するかどうかを単純に推測できないのはなぜですか? 私はゲームのプログラミングを少しやったことがありますが、ファイルシステムについて心配する必要があるのは、ほとんどの場合、ロギング目的またはアセットの読み込み時だけです。これらの両方について、それらのパスが何であるかをほとんど推測することができます。
さらに、ファイルを削除するためのremove 関数を確認することもできます。目的のタスクを実行するための C++ の生のコードを思い付くことができませんls
。私はそのようなタスクを実行するために C++ を使用しません (ヒント:ls
はかなりきちんとしたプログラムです)。
また、あなたのプラットフォームで利用できるはずのstat
and (Ben に感謝) も見てください。opendir
もう 1 つのポイントは、dir 内のファイルを一覧表示するなどのタスクは、通常、OS カーネルに実行を依頼することです。
別の回答者が言及したより高レベルのアプローチは、Boost Filesystem です。Boost が通常そうであるように、これは堅実な選択です。このディレクトリ反復の例を見てください。
ゲーム プログラミングの観点からすると、私は Lua のようなものに頼る傾向がありましたos()
。たとえば、Python プログラムがある場合os.system("ls")
、プログラムが利用可能であると仮定して、ディレクトリの内容を取得するようなことを行うことができls
ます。
C++ プログラムからプログラムexec
することもできます。ls
ブーストファイルシステムは問題ありません。iOS バージョンと clang++。ブーストと NDK .
よく使われているBoostライブラリを試してみてください。iOSとAndroidで動作します。
Boost を使用してクロス プラットフォームの方法でファイルとディレクトリを操作する方法の詳細については、SO に関するこの回答を参照してください。
たとえば、特定のファイルが存在するかどうかを確認し、ディレクトリを再帰的に確認する Boost Web サイトのコードを次に示します。
#include "boost/filesystem/operations.hpp"
#include "boost/filesystem/path.hpp"
#include "boost/progress.hpp"
#include <iostream>
namespace fs = boost::filesystem;
int main( int argc, char* argv[] )
{
boost::progress_timer t( std::clog );
fs::path full_path( fs::initial_path<fs::path>() );
if ( argc > 1 )
full_path = fs::system_complete( fs::path( argv[1] ) );
else
std::cout << "\nusage: simple_ls [path]" << std::endl;
unsigned long file_count = 0;
unsigned long dir_count = 0;
unsigned long other_count = 0;
unsigned long err_count = 0;
if ( !fs::exists( full_path ) )
{
std::cout << "\nNot found: " << full_path.file_string() << std::endl;
return 1;
}
if ( fs::is_directory( full_path ) )
{
std::cout << "\nIn directory: "
<< full_path.directory_string() << "\n\n";
fs::directory_iterator end_iter;
for ( fs::directory_iterator dir_itr( full_path );
dir_itr != end_iter;
++dir_itr )
{
try
{
if ( fs::is_directory( dir_itr->status() ) )
{
++dir_count;
std::cout << dir_itr->path().filename() << " [directory]\n";
}
else if ( fs::is_regular_file( dir_itr->status() ) )
{
++file_count;
std::cout << dir_itr->path().filename() << "\n";
}
else
{
++other_count;
std::cout << dir_itr->path().filename() << " [other]\n";
}
}
catch ( const std::exception & ex )
{
++err_count;
std::cout << dir_itr->path().filename() << " " << ex.what() << std::endl;
}
}
std::cout << "\n" << file_count << " files\n"
<< dir_count << " directories\n"
<< other_count << " others\n"
<< err_count << " errors\n";
}
else // must be a file
{
std::cout << "\nFound: " << full_path.file_string() << "\n";
}
return 0;
}
Android で作業している場合、Java アクティビティでゲームの一部を作成し、重い作業のほとんどをネイティブの C/C++ コードに委譲することになるでしょう。
したがって、Steven Lu の答えがそのままでは機能しない場合は、Java の File クラスを使用して、任意のディレクトリの下にあるすべてのファイル名を一覧表示し、それを彼のネイティブ ファイル処理クラスに渡して、それを乗り越えることができます。または、Java で処理するだけです。
iOSの場合、おそらくこれは実行されますか?
#include <dirent.h> // directory header
#include <stdio.h>
void listdir (const char *path)
{
// first off, we need to create a pointer to a directory
DIR *pdir = NULL;
pdir = opendir (path); // "." will refer to the current directory
struct dirent *pent = NULL;
if (pdir == NULL) // if pdir wasn't initialised correctly
{ // print an error message and exit the program
printf ("\nERROR! pdir could not be initialised correctly");
return; // exit the function
} // end if
while (pent = readdir (pdir)) // while there is still something in the directory to list
{
if (pent == NULL) // if pent has not been initialised correctly
{ // print an error message, and exit the program
printf ("\nERROR! pent could not be initialised correctly");
return; // exit the function
}
// otherwise, it was initialised correctly. let's print it on the console:
printf ("%s\n", pent->d_name);
}
// finally, let's close the directory
closedir (pdir);
}
/** EXAMPLE USAGE **/
int main ()
{
listdir ("C:\\");
return 0;
}
しかし、私が言ったように、AndroidManifest.xml ファイル内のユーザーのファイルをいじりたい場合は、SD_CARD と INTERNAL_STORAGE にアクセスするためのアクセス許可を要求する必要があるため、Android ではより大きな問題が発生します。ほとんどの場合、ゲームをネイティブアプリ (実行可能バイナリ) ではなく APK として出荷する必要があるため、ほとんどのものは /data/data/your.package.name フォルダーに置かれます。
したがって、Android と ios のライブラリは実際には必要ありません。後で Android の Java (Activity) でラップする iOS で実行できるライブラリが必要です :)