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 );
}