JAVA basics: benefits of using the Properties class

Source: Internet
Author: User
JAVA basics: benefits of using the Properties class-general Linux technology-Linux programming and kernel information. For more information, see the following. Many developers complain that C ++ cannot bind the Properties class as Java does. The Properties class of Java contains a file which is used to read and write Properties in the Properties class. It can be written as follows: <名字> = <数值> (For example, ConnectToInternet = Use IE ).

The advantage of using the Properties class is that you can easily understand and modify them. In the first part of this article, you will see that we can also use the Properties class in C ++. The second part of this article will show you how to use the operators >>and < <把数据保存到properties类中是多么的容易。

Now we will introduce the structure of the C ++ Properties file. Each row of the file can be one of the following three situations:

Empty line (think it is part of the comment)

Comment row starting '#'

' <名字> = <数值> 'Row. This is a statement that assigns a value to an attribute.

Now let's take a look at the features of the Properties class:

Annotations are persistent (they are not lost when the Properties class is saved ). Note that each comment belongs to a certain attribute. In' <名字> = <数值> 'Line comment row belongs to this' <名字> 'Property.

After the Properties class is saved, the attributes are retained.

It is effective for various character types: char, wchar_t, etc.

The use of the Properties class is quite simple:

Save (): save attributes

Has_property (strPropertyName): If the class has this property, 'true' is returned'

String get_property (strPropertyName): returns the specified property (if the specified property does not exist, an exception is thrown)

Set_property (strPropertyName, strPropertyValue): Set the given property

Stringget_property_comment (strPropertyName): returns the comment that belongs to the specified attribute. (If the comment of the specified attribute does not exist, an exception is thrown)

Set_property_comment (strPropertyName, strPropertyComment): sets the comment for the specified attribute. (If the comment for the specified attribute does not exist, an exception is thrown)

The following is the code of the file_reader_writer class and the corresponding example. After running the command, copy the properties.txt file. Let's see how easy it is to access and modify it.


# Include exception>

# Include string>

# Include sstream>

# Include map>

# Include vector>

# Include fstream>

# Include algorithm>

# Include functional>

// Allow String Conversion

Template <class FromCharType, class ToCharType>

Inline std: basic_string <ToCharType> convert_string (const std: basic_string <FromCharType> & strSource)

{

Std: basic_string <ToCharType> strDest;

Int nSourceLen = strSource. length ();

StrDest. resize (nSourceLen );

For (int idxChar = 0; idxChar <nSourceLen; idxChar ++)

{StrDest [idxChar] = (ToCharType) strSource [idxChar];}

Return strDest;

}

// Used for trim_spaces;

Template <class CharType>

Struct is_char_in_str: public std: binary_function <CharType, std: basic_string <CharType>, bool>

{

Bool operator () (CharType ch, const std: basic_string <CharType> & strSource) const

{Return (strSource. find (ch )! = Std: basic_string <CharType >:: npos );}

};



// Remove spaces in the string

Template <class CharType>

Std: basic_string <CharType> trim_spaces (const std: basic_string <CharType> & strSource)

{

Std: basic_string <CharType> strSpaces; strSpaces + = (CharType) ''; strSpaces + = (CharType) '\ T ';

Typedef std: basic_string <CharType> string_type;

String_type: const_iterator

ItFirst = std: find_if (strSource. begin (), strSource. end (),

Std: not1 (std: bind2nd (is_char_in_str <CharType> (), strSpaces )));

String_type: const_reverse_iterator

RitLast = std: find_if (strSource. rbegin (), strSource. rend (),

Std: not1 (std: bind2nd (is_char_in_str <CharType> (), strSpaces )));

String_type: const_iterator itLast = & * ritLast;

If (itFirst <= itLast)

If (itFirst! = StrSource. end ())

Return string_type (itFirst, itLast + 1 );

Return string_type ();

}

// Exception when reading/writing attributes

Class properties_exception: public std: exception

{

Public:

Properties_exception (const std: string & str): m_strDescription (str ){}

Const char * what () const {return m_strDescription.c_str ();}

Private:

Std: string m_strDescription;

};



// Read/write attributes from a file

Template <class CharType>

Class file_reader_writer

