Вопрос

Может ли кто-нибудь найти способ немного улучшить этот код?Я хочу одним махом прочитать INI-файл и создать соответствующую структуру данных.

<cfset INIfile = expandPath(".") & "\jobs.ini">
<cfset profile = GetProfileSections(INIfile)>
<cfloop collection="#profile#" item="section">
    <cfloop list="#profile[section]#" index="entry">
        <cfset app.workflow[section][entry]=GetProfileString(INIfile, section, entry) >
    </cfloop>
</cfloop>
Это было полезно?

Решение

Я не верю, что вы можете улучшить это, используя возможности CFML.Вам нужно разобрать огромные ini-файлы?Если нет, то зачем вам улучшать свой код, мне кажется, это довольно просто.

Другой возможный (хотя это обычное решение для CF) — попробовать чистую Java.См. эту тему SO для чистой Java. Примеры.

P.S.Кстати, в случае особых требований к производительности вам следует рассмотреть возможность использования другого хранилища для конфигурации.Простой запрос SELECT к старому доброму MySQL может быть намного быстрее для больших наборов данных.

Другие советы

Чтобы расширить комментарий Райбера, вы можете вместо этого рассмотреть возможность использования этого подхода.Я предполагаю, что вы используете CF8.01 или более позднюю версию, поскольку я использую нотацию вложенной неявной структуры.Это можно было бы легко преобразовать в синтаксис CF7/6/etc, но это было бы не так чисто и лаконично.

Опять же, это применимо только в том случае, если ваш ini-файл не используется другими приложениями или людьми и не нуждаться быть в формате ini.

настройки.cfm:

<cfset variables.settings = {
    fooSection = {
        fooKey = 'fooVal',
        fooNumber = 2,
    },
    fooSection2 = {
        //...
    },
    fooSection3 = {
        //...
    }
} />

Приложение.cfc: (только метод onApplicationStart)

<cffunction name="onApplicationStart">
    <cfinclude template="settings.cfm" />
    <cfset application.workflow = variables.settings />
    <cfreturn true />
</cffunction>

Кроме того, я использовал CFEncode приложение для шифрования содержимого settings.cfm.Это не защитит вас от того, кто получит копию файла и захочет узнать, каково его зашифрованное содержимое (шифрование не такое уж надежное, и есть способы увидеть содержимое, не расшифровывая его), но если вы просто Если вы хотите не допустить любопытных людей, это добавляет дополнительный барьер для входа, который может отпугнуть некоторых людей.


Обновлять: Поскольку вы только что оставили комментарий, в котором говорится, что вы используете CF7, вот собственный синтаксис CF7:

настройки.cfm:

<cfset variables.settings = StructNew() />
<cfset variables.settings.fooSection = StructNew() />
<cfset variables.settings.fooSection.fooKey = 'fooVal' />
<cfset variables.settings.fooSection.fooNumber = 2 />
<!--- ... --->

В качестве альтернативы вы можете использовать JSONUtil и CFSaveContent, чтобы продолжать использовать подход, похожий на JSON (похожий на мой исходный синтаксис), но на CF7:

<cfsavecontent variable="variables.jsonSettings">
{
    fooSection = {
        fooKey = 'fooVal',
        fooNumber = 2,
    },
    fooSection2 = {
        //...
    },
    fooSection3 = {
        //...
    }
};
</cfsavecontent>
<cfset variables.settings = jsonUtil.deserializeFromJSON(variables.jsonSettings) />

Я создал CFC, который я использую в куче приложений. Когда вы его инициализируете, вы задаете путь к файлу ini, и он создает структуру на основе файла ini. Кроме того, при желании структура остается плоской или создается подструктура на основе [Разделов] в INI-файле. Затем вы можете использовать метод getSetting () для получения отдельных методов или метод getAllSettings () для возврата всей структуры. Вы можете найти это полезным.

<cfcomponent hint="converts INI file to a structure">
    <cfset variables.settings=structNew() />
    <cffunction name="init" access="public" output="false" returntype="any">
        <cfargument name="configurationFile" type="string" required="yes" />
        <cfargument name="useSections" default="false" type="boolean" />
        <cfset var local=structNew() />
        <cfif fileExists(arguments.configurationFile)>
            <!--- Get the [sections] in the .INI file --->
            <cfset local.sectionStruct=getProfileSections(arguments.configurationFile) />
            <!--- Loop over each of these sections in turn --->
            <cfloop collection="#local.sectionStruct#" item="local.item">
                <cfset local.workingStruct=structNew() />
                <cfloop list="#local.sectionStruct[local.item]#" index="local.key">
                    <!--- Loop over the keys in the current section and add the key/value to a temporary structure --->
                    <cfset local.workingStruct[local.key]=getProfileString(arguments.configurationFile,local.item,local.key) />
                </cfloop>
                <cfif arguments.useSections>
                    <!--- Copy the temporary structure to a key in the setting structure for the current section --->
                    <cfset variables.settings[local.item]=duplicate(local.workingStruct) />
                <cfelse>
                    <!--- Append the temporary structure to the setting structure --->
                    <cfset structAppend(variables.settings,local.workingStruct,"yes") />
                </cfif>
            </cfloop>
        <cfelse>
            <cfthrow
                message="Configuration file not found. Must use fully-qualified path."
                extendedinfo="#arguments.configurationFile#"
            />
        </cfif>
        <cfreturn this>
    </cffunction>

    <cffunction name="getAllSettings" access="public" output="false" returntype="struct">
        <cfreturn variables.settings>
    </cffunction>

    <cffunction name="getSetting" access="public" output="false" returntype="string">
        <cfargument name="settingName" required="yes" type="string" />
        <cfset var returnValue="" />

        <cfif structKeyExists(variables.settings,arguments.settingName)>
            <cfset returnValue=variables.settings[arguments.settingName] />
        <cfelse>
            <cfthrow
                message="No such setting '#arguments.settingName#'."
            />
        </cfif>
        <cfreturn returnValue>
    </cffunction>
</cfcomponent>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top