天天看點

ACE筆記(1)-ACE檔案操作

        ACE裡的檔案操作與平常的Win32裡面的檔案操作有所不同,這是因為ACE是為網絡開發而設計的,裡面普遍都遵循了Client/Server模式,這樣在操作檔案時,ACE把檔案看做是一個Socket伺服器,而進行檔案操作的類(ACE_FILE_IO)被看做是一個Socket Client。

        有了上面的認識,使用ACE的檔案操作就容易了解了:

        調用ACE_FILE_IO.send(...)其實就是進行寫檔案的操作;

        調用ACE_FILE_IO.recv(...)其實就是進行檔案的讀操作。

       ACE裡面的檔案操作類主要包括:ACE_IO_SAP、ACE_FILE、ACE_FILE_IO、ACE_FILE_Connector。

       ACE_FILE_Connector是一個用來産生ACE_FILE_IO的類工廠。

      ACE_FILE_IO繼承于ACE_FILE,ACE_FILE繼承于ACE_IO_SAP。

      ACE_FILE隻能夠對檔案進行一些整體性的操作,如:關閉檔案(close)、删除檔案(remove/ulink)、擷取檔案屬性(get_info)、設定檔案大小(truncate)、定位或擷取檔案遊标位置(seek/position/tell)、擷取檔案路徑(get_local_addr/get_remote_addr)。

      ACE_FILE_IO則能夠進行檔案的讀寫操作,如:多個版本的send/recv, send_n/recv_n,  sendv/recvv,  sendv_n/recvv_n

      ACE_FILE_Connector實際是為了使ACE_FILE類族能夠符合Connector/Acceptor設計模式而設計的,隻是沒有相應的Acceptor。

示例代碼如下:

#include "ace/OS_main.h"

#include "ace/FILE_Addr.h"

#include "ace/FILE_Connector.h"

#include "ace/FILE_IO.h"

#include "ace/OS_NS_string.h"

#include "ace/OS_NS_stdio.h"

ACE_RCSID(FILE_SAP, client, "client.cpp,v 4.16 2003/11/01 11:15:23 dhinton Exp")

int

ACE_TMAIN (int argc, ACE_TCHAR *argv[])

