Pergunta

Alguém poderia encontrar uma maneira de melhorar este código um pouco? Eu quero ler em um arquivo INI de uma só sentiu e criar uma estrutura de dados correspondente.

<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>
Foi útil?

Solução

Eu não acredito que você pode melhorar isso usando o poder CFML. Você precisa analisar enormes ini? Se não, por que você gostaria de melhorar o seu código, parece bastante simples para mim.

Outros possível (embora comum para CF) solução é tentar puro Java. Veja este tópico SO para exemplos href="https://stackoverflow.com/questions/190629/what-is-the-easiest-way-to-parse-an-ini-file-in-java"> puro Java .

P.S. BTW, em caso de necessidades especiais de desempenho que você deve considerar o uso de outro armazenamento de configuração. Simples consulta SELECT para o velho bom MySQL pode ser muito mais rápido para grandes conjuntos de dados.

Outras dicas

Para expandir o comentário de ryber, você pode considerar usar essa abordagem em seu lugar. Eu estou supondo que você está usando CF8.01 ou mais tarde, como eu fazer uso de notação estrutura implícita aninhada. Isso pode ser facilmente convertido em CF7 / 6 / etc sintaxe, mas não seria tão limpa ou conciso.

Mais uma vez, isto só se aplica se o seu arquivo ini não é usado por quaisquer outras aplicações ou pessoas, e não necessidade para estar no formato INI.

settings.cfm:

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

Application.cfc: (apenas o método onApplicationStart)

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

Além disso, eu tenho usar o aplicativo CFEncode para criptografar o conteúdo de settings.cfm. Ele não vai protegê-lo de alguém que recebe uma cópia do arquivo e quer ver o que os seus conteúdos criptografados são (a criptografia não é tão forte, e há maneiras de ver o conteúdo sem descriptografar), mas se você apenas quer manter algumas pessoas intrometidas fora, ele adiciona uma entrada de barreira-to-pequeno extra que pode dissuadir algumas pessoas.


Update: Desde que você acabou de sair um comentário que diz que você está no CF7, aqui está a sintaxe nativa CF7:

settings.cfm:

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

Como alternativa, você poderia usar JSONUtil e cfsavecontent para continuar a usar uma abordagem JSON-olhando (similar à minha sintaxe original), mas em CF7:

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

Eu criei um CFC que eu uso em um monte de apps. Você dar-lhe um caminho de arquivo ini quando o init-lo e ele cria uma estrutura com base no arquivo ini. Também mantém opcionalmente a estrutura plana ou cria sub-estruturas baseadas nas Secções [] no ficheiro INI. Você pode então usar seu método getSetting() para obter métodos individuais ou getAllSettings() para retornar toda a estrutura. Você pode achar útil.

<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>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top