2

次のように、C++ で特定のファイル操作を実行する必要があります。

  1. 特定のディレクトリ内のすべてのファイルを検索して削除します。
  2. 特定のファイルが存在するかどうかを検索し、存在する場合は削除します。

Android と iOS プラットフォームの両方で動作する C++ ソリューション/ライブラリを教えてください。

4

4 に答える 4

1

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はかなりきちんとしたプログラムです)。

また、あなたのプラットフォームで利用できるはずのstatand (Ben に感謝) も見てください。opendirもう 1 つのポイントは、dir 内のファイルを一覧表示するなどのタスクは、通常、OS カーネルに実行を依頼することです。

別の回答者が言及したより高レベルのアプローチは、Boost Filesystem です。Boost が通常そうであるように、これは堅実な選択です。このディレクトリ反復の例を見てください。

ゲーム プログラミングの観点からすると、私は Lua のようなものに頼る傾向がありましたos()。たとえば、Python プログラムがある場合os.system("ls")、プログラムが利用可能であると仮定して、ディレクトリの内容を取得するようなことを行うことができlsます。

C++ プログラムからプログラムexecすることもできます。ls

于 2012-12-29T23:05:57.350 に答える
1

ブーストファイルシステムは問題ありません。iOS バージョンと clang++ブーストと NDK .

于 2012-12-29T23:23:45.183 に答える
1

よく使われているBoostライブラリを試してみてください。iOSAndroidで動作します。

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;
 }
于 2012-12-29T23:13:18.833 に答える
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 で実行できるライブラリが必要です :)

于 2012-12-29T23:30:02.403 に答える