{

Typedef std: basic_string <CharType> string_type;

Public:

//... Needed within the basic_properties!

Typedef CharType char_type;

Public:

File_reader_writer (const char * strFileName)

: M_bIsDirty (false), m_strFileName (strFileName) {read_properties ();}

~ File_reader_writer () {save ();}

Void save ()

{Write_properties ();}

Bool has_property (const string_type & strPropertyName) const

{

PropertiesCollection: const_iterator itFound = m_collProperties.find (strPropertyName );

Return (itFound! = M_collProperties.end ());

}

Const string_type & get_property (const string_type & strPropertyName) const

{

PropertiesCollection: const_iterator itFound = m_collProperties.find (strPropertyName );

If (itFound! = M_collProperties.end ())

Return itFound-> second. m_strValue;

Else

Throw properties_exception (

"Cound not get property value for '" + convert_string <char_type, char> (strPropertyName) +

"', Since this property does not exist .");

}



Void set_property (const string_type & strProperty, const string_type & strPropertyValue)

{

PropertiesCollection: iterator itFound = m_collProperties.find (strProperty );

If (itFound = m_collProperties.end ())

// It is a new property

M_aProperties.push_back (strProperty );

M_collProperties [strProperty]. m_strValue = strPropertyValue;

M_bIsDirty = true;

}



Const string_type & get_property_comment (const string_type & strPropertyName) const

{

PropertiesCollection: const_iterator itFound = m_collProperties.find (strPropertyName );

If (itFound! = M_collProperties.end ())

Return itFound-> second. m_strComment;

Else

Throw properties_exception (

"Cound not get property comment for '" + convert_string <char_type, char> (strPropertyName) +

"', Since this property does not exist .");

}



Void set_property_comment (const string_type & strPropertyName, const string_type & strPropertyComment)

{

PropertiesCollection: iterator itFound = m_collProperties.find (strPropertyName );

If (itFound! = M_collProperties.end ())

ItFound-> second. m_strComment = strPropertyComment;

Else

Throw properties_exception (

"Cound not set property comment for '" + convert_string <char_type, char> (strPropertyName) +

"', Since this property does not exist .");

M_bIsDirty = true;

}



Private:

Static const char_type get_delimeter () {return '= ';}

Static const char_type get_comment () {return '#';}

Void read_properties ()

{

Const char DELIMETER = get_delimeter ();

Const char COMMENT = get_comment ();

Std: basic_ifstream <char_type> streamIn (m_strFileName.c_str ());

String_type strLine;

String_type strComment;

While (std: getline (streamIn, strLine ))

{

StrLine = trim_spaces (strLine );

Bool bIsComment = strLine. empty () | (strLine [0] = COMMENT );

If (bIsComment)

{StrComment + = strLine; strComment + = '\ n ';}

Else

{

Int idxDelimeter = strLine. find (DELIMETER );

If (idxDelimeter! = String_type: npos)

{

String_type strPropertyName = strLine. substr (0, idxDelimeter );

String_type strPropertyValue = strLine. substr (idxDelimeter + 1 );

StrPropertyName = trim_spaces (strPropertyName );

StrPropertyValue = trim_spaces (strPropertyValue );

M_collProperties.insert (

Std: make_pair (strPropertyName, OneProperty (strPropertyValue, strComment )));

M_aProperties.push_back (strPropertyName );

StrComment. erase ();

}

Else

Throw properties_exception (

"While reading from file'" + m_strFileName +

"', We encountered an invalid line: \ n" + convert_string <char_type, char> (strLine ));

}

}

M_strLastComment = strComment;

}



Void write_properties () const

{

If (! M_bIsDirty)

// No need to save

; Return;

Const char DELIMETER = get_delimeter ();

Std: basic_ofstream <char_type> streamOut (m_strFileName.c_str ());

PropertiesArray: const_iterator

ItFirst = m_aProperties.begin (), itLast = m_aProperties.end ();

While (itFirst! = ItLast)

{

Const string_type & strPropertyName = * itFirst;

Const OneProperty & property = m_collProperties.find (strPropertyName)-> second;

Write_property_comment (streamOut, property. m_strComment );

String_type strToWrite = strPropertyName;

StrToWrite + = ''; strToWrite + = DELIMETER; strToWrite + = '';

StreamOut strToWrite <property. m_strValue <std: endl;

++ ItFirst;

}

Write_property_comment (streamOut, m_strLastComment );

M_bIsDirty = false;

}



Void write_property_comment (std: basic_ofstream <char_type> & streamOut, const string_type & strComment) const

{

Const char COMMENT = get_comment ();

Std: basic_stringstream <char_type> streamComment (strComment );

String_type strLine;

While (std: getline (streamComment, strLine ))

{

If (! StrLine. empty ())

If (strLine [0] = COMMENT)

StreamOut <strLine <std: endl;

Else

{

String_type strPrefix;

StrPrefix + = COMMENT; strPrefix + = '';

StreamOut <strPrefix <strLine <std: endl;

}

Else

StreamOut <std: endl;

}

}



Private:

// The file we use to read and write

Std: string m_strFileName;

// If the attribute is modified after the last save, the value is "true"

Mutable bool m_bIsDirty;



Struct OneProperty

{

OneProperty (){}

OneProperty (const string_type & strValue, const string_type & strComment)

: M_strValue (strValue), m_strComment (strComment ){}

String_type m_strValue;

String_type m_strComment;

};

// Attributes

Typedef std: map <string_type, OneProperty> PropertiesCollection;

PropertiesCollection m_collProperties;

//...... Make sure that attributes are saved in the same order.

// Read attributes

Typedef std: vector <string_type> PropertiesArray;

PropertiesArray m_aProperties;

// Read comments after all attributes

String_type m_strLastComment;

};



The following is an example of using this class:



# Include

Int main (int argc, char * argv [])

{

File_reader_writer <char> rw ("properties.txt ");

Rw. set_property ("App Path", "C: \ Program Files \ PFS \ jokExplorer ");

Rw. set_property_comment ("App Path", "where are we installed? ");

Rw. set_property ("Version", "4.0.0.1 ");

Rw. set_property_comment ("Version", "What's our version? ");

Rw. set_property ("Run On Startup", "1 ");

Rw. set_property_comment ("Run On Startup", "are we run, when the computer starts? ");

Rw. set_property ("Automatic Logoff Minutes", "60 ");

Rw. set_property_comment ("Automatic Logoff Minutes", "when shoshould we deconnect from the server? ");

Rw. set_property ("Connect To Internet", "Use IE ");

Rw. set_property_comment ("Connect To Internet", "how are we going to connect to the Internet? ");

Std: cout <"This is how we connect to Internet:" <rw. get_property ("Connect To Internet") <std: endl;

Return 0;

}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.