Writing into config file using file streams w/o re-opening file.

Feb 12, 2012 at 1:01am
Hello,

I run g++ and Ubuntu.

I need to read and write into a config file that has a few entries with simple format: key=value. When I write new value it can be shorter or longer than the value already in the file. At my understanding, to write into file I have to read and save all file context into a buffer, delete all file context, update the value, and then write everything back into a file from buffer.

I want to open file only once and then read and write into it. I want to avoid closing/opening file every time I need to write into it because it impedes performance.

Could someone suggest what is the best way to do it? Thank you!


Feb 12, 2012 at 4:07am
I want to open file only once and then read and write into it. I want to avoid closing/opening file every time I need to write into it because it impedes performance.
I know how you feel, however, this sounds like premature optimization. Is it really impeding the performance of what you are trying to accomplish? If you really feel like you must read/write in one open then just use an fstream http://www.cplusplus.com/reference/iostream/fstream/.
Feb 12, 2012 at 5:14pm
I am reading & writing data (price quotes) from the remote server over tcp sockets, there is no performance number that would be satisfactory - the faster I do it the better. I need to keep count of incoming and outgoing messages and I need to store the counter into a file in case my application crashes.

This is what I am doing right now. I know how to read from file without file open/close, I do not know how to write into file (which is more critical than reading) without open/close. I certainly googled for it so this is the only solution I found. (Another solution is to delete original file, create another one and rename it, which is probably even slower.)

I'd appreciate any suggestion how to avoid opening/closing file every time I need to write into it.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
class ReadConfigClass
{
      fstream file_stream;
      string file_name;
      .........................
}

ReadConfigClass::ReadConfigClass(string str)
{
    file_name = str;
}

int ReadConfigClass::GetInteger(string key)
{
    string line;
    int value = -1;
    string value_str;

    file_stream.open(file_name.c_str(), ios_base::in );
    if (!file_stream.is_open()) {
        err("ReadConfigClass::GetInteger() error opening config file.");
        return -1;
    }

    while ( getline(file_stream, line) )
    {
        if( line.substr(0,11) == key)
        {
            value_str = line.substr(12);
            value = stoi(value_str);
        }
    }
    file_stream.close();

    return value;
}

int ReadConfigClass::SetInteger(string key, int value)
{
    // Save values that are already in the file.
    int valc = this->GetInteger("clt_seq_num");
    int vals = this->GetInteger("svr_seq_num");
    if( key == "clt_seq_num")
        valc = value;
    if( key == "svr_seq_num")
        vals = value;

    file_stream.open(file_name.c_str(), ios_base::in | ios_base::out | ios_base::trunc);
    if (!file_stream.is_open()) {
        err("ReadConfigClass::SetInteger() error opening config file.");
        return -1;
    }

    // Write.
    file_stream << "clt_seq_num=" << valc << endl << flush;
    file_stream << "svr_seq_num=" << vals << endl << flush;
    file_stream.close();
}
Feb 12, 2012 at 5:21pm
Just came up to me, I guess I can use a placeholder in config file:
clt_seq_num=000001
svr_seq_num=000001
Feb 12, 2012 at 6:26pm
> there is no performance number that would be satisfactory - the faster I do it the better.

Map the file into process memory?

Portable: boost::Iostreams::mapped_file
http://www.boost.org/doc/libs/1_48_0/libs/iostreams/doc/index.html

Unix: mmap, msync and friends
http://www.freebsd.org/cgi/man.cgi?query=mmap&apropos=0&sektion=0&manpath=FreeBSD+9.0-RELEASE&arch=default&format=html

Windows: MapViewOfFile and friends
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366761(v=vs.85).aspx

Feb 12, 2012 at 6:57pm
mmap will work (I am on Ubuntu) - thank you!
Topic archived. No new replies allowed.