适用于iOS和Android的C ++文件操作

时间:2012-12-29 23:00:30

标签: c++ ios file-io

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

  1. 查找并删除指定目录中的所有文件。
  2. 查找是否存在给定文件,如果存在,则删除它等等。
  3. 请告诉我一个适用于Android和iOS平台的C ++解决方案/库。

4 个答案:

答案 0 :(得分: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 ++列出目录中的文件。为什么你不能简单地假设某些文件是否存在?我做了一些游戏编程,几乎只需要担心文件系统用于记录目的或加载资产。对于这两者,你几乎可以假设他们的路径是什么。

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

另请查看应在您的平台上提供的statopendir(感谢Ben)。另一个要点是,在dir中列出文件这样的任务通常是你要求你的操作系统内核为你做的事情。

另一个回答者提到的更高级别的方法是Boost Filesystem,这是一个坚实的选择,因为Boost通常是:看看this directory iteration example

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

你也可以从你的C ++程序中exec ls程序。

答案 1 :(得分:1)

答案 2 :(得分:0)

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

有关如何使用Boost以跨平台方式操作文件和目录的详细信息,请参阅SO上的this answer

例如,这里是来自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;
 }

答案 3 :(得分: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)包围:)