![]() | |
Filename extension | .ini |
---|---|
Internet media type | text/plain, application/textedit, zz-application/zz-winassoc-ini |
Type of format | Initialization/Configuration File |
AnINI file is aconfiguration file forcomputer software that consists ofplain text with a structure and syntax comprisingkey–value pairs organized in sections.[1] The name of these configuration files comes from thefilename extensionINI, short forinitialization, used in theMS-DOS operating system which popularized this method of software configuration. The format has become an informal standard in many contexts of configuration, but many applications on other operating systems use different file name extensions, such asconf andcfg.[2]
The primary mechanism of software configuration inWindows was originally a text file format that comprised text lines with one key–value pair per line, organized into sections. This format was used for operating system components, such as device drivers, fonts, and startup launchers. INI files were also generally used by applications to store individual settings.[3]
The format was maintained in 16-bitMicrosoft Windows platforms up throughWindows 3.1x. Starting withWindows 95 Microsoft favored the use of theWindows Registry and began to steer developers away from using INI files for configuration. All subsequent versions of Windows have used the Windows Registry for system configuration, but applications built on the .NET Framework use specialXML.config files. The initialization-file functions are still available in Windows and developers may still use them.
Besides Windows software, platform-agnostic software may use this file format for configuration. SomeUnix-like config files also use a similar format. INI ishuman-readable and simple to parse, so it is a usable format for configuration files that do not require much greater complexity.
What follows is a non-exhaustive list of places in which INI files appear.
Desktop.ini
files are still used in Windows to configure properties of directories, e.g. specifying the icon for a folder.[4][5]php.ini
file employs the INI format.[6][7].git/config
file is written in an INI flavour.[8]*.desktop
entries are written in an INI flavour.[9]*.service
unit configuration files are written in INI.[10]afp.conf
file is written in an INI-style configuration language.[11]pacman.conf
file is written in INI.[12]app.ini
configuration file is written in INI.[13]The following example file has two sections: one for the owner of the software, and one for a payroll database connection. Comments record the last person who modified the file and the reason for modification.
; last modified 1 April 2001 by John Doe[owner]name=John Doeorganization=Acme Widgets Inc.[database]; use IP address in case network name resolution is not workingserver=192.0.2.62port=143file="payroll.dat"
In its broader sense, INI is an informal format which lends itself well to ad-hoc implementation while remaining human-configurable. Consequently, many varying specifications (where sometimes a parser implementation is the only specification ever written) exist, calledINI dialects.
INI interpretations depend a lot on personal taste and the needs of the computing environment, such as whitespace preservation, field type information, case sensitivity, or preferred comment delimiters. This makes INI prone to proliferation. Nonetheless,INI-flavoured implementations typically share common design features: a text file consisting of akey-value pair on each line, delimited by anequals sign, organized into sections denoted by square brackets.
Attempts to create parsers able to support as many dialects as possible exist,[14] and in its most complicated interpretation, the INI format is able to express arbitraryS-expressions, making it equivalent to standardised formats likeXML orJSON, albeit with a syntax which is not set in stone and to some may feel more comfortable.
As the INI file format is not rigidly defined, many parsers support features beyond those that form the common core.Implemented support is highly volatile.
Data in INI is held in key-value pairs calledkey orproperty.Key may thus either refer to the entire key-value pair or only its key. A value is also calledproperty name. In its textual representation, the key-value pair is represented by either a line or a multiline where the start of the value is indicated by adelimiter, most often anequals sign (=
, ASCII 0x3D) but sometimes also a colon (:
, ASCII 0x3A) or whitespace (occasionally used in the GNU world[14]). The key's key appears to the left of the delimiter, is often non-empty and should not contain the delimiter. Some flavours allow escape sequences in the value.
In the Windows implementation, the equals sign and the semicolon are reserved characters and cannot appear in the key. Any whitespace surrounding the key is stripped by the parser. The value can contain any character (in Windows-style, no whitespace surrounds the delimiter: e.g.IconFile=Folder.ico
).
Key-value pairs may textually look like:
key=key=vname=valuesem=;semver=v5822.433.2
Key-value pairs may be grouped under asection. Some INI dialects require every key-value pair to be in a section, some allow so-calledglobal properties.[15] When key-value pairs are grouped, the section name appears on a line by itself, enclosed insquare brackets ([
, ASCII 0x5B, and]
, ASCII 0x5D), and applies to all key-value pairs on subsequent lines until another section is declared. There is no explicit "end of section" delimiter (such as e.g. XML's</tag>
). Thus, sections syntactically cannot be arbitrarily nested. When required, nesting can be implemented through flattening one's hierarchy and concatenating with a custom delimiter character inside the section name (often.
, ASCII 0x2E). One level of nesting is often supported, calledsubsections.
Exemplary INI document employing nested sections:
[project]name=orchard rental service (with app)target region="Bay Area"; TODO: advertise vacant positionslegal team=(vacant)[fruit "Apple"]trademark issues=foreseeabletaste=known[fruit.Date]taste=novelTrademark Issues="truly unlikely"[fruit "Raspberry"]anticipated problems="logistics (fragile fruit)"Trademark Issues=\possible[fruit.raspberry.proponents.fred]date=2021-11-23, 08:54 +0900comment="I like red fruit."[fruit "Date/proponents/alfred"]comment:Why,\\\I would buy dates.# folding: Is "\\\\\nn" interpreted as "\\n" or "\n"?# Or does "\\\\" prevent folding?editor=My name may contain a \\newline.
Some parsers allow section nesting, using dots as path delimiters:
[section]domain=example.com[section.subsection]foo=bar
In some cases relative nesting is supported too, where a leading dot expresses nesting to the previous section:[14]
[section]domain=example.com[.subsection]foo=bar
Historically, ways for expressing nesting alternative to the dot have existed too (for example, IBM's driver file for Microsoft Windowsdevlist.ini
, in which thebackslash was used as nesting delimiter in the form of[A\B\C]
; or Microsoft Visual Studio'sAEMANAGR.INI
file, which used a completely different syntax in the form of[A]
andB,C,P = V
). Some parsers did not offer nesting support at all and were hierarchy-blind, but nesting could still be partially emulated by exploiting the fact that[A.B.C]
constitutes a unique identifier.
Section and property names in Windows arecase insensitive.[16] Most Unix-style INI interpretations forbid case folding altogether, although case folding for the section name[17] or key[18] is sometimes allowed.
A line with contiguous trailing whitespace followed by asemicolon (;
, ASCII 0x3E) indicates acomment. Some INI dialects furthermore allow use of thenumber sign (#
, ASCII 0x23) to denote a comment, mirroring Unixshell comments. Some INI dialects but not all allow a comment on a key-value pair line or section line (calledin-line comment), where some require whitespace separating the value or section closing bracket from the comment. The number sign might be nonetheless included in the key name in some dialects and ignored as such. Comment lines are designed to be ignored by a parser.
#! /bin/convert-ini-to-perl | perl | ssh wikipedia.org upload --sanitise=no; Ambiguous without further knowledge of the INI dialect:; is the value "live" or "live # dangerously"?I like to=live# dangerously#var = avar=a; This is an inline commentfoo=bar# This is another inline comment
Under theWinAPI'sGetPrivateProfileString's dialect, comments must occur on lines by themselves.
The order of properties in a section and the order of sections in a file is irrelevant.
Most implementations only support having one property with a given name in a section. The second occurrence of a property name may cause anabort, it may be ignored (and the value discarded), or it may override the first occurrence (with the first value discarded). Some programs use duplicate property names to implement multi-valued properties.
Interpretation of multiple section declarations with the same name also varies. In some implementations, duplicate sections simply merge their properties, as if they occurred contiguously. Others may abort, or ignore some aspect of the INI file.
Some implementations allow values to be quoted, typically usingdouble quotes and/orapostrophes. This allows for explicit declaration of whitespace, and/or for quoting of special characters (equals, semicolon, etc.). The standard Windows functionGetPrivateProfileString supports this, and will remove quotation marks that surround the values.
EmulatingC syntax, some dialects allow line folding by a backslash (\
, ASCII 0x5C) as the last character on a line.[19] In suchline continuation, backslashes followed immediately by EOL (end-of-line) cause the backslash and line break to be dropped, transforming the document's lines intological lines.
Some dialects offer varying support forcharacter escaping, typically with thebackslash character (\
, ASCII 0x5C) as a metacharacter and emulatingC syntax.[20]
It is not wise to blindly interpret escape sequences as some specifications explicitly mute their metacharacter for common escape sequences.[21][22]
Sequence | Meaning |
---|---|
\\ | \ (a singlebackslash, escaping the escape character) |
\' | Apostrophe |
\" | Double quotes |
\0 | Null character |
\a | Bell/Alert/Audible |
\b | Backspace,Bell character for some applications |
\t | Tab character |
\r | Carriage return |
\n | Line feed |
\; | Semicolon |
\# | Number sign |
\= | Equals sign |
\: | Colon |
\xhhhh | Unicode character withcode point 0xhhhh, encoded either in UTF-8 or local encoding |
Under Windows, theProfile API is the programming interface used to read and write settings from classic Windows.ini
files. For example, theGetPrivateProfileString function retrieves a string from the specified section in an initialization file. (The "private" profile is contrasted withGetProfileString
, which fetches fromWIN.INI.)
The following sampleC program demonstrates reading property values from the above sample INI file (let the name of configuration file bedbsettings.ini
):
#include<windows.h>intmain(intargc,TCHAR*argv[]){TCHARdbserver[1000];intdbport;GetPrivateProfileString(TEXT("database"),TEXT("server"),TEXT("127.0.0.1"),dbserver,sizeof(dbserver)/sizeof(dbserver[0]),TEXT(".\\dbsettings.ini"));dbport=GetPrivateProfileInt(TEXT("database"),TEXT("port"),143,TEXT(".\\dbsettings.ini"));// N.B. WritePrivateProfileInt() does not exist, only WritePrivateProfileString()return0;}
The third parameter of theGetPrivateProfileString
function is the default value, which are"127.0.0.1"
and143
respectively in the two function calls above. If the argument supplied for this parameter isNULL
, the default is an empty string,""
.
Under Unix, many different configuration libraries exist to access INI files. They are often already included in frameworks and toolkits. Examples of INI parsers for Unix includeGLib,iniparser andlibconfini.
Name | Sections support | Section nesting support | Disabled entry recognition[23] | Multi-line support[24] | Value types | Read/Write support | Platform | License | Programming language | Latest release version |
---|---|---|---|---|---|---|---|---|---|---|
Python ConfigParser[25][26] | Yes | Yes | No | Non-standard[27] | Boolean,Number,String | Read + Write | *BSD,Linux,macOS,Windows | PSFL | C (implementation),Python (usage) | 3.9.7[28] |
GLib[29] | Yes | Yes | No | No | Boolean,Number,String,Array | Read + Write | *BSD,Linux,macOS,Windows | LGPL | C | 2.66.7 (February 11, 2021; 4 years ago (2021-02-11)) [±][30] |
inifile[32] | Yes | No | No | No | Boolean,Number,String | Read + Write | *BSD,Linux,macOS,Windows | Apache | Go | 1.2.0[33] |
inih[34] | Yes | No | No | Non-standard[35] | Boolean,Number,String | Read | *BSD,Linux,macOS,Windows | BSD | C | 53[36] |
iniparser[37] | Yes | No | No | Yes | Boolean,Number,String | Read + Write | *BSD,Linux,macOS,Windows | MIT | C | 4.2.4[38] |
Java (viajava.util.Properties )[39] | No | No | No | Yes | String | Read + Write | Platform-agnostic | Dual-license:GPL version 2 with classpath exception,[40] and aproprietary license.[41] | C (implementation),Java (usage) | 23.0.1 (October 15, 2024; 4 months ago (2024-10-15)[42]) [±] |
libconfini[47] | Yes | Yes | Yes | Yes | Boolean,Number,String,Array | Read | *BSD,Linux,macOS,Windows | GPL | C | 1.16.2[48] |
PHP (viaparse_ini_file() )[49] | Yes | Yes | Yes | No | Boolean,Number,String,Null | Read | Linux,macOS,Windows | PHP License v3.01[50] | C (implementation),PHP (usage) | 8.4.4[51] ![]() |
PyINI[52] | Yes | No | Yes | Yes | Boolean,Number,String | Read + Write | Platform-agnostic | GPL | Python | 1.0[53] |
python-ini[54] | Yes | No | No | Yes | Boolean,Number,String,Null | Read + Write | Platform-agnostic | BSD | Python | 1.1.0 |
RudeConfig[55] | Yes | No | No | No | Boolean,Number,String | Read + Write | Linux,Windows | GPL | C++ | Discontinued – last version is 5.0.5, from November 2009[56] |
Windows API | Yes | No | No | No | Number,String,Struct | Read + Write (non-destructive) | Windows | Proprietary | C | 24H2 (10.0.26100.3476) (March 11, 2025; 2 days ago (2025-03-11)[57]) [±] |
Wine (implementation ofWindows API) | Yes | No | No | No | Number,String,Struct | Read + Write (non-destructive) | Linux,macOS,Windows | LGPL | C | 10.0[58] ![]() |
Rust configparser[59] | Yes | No | No | No | Boolean,Number,String | Read + Write | *BSD,Linux,macOS,Windows | MIT orLGPL v3.0+ | Rust | 3.0.2[59] 11 September 2022; 3 months ago |
java-ini-parser[60] | Yes | No | Yes | Yes | Boolean,Number,String | Read + Write | Platform-agnostic | Apache | Java | 1.4[59] 29 December 2022; 3 days ago |
Name | Sections support | Section nesting support | Disabled entry recognition | Multi-line support | Value types | Read/Write support | Platform | License | Programming language | Latest release version |
Initialization file mapping creates a mapping between an INI file and theWindows registry.[61][62] It was introduced with Windows NT and Windows 95 as a way to migrate from storing settings in classic.ini
files to the new registry. File mapping traps the Profile API calls and, using settings from theIniFileMapping Registry section, directs reads and writes to appropriate places in the Registry.
Using the example below, a string call could be made to fetch thename key from theowner section from a settings file called, say,dbsettings.ini
. The returned value should be the string "John Doe":
GetPrivateProfileString("owner","name",...,"c:\\programs\\oldprogram\\dbsettings.ini");
INI mapping takes this Profile API call, ignores any path in the given filename and checks to see if there is a Registry key matching the filename under the directory:
If this exists, it looks for an entry name matching the requested section. If an entry is found, INI mapping uses its value as a pointer to another part of the Registry. It then looks up the requested INI setting in that part of the Registry.
If no matching entry name is found and there is an entry under the(Default) entry name, INI mapping uses that instead. Thus each section name does not need its own entry.
(Default) | @USR:Software\oldprogs\inisettings\all |
database | USR:Software\oldprogs\inisettings\db |
So, in this case the profile call for the [owner] section is mapped through to:
name | John Doe |
organization | Acme Products |
where the "name" Registry entry name is found to match the requested INI key. The value of "John Doe" is then returned to the Profile call. In this case, the @ prefix on the default prevents any reads from going to thedbsettings.ini
file on disk. The result is that any settings not found in the Registry are not looked for in the INI file.
The "database" Registry entry does not have the @ prefix on the value; thus, for the[database]
sectiononly, settings in the Registry are taken first followed by settings in thedbsettings.ini
file on disk.
Starting withWindows 95, Microsoft began strongly promoting the use of the Windows registry over INI files.[63] INI files are typically limited to two levels (sections and properties) and do not handle binary data well. This decision, however, has not been immune to critiques, due to the fact that the registry is monolithic, opaque and binary, must be in sync with the filesystem, and represents asingle point of failure for the operating system.[64]
LaterXML-based configuration files became a popular choice for encoding configuration in text files.[citation needed] XML allows arbitrarily complex levels and nesting, and has standard mechanisms for encodingbinary data.
More recently,data serialization formats, such asJSON,TOML, andYAML can serve as configuration formats. These three alternative formats can nest arbitrarily, but have a different syntax than the INI file. Among them, TOML most closely resembles INI, but the idea to make TOML deliberately compatible with a large subset of INI was rejected.[65]
The newest INI parsers however allow the same arbitrary level of nesting ofXML,JSON,TOML, andYAML, offer equivalent support oftyped values andUnicode, although keep the "informal status" of INI files by allowing multiple syntaxes for expressing the same thing.[66]
php.ini
"a
in the following example:[section]
#a=a
b=b
java.util.Properties
parse_ini_file()
— Parse a configuration file".Official PHP documentation. Retrieved2022-07-19.