Потеря столбцов при замене значений NULL в файле с разделителями табуляции - Coldfusion

У меня есть текстовый файл с разделителями табуляции, который содержит страшное значение «NULL». И после некоторых поисков я нашел, как заменить пустую строку... на "что-то". Но когда я делаю это, я, кажется, теряю половину своих ценностей.

<cfset thisRow = replace(thisRow, "#chr(9)##chr(9)#", "#chr(9)#ScoobySnack#chr(9)#", "all")>

Например: одна строка данных содержит 120 «пустых вкладок», но когда я использую этот обходной путь, я возвращаю только 60. Фрагмент здесь:

    <cffile action="read" file="c:\websites\the website\UsageData\#MyFile.NAME#" variable="myDataFile">

  <cfset rowCount = listLen(myDataFile,chr(13))>


  -Other stuff happens-


  <cfloop from="1" to="#rowCount#" index="i">
  <table cellpadding="2" cellspacing="0" border="1">
  <tr>
  <th>ID</th>
  <th>Date</th>
  <th>Time</th>
  <th>DeviceMac</th>
  <th>DeviceAddress</th>
  <th>DeviceName</th>
  <th>UsageBytes</th>
  </tr>
  <!--- set current row to simple variable --->
  <cfset thisRow = listGetAt(myDataFile,i,chr(13))>

  <cfset Field1 = listGetAt(thisRow,1,chr(9))>
  <cfset Field2 = listGetAt(thisRow,2,chr(9))> 
  <cfset Field3 = listGetAt(thisRow,3,chr(9))>


  <cfset thisRow = replace(thisRow, "#chr(9)##chr(9)#", "#chr(9)#ScoobySnack#chr(9)#", "all")>

  <cfset variables.CheckColumnCount = listLen(thisRow,chr(9))>

  <cfif variables.CheckColumnCount NEQ variables.ColumnCount>
  <cfset variables.AdjustedColumnCount = (variables.CheckColumnCount - 3)>
  <cfelse>
  <cfset variables.AdjustedColumnCount = (variables.ColumnCount - 3)>
  </cfif>

  <!---Row #i# Data as a string (#thisRow#)<br/>--->
  <cfset ColNum = 4>
  <!--- now loop the row --->
  <cfloop from="1" to="#variables.AdjustedColumnCount#" index="r">
  <cfif r EQ 1>
  <cfset variables.MyLoopStartTime = variables.MyStartTime>
  <cfelse>

  </cfif>

  <tr>
  <td>#ColNum#</td>
  <td>#variables.thisDate#</td>
  <td>#TimeFormat(variables.MyLoopStartTime,"hh:mm:ss")#</td>
  <td>#Field1#</td>
  <td>#Field2#</td>
  <td>#Field3#</td>
  <td>#listGetAt(thisRow,ColNum,chr(9))#</td>
  </tr>
  <cfset variables.MyLoopStartTime = DateAdd('n', 1, variables.MyLoopStartTime)>
  <cfset ColNum = ColNum +1>
  </cfloop>
  </table>
  <hr>
  <cfset count = count + 1>
  </cfloop>

Мысли?


person Big Fat Designs    schedule 16.09.2013    source источник
comment
(Редактировать) Если вы должны свернуть свой собственный, не используйте replace(). Проще использовать массивы, в частности listToArray(..) с includeEmptyFields=true. Тем не менее, для этой работы есть лучшие инструменты. Специально разработанные для разбора файлов с разделителями.   -  person Leigh    schedule 16.09.2013
comment
Спасибо, Ли, тогда ответ на мой вопрос будет таким: <cfset MyDataArray = ListToArray(listGetAt(myDataFile,i,chr(13)), chr(9), true)>   -  person Big Fat Designs    schedule 17.09.2013
comment
Не совсем. Если вы собираетесь переключиться на массивы, избавьтесь от всех функций списка. Вам нужно только преобразовать его в массив один раз. Затем везде, где вы используете списки, вместо этого используйте массив. Вместо listGetAt( yourList, x, delim ) используйте yourArray[ x ], вместо listLen( yourList, delim ) используйте arrayLen( yourArray) и так далее.   -  person Leigh    schedule 17.09.2013
comment
Ну, по правде говоря, массивы не моя сильная сторона. Когда я конвертирую свой файл в массив, он не разделяет строки... Все становится одним большим столбцом. (С 37000 строк...) Но мой код выше преобразовал строку в массив и сохранил пустые поля... (что было здорово) Но я понимаю, что смешивал... просто не знал, как сохранить строки в исходном файле.   -  person Big Fat Designs    schedule 17.09.2013


Ответы (1)


(Из комментариев..)

Существуют лучшие инструменты для работы: специально разработанные для анализа файлов с разделителями. Однако, чтобы ответить на ваш вопрос, если вы должны свернуть свой собственный, не используйте replace(). Проще использовать массивы, в частности listToArray() с includeEmptyFields=true.

Прочитайте файл и разделите содержимое на CR, чтобы создать массив строк:

<!--- split content into an array of rows --->
<cfset rowArray  = listToArray(myDataFile, chr(13), true)>
<cfset rowCount  = arrayLen(rowArray)>

Затем прокрутите массив и создайте отдельный массив столбцов из каждой строки:

<cfloop from="1" to="#rowCount#" index="rowIndex">
    <!--- split current row into an array of columns --->
    <cfset thisRow  = rowArray[ rowIndex ]>
    <cfset colArray = listToArray(thisRow , chr(9), true)>

    <!--- get first 3 columns (for illustration) --->   
    <cfset Field1 = colArray[ 1 ]>
    <cfset Field2 = colArray[ 2 ]> 
    <cfset Field3 = colArray[ 3 ])>
    ...

</cfloop>

Если вам не нужен индекс цикла для других вещей, вы также можете использовать цикл массива:

<!--- split content into an array of rows --->
<cfset rowArray  = listToArray(myDataFile, chr(13), true)>
<cfloop array="#rowArray#" index="thisRow">
    <!--- split current row into an array of columns --->
    <cfset columns = listToArray(thisRow, chr(9), true)>

    <!--- get first N columns for illustration ---> 
    <cfset Field1 = columns [ 1 ]>
    <cfset Field2 = columns [ 2 ]> 
    <cfset Field3 = columns [ 3 ])>
    ...
</cfloop>
person Leigh    schedule 17.09.2013