{

  if (argc < 3 || argc > 3)

    ACE_ERROR_RETURN ((LM_ERROR,

                       "usage: %s filename string/n",

                       argv[0]),

                      1);

  ACE_TCHAR *readback = new ACE_TCHAR[ACE_OS::strlen (argv[1]) + 1];

  readback[ACE_OS::strlen (argv[1])] = '/0';

  ACE_TCHAR *filecache = new ACE_TCHAR[1024];

  ACE_FILE_Info fileinfo;

  ACE_FILE_IO cli_file;

  ACE_FILE_IO file_copy;

  ACE_FILE_Connector con;

  if (con.connect (cli_file,

                   ACE_FILE_Addr (argv[1]),

     0,

                   ACE_Addr::sap_any, 0,

     O_RDWR|O_APPEND|O_CREAT,

                   ACE_DEFAULT_FILE_PERMS) == -1)

    ACE_ERROR_RETURN ((LM_ERROR,

                       "%p/n to %s",

                       "connect",

                       argv[1]),

                      -1);

  if (con.connect ( file_copy,

     ACE_FILE_Addr ("testfile_cpy.bak"),

     0,

     ACE_Addr::sap_any, 0,

     O_RDWR|O_APPEND|O_CREAT,

     ACE_DEFAULT_FILE_PERMS) == -1)

   ACE_ERROR_RETURN ((LM_ERROR,

     "%p/n to %s",

     "connect",

     "testfile_cpy.bak"),

     -1);

  ssize_t len = ACE_OS::strlen (argv[2]) + 1;

  if (cli_file.send (argv[2], len) != len)

    ACE_ERROR_RETURN ((LM_ERROR,

                       "%p/n",

                       "send"),

                      1);

  if (cli_file.get_info (&fileinfo) == -1)

    ACE_ERROR_RETURN ((LM_ERROR,

                       "%p/n",

                       "get_info"),

                      1);

  else

    ACE_OS::printf ("fileinfo : mode = %o/nno of links = %lu/nsize = %lu/n",

                    (u_int) fileinfo.mode_ & 0777,

                    ACE_static_cast(u_long ,fileinfo.nlink_),

                    (u_long) fileinfo.size_);

  off_t fpos = cli_file.position ();

  if (fpos == -1)

    ACE_ERROR_RETURN ((LM_ERROR,

                       "%p/n",

                       "position"),

                      1);

  else

    ACE_OS::printf ("current filepointer is at %ld/n",

                    (long int) fpos);

  if (cli_file.position (0,

                         SEEK_SET) == -1)

    ACE_ERROR_RETURN ((LM_ERROR,

                       "%p/n",

                       "position"),

                      1);

  unsigned long lfsize = (u_long) fileinfo.size_;

  if (lfsize <= 1024)

  {

  if (cli_file.recv(filecache, lfsize) != lfsize)

   ACE_ERROR_RETURN ((LM_ERROR,

        "%p/n",

        "recv"),

        1);

  if (file_copy.send (filecache, lfsize) != lfsize)

   ACE_ERROR_RETURN ((LM_ERROR,

       "%p/n",

       "send"),

       1);

  }

  else

  {

   unsigned int uiTemp = lfsize;

   while (uiTemp - 1024 >= 0)

   {

   if (cli_file.recv(filecache, 1024) != 1024)

    ACE_ERROR_RETURN ((LM_ERROR,

         "%p/n",

         "recv"),

         1);

   if (file_copy.send (filecache, 1024) != 1024)

    ACE_ERROR_RETURN ((LM_ERROR,

        "%p/n",

        "send"),

        1);

   uiTemp -= 1024;

   }

  }

  if (cli_file.recv (readback, len) != len)

    ACE_ERROR_RETURN ((LM_ERROR,

                       "%p/n",

                       "recv"),

                      1);

  ACE_OS::printf ("read back :%s/n",

                  ACE_TEXT_ALWAYS_CHAR(readback));

  if (cli_file.close () == -1 || file_copy.close() == -1)

    ACE_ERROR_RETURN ((LM_ERROR,

                       "%p/n",

                       "close"),

                      1);

  return 0;

}

 除了上面提供的基本檔案操作類外,ACE還提供了對配置檔案進行操作的類,如對INI檔案進行操作,當然也可以對XML檔案進行操作

 對INT檔案進行操作的相關類如下:

 ACE_Configuration_Heap 用于獲得配置檔案的資訊

 ACE_Ini_ImpExp 用于導入配置檔案資訊

  ACE_Configuration_Section_Key 用于定位配置檔案的章節

  示例如下:

CIniFile.h 檔案

#ifndef CINIFILE

#define CINIFILE

#include "ace/Configuration.h"

#include "ace/Configuration_Import_Export.h"

class CIniFile

{

public:

 ~CIniFile();

 //傳回0表打開成功,-1表打開配置檔案失敗,-2表不存在【CRB】章節

 int open(const ACE_TCHAR * filename);

 int GetKeyValue(const ACE_TCHAR * name,ACE_TString &value);

protected:

private:

 ACE_Configuration_Section_Key root_key_;

 ACE_Ini_ImpExp * impExp_;

 ACE_Configuration_Heap config;

 //ACE_TCHAR[1000] tmp_;

};

#endif

CIniFile.cpp 檔案

#include "CIniFile.h"

CIniFile::~CIniFile(){

 delete this->impExp_;

}

int CIniFile::open(const ACE_TCHAR * filename){

 this->config.open();

 this->impExp_=new ACE_Ini_ImpExp(config);

 if (this->impExp_->import_config(filename)==-1){

  return -1;

 }

 if (config.open_section(config.root_section(),ACE_TEXT("CRB"),0,this->root_key_)==-1){

  return -2;

 }

 return 0;

}

int  CIniFile::GetKeyValue(const ACE_TCHAR * name,ACE_TString &value){

 return config.get_string_value(this->root_key_,name,value);

}