2013-05-04 55 views
3

我想了解如何使用ColdFusion中的CFFILE標記來讀取文本文件的內容。就我而言,該文本文件是FFMpeg在轉碼媒體文件時生成的進度日誌。我想編寫一個ColdFusion腳本來定期輪詢進度日誌,直到日誌指出FFMpeg已完成其轉碼操作。然後在客戶端,我可以使用Ajax命中該ColdFusion腳本,並在FFMpeg執行其工作時向用戶顯示「完成百分比」。使用ColdFusion的CFFILE標記來監視FFMpeg的進度日誌

我通過使用FFMpeg最新版本現在支持的新「進度」標誌來獲得FFMpeg來生成日誌文件。下面我將向您展示使用此標誌的方式以及日誌文件中生成的輸出。

這裏的FFmpeg的命令:

ffmpeg -i c:\my_original_file.ogg c:\my_converted_file.mp3 -progress c:\my_progress.txt 

上面的命令將導致FFmpeg的生成名爲my_progress.txt的日誌文件。

下面是它生成日誌文件:

total_size=206150 
out_time_ms=51410044 
out_time=00:00:51.410044 
dup_frames=0 
drop_frames=0 
progress=continue 

以上6條線都在日誌文件中反覆產生,隨着價值。

total_size=206150 
out_time_ms=51410044 
out_time=00:00:51.410044 
dup_frames=0 
drop_frames=0 
progress=continue 
total_size=412413 
out_time_ms=102975756 
out_time=00:01:42.975756 
dup_frames=0 
drop_frames=0 
progress=continue 
total_size=618363 
out_time_ms=154463111 
out_time=00:02:34.463111 
dup_frames=0 
drop_frames=0 
progress=continue 
total_size=824939 
out_time_ms=206107189 
out_time=00:03:26.107189 
dup_frames=0 
drop_frames=0 
progress=continue 

最後,當作業完成時,最後一塊6行是日誌文件中的最後一行。請注意,在最後一行的「進步=結束」:

total_size=9725902 
out_time_ms=2431348011 
out_time=00:40:31.348011 
dup_frames=0 
drop_frames=0 
progress=end 

我想用CFFILE標籤讀取只有最後6行的文件(無論文件多大必須寫一個ColdFusion腳本成爲),並在每次瀏覽器通過Ajax調用腳本時執行此操作。最後,我需要將這些行中的值解析爲變量,以便將一些數據返回給調用者。

我已經研究了FFMpeg的進度條,但是它們在PHP中對我來說很難,而且他們解析了舊版本的FFMpeg日誌文件,我想使用上面的新格式。任何人都可以幫忙嗎?

+0

*使用CFFILE標籤只讀取文件的最後6行*爲了澄清,沒有一個CF文件標籤/函數真的支持只讀*文件的結尾。您必須閱讀整個文件,並向後循環。因此,彼得建議使用「尾巴」(這是專門爲此目的而設計的)外部程序。 – Leigh 2013-05-06 13:46:02

回答

2
變快

爲了得到最後六行tail會更快,因爲它向後工作,只加載你所要求的(而不是讀入整個文件然後循環)。無論文件大小如何,它顯然也會使用更少的內存。

<cfexecute 
    name  = "tail" 
    arguments = "--lines=6 #Filename#" 
    timeout = 30 
    variable = "LastSixLines" 
    /> 

<cfset Data = {} /> 
<cfloop index="CurLine" array=#LastSixLines.trim().split('\n')# > 
    <cfset Data[ListFirst(CurLine,'=')] = ListRest(CurLine,'=') /> 
</cfloop> 


正如你似乎是在Windows上,你可能需要安裝尾(這是預裝了Linux和MacOS)。最簡單的選項是MSYS,這可能取決於您使用的其他軟件 - 例如,Git for Windows使用MSYS,並且在其bin文件夾中有tail.exe。

在這種情況下,像上面這樣的改變的東西下聯:

name  = "C:/Program Files/Git/bin/tail" 

如果您需要的代碼,以在多個系統上運行,則可以使該部分的變量,(或出臺相應的目錄上系統PATH,因此可以從任何地方調用)。

0

這將讀取您的文件並創建一個最後6行的結構。

<cffile action="read" file="myfile.txt" variable="myfile"> 

<cfoutput> 
    <cfset linecount = listlen(myfile,chr(10))> 
    #linecount# lines 

    <cfset count = 0> 
    <cfset stData = {}> 
    <cfloop list="#myfile#" index="i" delimiters="#chr(10)#"> 
     <cfset count++> 
     <cfif count GT linecount - 6><!--- we only care about the last 6 lines ---> 
      #i#<Br> 
      <cfset stData[listfirst(i,'=')] = listlast(i,'=')><!--- add data to stData ---> 
     </cfif> 
    </cfloop> 
</cfoutput> 
<cfdump var="#stData#"> 

上面會輸出的代碼從文本文件中的原始數據,並基於該=是一個分隔符

您還可以將文件存儲到一個數組,然後拉出最後6行創建結構像這樣。此選項是約2倍的速度與更小的文件(< 200K線),但作爲文件大小增長的兩個選項幾乎是一樣的,然後第一個選項大約100萬行

<cffile action="read" file="c:\ColdFusion10\cfusion\wwwroot\myfile.txt" variable="myfile"> 

<cfset filearray = listToArray(myfile,chr(10))> 
<cfset linecount = arrayLen(filearray)> 
<cfset stData = {}> 
<cfloop from="0" to="5" index="i"> 
    <cfset stData[listfirst(filearray[linecount - i],'=')] = listlast(filearray[linecount - i],'=')> 
</cfloop> 

enter image description here

+0

這看起來倒退了。爲什麼不從頭開始循環,爲什麼不從頭開始並向後退步6次? – 2013-05-04 12:49:31

+0

@DanBracuk你將如何向後循環而不會導致大量額外的處理?我向txt文件中添加了100萬行,並且讀取時間爲300ms。 – 2013-05-04 12:53:03

+0

2013-05-04 12:56:33