В Windows существует несколько способов хранить настройки программы. Реестр, ini файлы, другие типы файлов (по усмотрению разработчика). Порой удобнее одно, порой другое… У каждого подхода есть свои преимущества и свои недостатки. Предлагаю разобраться что лучше и предложить альтернативу, сочетающую в себе преимущества нескольких подходов.
Реестр удобен тем, что настройки лежат все в одном месте и не болтаются рядом с программой. Но не совсем удобно если нужно использовать несколько копий одних и тех же программ(утилит), но с разными настройками одновременно. Тогда приходится при написании программы учитывать это и придумывать что-нибудь, что бы реализовать сохранение отдельно для каждой копии программы. Например, выделять ключ реестра, в который будет включено так же название исполняемого файла.
*.ini файлы, а так же другие файлы настроек удобны тем, что хранят настройки той программы, с которой непосредственно находятся. Таким образом, можно держать несколько копий программ с разными настройками (причем, только тогда, когда программы в разных директориях). Но приходится таскать рядом с программой эти файлы. А если программа не большая, в которой достаточно одного exe файла, и никаких лишних файлов и ресурсов больше не требуется, то эти файлы настроек как груз висят над душой.
Хочу рассказать об альтернативном месте, где можно сохранить настройки программы так, что бы рядом с ней не было никаких файлов настроек, и в то же время для каждого exe файла были свои настройки, даже если они находятся в одной директории. Данный способ работает только на NTFS, т.к. используются возможности самой файловой системы.
У файлов в NTFS есть так называемые «файловые потоки».
Каким образом это реализовано? Любая информация о файле, начиная с его имени, разрешений и заканчивая собственно данными, хранящимися в файле, с точки зрения NTFS представляет собой атрибут, хранящийся в собственном потоке (stream).
Обычно у файла один поток — главный. А вообще у любого файла может быть сколько угодно потоков. Многопоточный файл представляет собой разновидность коллекции однопоточных файлов, которая с точки зрения пользователя выглядит как неделимая единица. На самом же деле это набор файлов-потоков, каждый из которых можно независимо создавать, редактировать и удалять. У каждого дополнительного потока есть символьное имя, через которое можно обращаться к данным в этом потоке. Например «Program.exe:stream». Сам поток создается при первом открытии на запись и дальше можно работать с ним как с обычным файлом.
Вот пример кода на С++, для работы с потоком.
Аналогично для записи в поток.
Таким образом, мы получаем возможность хранить настройки непосредственно в самом исполняемом файле. Причем эти настройки, никуда не денутся от файла, а так же для каждого exe файла можно сохранять свои индивидуальные настройки. Ну а если требуется разделять настройки по категориям или еще как-то, то можно создавать несколько потоков, для каждого типа настроек.
Данный способ хранения настроек удобен, если приложение не большое и состоит из одного исполняемого файла. А так же хранение настроек в потоке в некотором смысле повышает безопасность, т.к. можно прочитать информацию, только если знать имя потока. А вот узнать какие потоки есть в файле и вообще есть ли они там, не всегда просто. Скорее всего, есть API функции, которые позволяют узнать, какие потоки есть в файле. Но человек совершенно не подозревающий об их существовании данных возможностей не догадается, где хранятся настройки.
Существуют небольшие недостатки данного способа. Надо иметь ввиду, что при переносе такого файла в раздел с другой файловой системой копируется только основной неименованный поток. Имеет смысл использовать такие файлы только с файловой системой NTFS.
Так же если захотим перенести настройки куда-нибудь в отдельное место, то придется писать процедуру экспорта.
Но в остальном я считаю такой способ достаточно гибким и удобным. Получаются портативные приложения с возможностью конфигурации.
Реестр удобен тем, что настройки лежат все в одном месте и не болтаются рядом с программой. Но не совсем удобно если нужно использовать несколько копий одних и тех же программ(утилит), но с разными настройками одновременно. Тогда приходится при написании программы учитывать это и придумывать что-нибудь, что бы реализовать сохранение отдельно для каждой копии программы. Например, выделять ключ реестра, в который будет включено так же название исполняемого файла.
*.ini файлы, а так же другие файлы настроек удобны тем, что хранят настройки той программы, с которой непосредственно находятся. Таким образом, можно держать несколько копий программ с разными настройками (причем, только тогда, когда программы в разных директориях). Но приходится таскать рядом с программой эти файлы. А если программа не большая, в которой достаточно одного exe файла, и никаких лишних файлов и ресурсов больше не требуется, то эти файлы настроек как груз висят над душой.
Хочу рассказать об альтернативном месте, где можно сохранить настройки программы так, что бы рядом с ней не было никаких файлов настроек, и в то же время для каждого exe файла были свои настройки, даже если они находятся в одной директории. Данный способ работает только на NTFS, т.к. используются возможности самой файловой системы.
У файлов в NTFS есть так называемые «файловые потоки».
Каким образом это реализовано? Любая информация о файле, начиная с его имени, разрешений и заканчивая собственно данными, хранящимися в файле, с точки зрения NTFS представляет собой атрибут, хранящийся в собственном потоке (stream).
Обычно у файла один поток — главный. А вообще у любого файла может быть сколько угодно потоков. Многопоточный файл представляет собой разновидность коллекции однопоточных файлов, которая с точки зрения пользователя выглядит как неделимая единица. На самом же деле это набор файлов-потоков, каждый из которых можно независимо создавать, редактировать и удалять. У каждого дополнительного потока есть символьное имя, через которое можно обращаться к данным в этом потоке. Например «Program.exe:stream». Сам поток создается при первом открытии на запись и дальше можно работать с ним как с обычным файлом.
Вот пример кода на С++, для работы с потоком.
void read_settings(){
try{
ifstream file("Program:settings");
char* ProgramTitle = new char[256];
file >> ProgramTitle;
}
catch(...){
//сообщение об ошибке если требуется
}
}
Аналогично для записи в поток.
Таким образом, мы получаем возможность хранить настройки непосредственно в самом исполняемом файле. Причем эти настройки, никуда не денутся от файла, а так же для каждого exe файла можно сохранять свои индивидуальные настройки. Ну а если требуется разделять настройки по категориям или еще как-то, то можно создавать несколько потоков, для каждого типа настроек.
Данный способ хранения настроек удобен, если приложение не большое и состоит из одного исполняемого файла. А так же хранение настроек в потоке в некотором смысле повышает безопасность, т.к. можно прочитать информацию, только если знать имя потока. А вот узнать какие потоки есть в файле и вообще есть ли они там, не всегда просто. Скорее всего, есть API функции, которые позволяют узнать, какие потоки есть в файле. Но человек совершенно не подозревающий об их существовании данных возможностей не догадается, где хранятся настройки.
Существуют небольшие недостатки данного способа. Надо иметь ввиду, что при переносе такого файла в раздел с другой файловой системой копируется только основной неименованный поток. Имеет смысл использовать такие файлы только с файловой системой NTFS.
Так же если захотим перенести настройки куда-нибудь в отдельное место, то придется писать процедуру экспорта.
Но в остальном я считаю такой способ достаточно гибким и удобным. Получаются портативные приложения с возможностью конфигурации.