1. Reading/writing big files - Since <cffile> is a tag, it can only perform one-shot operations. So, to read, it has to read everything in one shot and to write, you have to provide the entire content and that means that <cffile> will have to keep the entire content in memory. It is not of much concern if the file size is just few KBs but as the size increases beyond 100 kb or when it reaches few megs, it can really hurt. It would create a memory crunch on the server and if the load is high and there are many read/write happening simultaneously with large files, it can even lead to OutOfMemory error in server. Apart from creating memory crunch, it will also slow down the server because VM would need to allocate/deallocate larger chunk of memory which would lead to larger and frequent Garbage Collection cycle. At this point, you might ask, why would I ever read or write such a big file? Well I can think of few
- You need to process the data that comes in a flat file
- csv parsing
- Finding the mime type of a file like mp3, image, video etc
- you want to create a log viewer
- ... many more
2. Again since <cffile> is a tag, it is not very easy to use inside cfscript. Either you have to move out of cfscript to use this tag or you wrap this tag in a function and call that function. Though thats true with all the tags but cffile is so commonly used that this looks like a limitation.
New File I/O introduced in ColdFusion 8 addresses both these problems. New File I/O is all based on functions and hence that automatically takes care of problem 2. That means you no longer need to use cffile if you are inside cfscript. I will give more details on handling problem 2 in my next post. In this post I will mainly focus on reading/writing files in chunk using new IO .
The new I/O is based on the same philosophy that is used in other languages i.e;
- You first open a file
- Perform read/write operations on it
- and close the file.
Step 1 : Open a file : Here is the function to open a file
FileOpen(filepath [,mode] [,charset]) -> fileobjectBoth mode and charset here and optional. Mode can be "read", "readBinary", "write" or "append"
"read" mode, which is default, is used to read a text file and hence any read operation will give you text data from it. When the file is a text file, you can also optionally specify the charset of the file. So if the file contains UTF-8 or UTF-16 characters (or characters from any other charset), you need to specify it while opening the file.
"readBinary" is used to read a binary file and hence any read operation will give you the binary data i.e byte array.
"write" mode will open the file in write mode which means that if the file already exists, it will be overwritten.
"append" mode, as the name suggests, will open the file in append mode which means that any write operation on that file object will write it at the end of file.
FileOpen function returns you a handle to the native file and you need to use this handle for all further read/write operation. Of course you should keep in mind that you can not perform "read" operation on a file handle that was opened in "write" mode and vice versa.
Step 2 : Do Read/Write operations : Once you get the handle to file object, you can perform multiple read/write operations using this handle. There are several functions to do that.
2A. Read Operation :
i) FileRead(fileobj, no of character/bytes to read) : This provides you a way to read a chunk of data (say 1 kb at a time) from the file at a time. Since you only read a chink of data at a time, it does not create memory crunch on the server. Since this is read operation, file must have been opened in "read" or "readBinary" mode. Depending on which mode the file was opened, this function will return the text or binary data read. One thing to note here - If the data remaining is less than the requested size, this method will return you only the remainign data. i.e if 100 character are remaining in the file being read, and you request for 1000 characters, it will return you 100 characters only.
ii) FileReadLine(fileobject) - This reads one line from the text file. To call this method, the file must have been opened in "read" mode.
Both these read operations can be called multiple times until you reach end of the file. One the end of file has reached, any further read call will result into an "EndOfFile" error. So in order to avoid this error, you should always check whether you have reached the end of file. And the function to do that is
FileIsEOF(fileobj) : Just to be more clear, EOF here stands for "End of File". This function will return true if the end of file has been reached otherwise will return false.
Here are few examples of reading content from file
Read 1 kb binary data at a time.
<cfscript>
myfile = FileOpen("c:\temp\song.mp3", "readbinary");
while (! FileIsEOF(myfile)) { // continue the loop if the end of file has not reached
x = FileRead(myfile, 1024); // read 1 kb binary data
...// process this binary data..
}
</cfscript>
<cfscript>
myfile = FileOpen("c:\temp\myfile.txt", "read");
while (! FileIsEOF(myfile)) { // continue the loop if the end of file has not reached
x = FileReadLine(myfile); // read a line
...// process this line..
}
</cfscript>
i)FileWrite(fileobject, content) - This will add the text or binary content to the file. The file must have been opened in "write" or "append" mode.
ii) FileWriteLine(fileobject, text) - This will add the text followed by a new line character to the file. Here again, the file must have been opened in "write" or "append" mode.
You might wonder that if both the write operations add the content to the file, whats the difference between "write" and "append" mode? The difference is only at the time of opening the file. As I said earlier, opening the file in "write" mode will overwrite the file if already existsed and put the file pointer at the the beginning of file. Whereas opening file in "append" mode will simply put the file pointer at the end of file.
Any subsequent "write" calls, irrespective of "write" or "append" mode, will append the content to the file.
Here is an example of writing content to a file. This reads one line from an input file, does some processing on it, and writes the resultant data to another file.
<cfscript>
infile = FileOpen("c:\temp\input.txt", "read");
outfile = FileOpen("C:\temp\result.txt", "write");
while (! FileIsEOF(infile)) { // continue the loop if the end of file has not reached
x = FileReadLine(infile); // read a line
data = processLine(x);
FileWriteLine(outfile, data);
}
</cfscript>
Step 3 : Close the file : Once you are done with read/write operations, you *must* close the handle to file. And the way to do that is using function
FileClose(fileobj)What if you don't close the file object? Well, that file will remain locked by the server as long as the file is open, and no other process can modify/rename or delete that file.
You might also ask, why does not ColdFusion automatically take care of closing the file? Why should the developer be bothered about it? Well.. ColdFusion does take care of it when the file object goes out of scope and if it is not kept in any accessible scopes but you can never be certain when exactly this will happen. This might happen immediately or this might happen hours later :-).
Bottomline, you should make it a practice to call FileClose() once you are done with the file object.
Just to show its usage, I will complete the example I used in write.
<cfscript>
infile = FileOpen("c:\temp\input.txt", "read");
outfile = FileOpen("C:\temp\result.txt", "write");
while (! FileIsEOF(infile)) { // continue the loop if the end of file has not reached
x = FileReadLine(infile); // read a line
data = processLine(x);
FileWriteLine(outfile, data);
}
FileClose(infile);
FileClose(outfile);
</cfscript>
These set of functions would greatly help if you need to work with a file of more than 10 kb size.
Apart from these set of functions, ColdFusion 8 also adds a new language struct to read text files. With ColdFusion 8, you can use <cfloop> to iterate over "lines" or "characters" in a text file. This makes it very easy and convenient to do any kind of text file parsing or processing in your application. Lets take a look at the new syntax of cfloop for reading file (and I really love this syntax :-)).
New attributes in cfloop for reading file :
"file" - path of the file to read
"characters" - no of characters to read in one iteration.
- Reading Lines : Below is the simplest syntax to read one line at a time from the file in a loop. This would read the entire file and the loop would end when the file has been completely read. The read content will be available in the index variable specified.
<cfloop file="c:\temp\myfile.txt" index="line">
<cfoutput>#line#</cfoutput> <!--- or do whatever with the line --->
</cfloop>
With cfloop, you can also iterate over a part of the file by specifying "from" and "to" values.
Here is an example to loop over lines between 10 and 20.
<cfloop file="c:\temp\myfile.txt" index="line" from=10 to=20>
<cfoutput>#line#</cfoutput> <!--- or do whatever with the line --->
</cfloop>
"from" and "to" both are optional attributes where "from" defaults to '1' i.e start of file and "to" defaults to the last line of the file.
So to read first 10 lines from the file, you can use
<cfloop file="c:\temp\myfile.txt" index="line" to="10">
<cfoutput>#line#</cfoutput> <!--- or do whatever with the line --->
</cfloop>
One word of caution here - If you use "to" attribute here, its value must be less than the number of lines in the file otherwise you would get an "EndOfFile" error. For example, if I had only 5 lines in my file and value of to is 7, this would throw an error because line 6 and 7 do not exist. - Reading characters : For reading characters instead of line, you need to provide the value for "characters" attribute and as many characters will be read in one iteration. The loop will automatically end when the end of file has reached. The read content will be available in the index variable specified.
An example for that isOne important thing to note here. In the last iteration, when the end of file has reached, index variable will only have the remaining characters. For example if I have 130 characters in the file and I run the loop to read a chunk of 20 characters, in the last iteration, index variable's value will only have last 10 characters.
<cfloop file="c:\temp\myfile.txt" index="chars" characters="1000">
<cfset x=chars>
<!--- do whatever with the characters --->
</cfloop>
20 comments:
Very nice!
Nice overview of the new file functionality. I think this is going to be make a huge difference.
Thanks Sami and Ben.
I just with they had added seek. For example, MP3 headers are at the end of the file, so I'd still have to read in the entire file.
@Ray
I agree that seek would have been cool.. CF9 :-)
Regarding MP3 headers, they are not really at the end of file. In fact the headers used to identify a mp3 file are there at each frame. This is what makes it possible to split mp3 file (or extract any part of it) and they would play perfectly fine.
I am saying this because I had to extract mp3 file metadata for cfpresentation. :-)
Check out the mp3 file format details
>here.
Ah - I hadn't done parsing in a long time. Well, ok, lets pretend it is some other format. ;)
So - you should see if you can getMP3Info() in CF9 as well. ;)
hehehe :-)
For MP3 Info, the code is all there. Its just a matter of exposing it :-)
Hmm. So I'm skimming the docs, and it mentions that yes, info on the mp3 is in every frame, but it says the ID3 info is at the end. That is what I meant - the ID3 info, which is the stuff most people are interested in. Make sense? It's too bad that we can't read backwards. That would take care of this case at least.
Heh, of course, that is for the earlier version. It looks like 2.3.0 may put it in front:
http://www.id3.org/id3v2.3.0#head-697d09c50ed7fa96fb66c6b0a9d93585e2652b0b
Yes, I'm confused now. ;)
Hmm.. I didn't mean ID3 info. It will be interesting to try it out with this function and see how much time it takes.
or let me write some java code to do it.
Good luck Rupesh. My Java skills are pretty minimal. If you get something going, it would be nice to wrap it in a CFC and publish it on RIAForge.
Can you give us an example of how this might work if you had an input type="file" type of file upload browse dialog and you wished to write the selected file to another location.
this still is slow, i get a GC overhead limit exceeded, meaning this method is not sufficient
Nice blog...
visit also coldfusion example
runescape money
runescape gold
runescape money
runescape gold
buy runescape gold buy runescape money runescape items
runescape accounts
runescape gp
runescape money
runescape power leveling
runescape money
runescape gold
dofus kamas
cheap runescape money
cheap runescape gold
Guild Wars Gold
buy Guild Wars Gold
lotro gold
buy lotro gold
lotro gold
buy lotro gold
lotro gold
buy lotro gold
Hellgate Palladium
Hellgate London Palladium
Hellgate money
Tabula Rasa gold tabula rasa money
Tabula Rasa Credit
Tabula Rasa Credits
Hellgate gold
Hellgate London gold
wow power leveling
wow powerleveling
Warcraft PowerLeveling
Warcraft Power Leveling
World of Warcraft PowerLeveling World of Warcraft Power Leveling runescape power leveling
runescape powerleveling
eve isk
eve online isk
eve isk
eve online isk
tibia gold
Fiesta Silver
Fiesta Gold
Age of Conan Gold
buy Age of Conan Gold
aoc gold
呼吸机
无创呼吸机
家用呼吸机
呼吸机
家用呼吸机
美国呼吸机
篮球培训
篮球培训班
篮球夏令营
china tour
beijing tour
beijing travel
china tour
tibet tour
tibet travel
computer monitoring software
employee monitoring
Woa! I can do the same in J2EE since 10 years! And I dont need to wait CF12 for the seek operation ;-)
Does cfloop file close the file at close cfloop tag or end of processing the whole template
看房子,買房子,建商自售,自售,台北新成屋,台北豪宅,新成屋,豪宅,美髮儀器,美髮,儀器,髮型,EMBA,MBA,學位,EMBA,專業認證,認證課程,博士學位,DBA,PHD,在職進修,碩士學位,推廣教育,DBA,進修課程,碩士學位,網路廣告,關鍵字廣告,關鍵字,課程介紹,學分班,文憑,牛樟芝,段木,牛樟菇,日式料理, 台北居酒屋,日本料理,結婚,婚宴場地,推車飲茶,港式點心,尾牙春酒,台北住宿,國內訂房,台北HOTEL,台北婚宴,飯店優惠,台北結婚,場地,住宿,訂房,HOTEL,飯店,造型系列,學位,SEO,婚宴,捷運,學區,美髮,儀器,髮型,看房子,買房子,建商自售,自售,房子,捷運,學區,台北新成屋,台北豪宅,新成屋,豪宅,學位,碩士學位,進修,在職進修, 課程,教育,學位,證照,mba,文憑,學分班,台北住宿,國內訂房,台北HOTEL,台北婚宴,飯店優惠,住宿,訂房,HOTEL,飯店,婚宴,台北住宿,國內訂房,台北HOTEL,台北婚宴,飯店優惠,住宿,訂房,HOTEL,飯店,婚宴,台北住宿,國內訂房,台北HOTEL,台北婚宴,飯店優惠,住宿,訂房,HOTEL,飯店,婚宴,結婚,婚宴場地,推車飲茶,港式點心,尾牙春酒,台北結婚,場地,結婚,場地,推車飲茶,港式點心,尾牙春酒,台北結婚,婚宴場地,結婚,婚宴場地,推車飲茶,港式點心,尾牙春酒,台北結婚,場地,居酒屋,燒烤,美髮,儀器,髮型,美髮,儀器,髮型,美髮,儀器,髮型,美髮,儀器,髮型,小套房,小套房,進修,在職進修,留學,證照,MBA,EMBA,留學,MBA,EMBA,留學,進修,在職進修,牛樟芝,段木,牛樟菇,關鍵字排名,網路行銷,PMP,在職專班,研究所在職專班,碩士在職專班,PMP,證照,在職專班,研究所在職專班,碩士在職專班,SEO,廣告,關鍵字,關鍵字排名,網路行銷,網頁設計,網站設計,網站排名,搜尋引擎,網路廣告,SEO,廣告,關鍵字,關鍵字排名,網路行銷,網頁設計,網站設計,網站排名,搜尋引擎,網路廣告,SEO,廣告,關鍵字,關鍵字排名,網路行銷,網頁設計,網站設計,網站排名,搜尋引擎,網路廣告,SEO,廣告,關鍵字,關鍵字排名,網路行銷,網頁設計,網站設計,網站排名,搜尋引擎,網路廣告,EMBA,MBA,PMP,在職進修,專案管理,出國留學,EMBA,MBA,PMP,在職進修,專案管理,出國留學,EMBA,MBA,PMP,在職進修,專案管理,出國留學,婚宴,婚宴,婚宴,婚宴,漢高資訊,漢高資訊,比利時,比利時聯合商學院,宜蘭民宿,台東民宿,澎湖民宿,墾丁民宿,花蓮民宿,SEO,找工作,汽車旅館,阿里山,日月潭,阿里山民宿,東森購物,momo購物台,pc home購物,購物漢高資訊,漢高資訊,在職進修,漢高資訊,在職進修,住宿,住宿,整形,造型,室內設計,室內設計,漢高資訊,在職進修,漢高資訊,在職進修,住宿,美容,室內設計,在職進修,羅志祥,周杰倫,五月天,住宿,住宿,整形,整形,室內設計,室內設計,比利時聯合商學院,在職進修,比利時聯合商學院,在職進修,漢高資訊,找工作,找工作,找工作,找工作,找工作,蔡依林,林志玲
酒店喝酒,禮服店,酒店小姐,傳播妹,便服店,鋼琴酒吧,酒店兼職,酒店兼差,酒店打工,伴唱小姐,暑假打工,酒店上班,酒店兼職,ktv酒店,酒店,酒店公關,酒店兼差,酒店上班,酒店打工,禮服酒店,禮服店,酒店小姐,酒店兼差,暑假打工,酒店小姐,台北酒店,禮服店 ,酒店小姐,酒店經紀,酒店兼差,寒假打工,酒店小姐,台北酒店,禮服店 ,酒店小姐,酒店經紀,酒店兼差,暑假打工,酒店小姐,台北酒店,禮服店 ,酒店小姐,酒店經紀,酒店兼差,寒假打工,台北酒店,禮服店 ,酒店小姐,酒店經紀,酒店兼差,暑假打工,酒店小姐,台北酒店,禮服店 ,酒店小姐,酒店兼差,暑假打工,酒店小姐,台北酒店,禮服店 ,酒店小姐,酒店經紀,酒店兼差,寒假打工,酒店小姐,台北酒店,禮服店 ,酒店小姐,酒店經紀,酒店兼差,暑假打工,酒店小姐,台北酒店,禮服店 ,酒店小姐,酒店經紀,酒店兼差,寒假打工,酒店小姐,台北酒店,禮服店 ,酒店小姐,酒店經紀,酒店兼差,暑假打工,酒店小姐,禮服店 ,酒店小姐,酒店經紀,酒店兼差,寒假打工,酒店小姐,禮服店 ,酒店小姐,酒店經紀,酒店兼差,暑假打工,酒店小姐,禮服店 ,酒店小姐,酒店經紀,酒店兼差,寒假打工,酒店小姐,禮服店 ,酒店小姐,酒店經紀,酒店兼差,暑假打工,酒店小姐,酒店傳播,酒店經紀人,酒店,酒店,酒店,酒店 ,禮服店 , 酒店小姐,酒店經紀,酒店兼差,暑假打工,招待所,酒店小姐,酒店兼差,寒假打工,酒店上班,暑假打工,酒店公關,酒店兼職,禮服店 , 酒店小姐 ,酒店經紀 ,酒店兼差,暑假打工,酒店,酒店,酒店經紀,
希望大家都會非常非常幸福~
「朵朵小語‧優美的眷戀在這個世界上,最重要的一件事,就是好好愛自己。好好愛自己,你的眼睛才能看見天空的美麗,耳朵才能聽見山水的清音。好好愛自己,你才能體會所有美好的東西,所有的文字與音符才能像清泉一樣注入你的心靈。好好愛自己,你才有愛人的能力,也才有讓別人愛上你的魅力。而愛自己的第一步,就是切斷讓自己覺得黏膩的過去,以無沾無滯的輕快心情,大步走向前去。愛自己的第二步,則是隨時保持孩子般的好奇,願意接受未知的指引;也隨時可以拋卻不再需要的行囊,一路雲淡風輕。親愛的,你是天地之間獨一無二的旅人,在陽光與月光的交替之中瀟灑獨行.............................................................................................................有時,你覺得痛。胃痛的時候,接受它,承認這個疼痛是你的身體的一部份,與它和平共處。心痛的時候,接受它,承認這個經驗是你的生命的一部份,與它和平共處。抗拒痛的存在,只會讓它更要證明它的存在,於是你就更痛。所以,.無論你有多麼不喜歡痛的感覺,還是要接納這個痛的事實。與你的痛站在同一邊,不逃避,不閃躲,不再與你的痛爭執,如此,你的痛才會漸漸不再胡鬧,才會乖乖平息下去。.................心願-你許下了一個心願,你閉上眼睛,在冥想之中把這個心願交託宙給宇整個讓宇宙推動它全部的力.量去執行.,你看見星球與星球的引力牽繫著彼此,你聽見虛空與虛空.唱裡著和妙美的聲音,為了你的心願,整個宇宙正在相互傳遞,然後你放下了心願,不僅是放下,最好你還把你的心願忘記,唯有如此,它才能脫離你,發展它自己,
當它在宇宙的遊歷結束之後,它自然會來到你身邊,以你曾經希望的方式回應你,許下,只是讓它發生,放下,才是讓>它實現,你的心願使你懂得不能執著的奧秘...................
Post a Comment