2

我需要在 C++ 中执行某个文件操作,如下所示:

  1. 查找并删除给定目录中的所有文件。
  2. 查找给定文件是否存在,如果存在,则删除它等。

请告诉我一个适用于 android 和 iOS 平台的 C++ 解决方案/库。

4

4 回答 4

1

C++ 为您提供了文件交互的规定。

我将向您展示我的 FileReader 类,该类使用 C++ 处理一些 C 风格的文件。

// 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++ 列出目录中的文件。为什么你不能简单地假设某些文件是否存在?我已经完成了一些游戏编程,几乎唯一需要担心文件系统的时间是用于记录目的或加载资产。对于这两者,您几乎可以假设它们的路径是什么。

此外,您可能需要查看删除文件的删除功能。我想不出任何 C++ 中的原始代码来执行该任务ls。我不会使用 C++ 来完成这样的任务(提示:ls是一个非常简洁的程序)。

还请查看statopendir(感谢 Ben)应该在您的平台上可用。另一点要说明的是,诸如在目录中列出文件之类的任务通常是您要让操作系统内核为您做的事情。

另一个回答者提到的更高级的方法是 Boost Filesystem,这是一个可靠的选择,因为 Boost 通常是:看一下这个目录迭代示例

从游戏编程的角度来看,我倾向于依赖 Lua 之类的东西os()。例如,如果您有一个 Python 程序,那么os.system("ls")假设您有一个可用的程序,您可以执行类似获取您的目录内容的ls操作。

您也可以exec使用lsC++ 程序中的程序。

于 2012-12-29T23:05:57.350 回答
1

您可以尝试使用Boost库,这似乎是一个流行的选择。它在iOSAndroid上运行。

有关如何使用 Boost 以跨平台方式操作文件和目录的更多信息,请参阅SO 上的此答案。

例如,这里有一些来自 Boost 网站的代码,用于检查特定文件是否存在,在目录中递归检查:

#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 回答
1

Boost 文件系统非常适合您。iOS 版本和 clang++升压和 NDK

于 2012-12-29T23:23:45.183 回答
0

如果您正在为 Android 工作,您可能会在 Java Activity 中编写一些游戏,然后将大部分繁重的工作委托给您的本地 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;
}

但就像我说的,Android 会给你带来更大的问题,因为如果你想弄乱 AndroidManifest.xml 文件中的用户文件,你需要请求访问 SD_CARD 和 INTERNAL_STORAGE 的权限。主要是因为您的大部分内容都在 /data/data/your.package.name 文件夹中,因为您必须将游戏作为 APK 而不是本机应用程序(可执行二进制文件)发布

因此,您实际上并不需要一个 android 和 ios 库,您需要一个可以在 iOS 上运行的库,稍后您将使用 Android 的 Java (Activity) 来包装它:)

于 2012-12-29T23:30:02.403 回答