The file operations in Ace are different from those in common Win32, because Ace is designed for network development and generally follows the Client/Server mode, in this way, Ace regards the file as a socket server while ace_file_io is regarded as a Socket Client.
With the above understanding, it is easy to understand the file operations using ACE:
Calling ace_file_io.send (...) is actually a file write operation;
Calling ace_file_io.recv (...) is actually reading the file.
The file operation classes in ACE mainly include ace_io_sap, ace_file, ace_file_io, and ace_file_connector.
Ace_file_connector is a class factory used to generate ace_file_io.
Ace_file_io inherits from ace_file and ace_file inherits from ace_io_sap.
Ace_file can only perform some holistic operations on the file, such as close, remove/ulink, get_info, and truncate), locate or obtain the file cursor location (seek/position/tell), and get the file path (get_local_addr/get_remote_addr ).
Ace_file_io can be used to read and write files, for example, send/Recv, send_n/recv_n, sendv/recvv, sendv_n/recvv_n of multiple versions.
Ace_file_connector is designed to make the ace_file class family conform to the connector/acceptor design mode, but there is no corresponding acceptor.
The sample code is as follows:
# 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;
}
In addition to the basic file operation class provided above, ACE also provides a class for operating the configuration file, such as operating the INI file, of course, you can also operate the XML file
The operations on Int files are as follows:
Ace_configuration_heap is used to obtain the configuration file information.
Ace_ini_impexp is used to import configuration file information
Ace_configuration_section_key: Chapter used to locate the configuration file
Example:
Cinifile. h file
# Ifndef cinifile
# Define cinifile
# Include "ACE/configuration. H"
# Include "ACE/configuration_import_export.h"
Class cinifile
{
Public:
~ Cinifile ();
// If Table 0 is successfully opened, table-1 fails to open the configuration file. Table-2 does not contain the Section [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 File
# 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 );
}