天天看點

ACE筆記(10) -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 );

}