




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、Fortran中批量處理文件的方法總結(jié)循環(huán)讀取目錄下的所有符合條件的文件=一、簡單的介紹 在一年之前,我寫過一個程序,主要是對Micaps資料進行批量處理,將逐日資料處理為旬、月的數(shù)據(jù),在那個程序中,始終有一個問題困擾我,就是如何自動生成該讀取的下一個文件名,這使我真正開始關(guān)注fortran中的批處理,時隔一年,決定寫下這些文字,將我用到的一些fortran批處理的方法和大家共享,交流。 對于那些只要會用程序,不求其中原理的朋友,請馬上跳過這些文字,直接去下載附件吧!程序里有使用說明,但是,如果你不懂原理,估計現(xiàn)成的程
2、序你使用起來也會碰壁哦! 這里所說的批處理是指對某一個目錄下的指定后綴的文件的批量讀取和處理。 我總結(jié)的批處理方法大概可以用下面這個示意圖來說明: | | |將文件目錄寫入一個文本文件,供fortran循環(huán)讀取 |手動輸入文件名 |運行程序之前命令行工具導(dǎo)出文件名 |程序運行后,未開始計算之前,生成文件名 | 調(diào)用CMD命令生成 |
3、0; GETFILEINFOQQ方法生成 | 調(diào)用WIN32API生成 | |在程序運行時動態(tài)生成文件名 | | 對于第一種方法,我將主要介紹如何將目錄寫入文件,然后舉出一個小的示例來驗證。第二種方法主要是說明其思路。 二、方法的介紹 1、 將文件目錄寫入一個文本文件,供fortran循環(huán)讀取 1.1、
4、60; 手動輸入文件名這是最基本的方法啦,如果文件個數(shù)不多,而且文件名中包含了空格等特殊字符的話,建議使用這種方法,在這里就不多說啦,至于在fortran中的處理,等幾個小方法介紹完之后會有一個例子來說明。 1.2、 運行程序之前命令行工具導(dǎo)出文件名 這是一個既高效又保險的方法,主要思路就是通過強大的CMD命令列出目錄下的文件到一個指定的文件中,然后由fortran去循環(huán)讀取該文件中的文件名信息,從而批量處理。 a、 從運行工具
5、打開你的CMD窗口; b、轉(zhuǎn)到要處理的當前目錄(可省略):CD /d 路徑,如: CD /d e:test 這樣可以快速到達e:test目錄 c、 使用DIR命令列出文件目錄信息到指定的文件,通常使用的 Dir *.*>新文件名 這個命令在這里已經(jīng)不能滿足要求,因為會列出一堆對于我們處理而言無用的信息,現(xiàn)
6、在要使用的命令是: DIR /b filter>newfile 注意,其中的filter為文件篩選,必須自己修改為所需的,比如你可以把它改成*.txt,這樣,就會列出當前目錄下的所有txt結(jié)尾的文件了。 Newfile就是你需要存放文件名的那個文件,比如可以是 dir.txt,這樣就成了 dir /b*.txt>dir.txt,就會把當前目錄下的所有文件都列出到dir.txt文件中,當然,由于dir.txt也在當前目錄,所以也會被算
7、進去,這在處理的時候是需要注意的,下面幾種方法中同樣考慮了這個問題。你可以選擇手動刪掉,或者把dir.txt這個文件存到其他地方去,或者,不要和你需要的文件具有相同的后綴也行,比如:dir /b *.txt>e:dir.txt (假設(shè)當前目錄是e:test) 如果省略了第二步中的轉(zhuǎn)到當前目錄的話,就需要在dir命令后輸入完整的路徑了,而且新生成的文件也要選擇有權(quán)限建立新文件的地方存放,比如你在c:users目錄下輸入:dir /b e:test*.txt>e:dir.txt,這個命令和上面先轉(zhuǎn)到e:test目錄下的效果是一樣的。
8、60; 現(xiàn)在你是不是比較好奇,/b 是干嘛的,其實就是只列出文件名,不要其他的附件信息,比如創(chuàng)建時間,文件大小等等這些對于我們批處理無關(guān)的信息。 如果你想包含某個目錄下的子目錄,那么,就可以這樣寫: Dir /b/s filter>newfile /s就表示包含子目錄,但是,這樣會有一個問題,那就是,批處理的時候必須獲得正確的路徑才能操作,這樣得到的子目錄里面的文件不會有任何標志說他是來自子目錄的,因此fortran處理的時候就無法判斷了,所以,如果包含了子目錄,那么請用下面的命
9、令: Dir /a-d/b/s filter>newfile 現(xiàn)在去看看新生成的文件吧,怎么樣,很驚喜吧! 懂了這個方法,下面一部分的第一個方法對你來說就是小菜一碟啦。 如果你使用的win7(或vista)系統(tǒng),而且無法正常使用CVF編譯器的話,那么第一部分到這里就算結(jié)束啦,除非,你會在其他fortran編譯器中調(diào)用WIN32API。 1.3、程序運行后,未開始計算之前生成文件名 1.3.1、在程序中調(diào)用CMD命令
10、60; 這個方法其實就是上一個方法的進化版,只不過變成了在程序運行的時候調(diào)用命令自動生成,這樣整個過程顯得少一點,只需要在程序里設(shè)置好相關(guān)的參數(shù)即可。 這個方法的關(guān)鍵在于SYSTEMQQ函數(shù)的使用,這是CVF編譯器封裝的調(diào)用CMD命令的一個函數(shù),存在于DFLIB庫中,其語法命令為: result = SYSTEMQQ(commandline) commandline:表示需要進行的CMD操作,字符串形式,函數(shù)中
11、的實際長度由傳入的參數(shù)決定,input類型(表示輸入為參數(shù)); Results:一個邏輯型變量(logical(4)),如果成功為true,失敗為false(不解的是程序中要實現(xiàn)的東西都是正常的,比如僅僅傳入dir命令,返回的結(jié)果仍然為F,請高手賜教) 給出一個簡單的例子: USE DFLIB LOGICAL(4)resultresult = SYSTEMQQ('copy e:dir.txt e:testdir.txt') 這個命令將第一個路徑中的文件復(fù)制到為第二個路徑中的文件。通過這
12、個例子再結(jié)合上面一個方法,就可以很方法便的構(gòu)造出我們需要用來批處理的子函數(shù),關(guān)鍵語句如下所示:subroutine ListToFile(fPath,outPut)character*(*),InTent(In): fPath,outPut character*100CMD LOGICAL(4) res CMD="dir/a-d/b/s "/trim(fPath)/" >"/trim(outPut)res=SYSTEMQQ(CMD)endsubroutine
13、 其中傳入的是文件篩選值和輸出的路徑,這個方法也是我在第一部分中最為推薦的一個方法了,代碼簡潔高效,能夠輸出完整的路徑,可以包含子文件夾,唯一的缺點就是輸出的文件個數(shù)不能直接在程序中調(diào)用(方便循環(huán)),需要在批處理的時候使用其他方法來判斷文件是否讀取結(jié)束。 1.3.2、使用GETFILEINFOQQ方法生成文件目錄 該方法是下面一個方法的進化版,是由CVF對WIN32的API進行了封裝,這樣,我們就可以通過簡單的調(diào)用函數(shù)來實現(xiàn)一些面向?qū)ο蟮墓δ堋:唵蔚姆g了一下官方給出的GET
14、FILEINFOQQ函數(shù)信息:Module: USE DFLIB (存在于DFLIB庫中)語法簡介:Syntax result = GETFILEINFOQQ (files, buffer, handle) files :輸入類型的字符型變量,表示你需要查找的路徑(也就是我們上面方法中的篩選值),同樣可以使用*或者?這樣的通配符。 buffer :在函數(shù)運行中會獲得一個值,可供輸出使用,這個值就是所找到的文件的相關(guān)信息,屬于FILE$INFO類型的變量(該類型定義于:fortran安裝路徑DF98INCLUDE路徑下),其結(jié)構(gòu)如下:T
15、YPE FILE$INFO INTEGER(4)CREATION INTEGER(4)LASTWRITE INTEGER(4)LASTACCESS INTEGER(4)LENGTH INTEGER(4)PERMIT CHARACTER(255)NAMEEND TYPE FILE$INFO handle :接受輸入和輸出整型變量
16、,表示文件控制信息(同樣在DFLIB中定義),包含以下內(nèi)容:FILE$FIRST - First matching file found.FILE$LAST - Previous file was the last valid file.FILE$ERROR - No matching file found.Results: 返回值是一個整型變量(integer(4)),表示的不含空格的文件名長度,如果文件未找到,則返回0。 了解了以上信息,我們就可以通過編程進行循環(huán)調(diào)用這個函數(shù),每找到一個符合條件的文件,就把他輸入到指定路徑的文件中去,注意,凡
17、是input類型的變量都必須傳入數(shù)值,否則會出錯。 如果你比較有探索精神,就試著用這個介紹和思路來編程一下吧,子程序如下所示(完整的請下載附件)Subroutine GetFileList(cFileName,outPut,iFile) UseDFLib,only:GetFileInfoQQ,GetLastErrorQQ,FILE$INFO,FILE$LAST,FILE$ERROR,FILE$FIRST,ERR$NOMEM,ERR$NOENT,FILE$DIR !引入庫函數(shù)Implicit None!根據(jù)上面的語
18、法介紹來定義變量Character*(*),Intent(In):cFileName !篩選值character*(*),intent(In):output !輸出路徑Integer,Intent(InOut):iFile !記錄已經(jīng)找到幾個文件TYPE (FILE$INFO) info !找到的文件的信息INTEGER(4):Wildhandle,length !文件控制信息,文件大小,Wildhandle = FILE$FIRSTiFile = 0 DOWHILE (.TRUE.
19、) !循環(huán)找文件 length = GetFileInfoQQ(cFileName,info,Wildhandle) !調(diào)用函數(shù)找文件!如果遇到錯誤或者不能再找到不同的文件,則進入選擇,準備退出 IF (Wildhandle .EQ. FILE$LAST) .OR.(Wildhandle .EQ. FILE$ERROR) THEN SELECT CASE (GetLastErrorQ
20、Q() CASE (ERR$NOMEM) !/內(nèi)存不足 iFile = - 1 Return CASE (ERR$NOENT) !/碰到通配符序列尾,正常退出
21、 Return CASE DEFAULT iFile = 0 Return END SELECT END IF
22、;iFile= iFile + 1 Call WriteFileName( Trim(info.Name) ,outPut, iFile) !調(diào)用子函數(shù)輸出文件名 ENDDOEnd Subroutine GetFileList 注意,在調(diào)用子函數(shù)輸出文件名時,要做一些處理,主要是判斷文件是否存在(不存在則新建,如果是第一次找到,而且文件存在,則覆蓋,否則追加),以及找到的是否為我們自己建立的這個dir.txt文件(如果是,則忽略,找到的文件數(shù)量-1)
23、 這個方法也不錯,如果不需要子目錄的信息,其優(yōu)越性不亞于上一種方法,因為該子函數(shù)能夠直接返回找到的文件數(shù)量。 1.3.3調(diào)用WIN32API生成目錄下的文件信息 有了上面的幾種方法,其實這個方法可以不需要介紹,但是也許有和我一樣喜歡刨根問底的朋友,還是貼出來,也算是分享一下CVF平臺下對于API的調(diào)用方法。fortran的最大強項是數(shù)值計算,他本身對于各種系統(tǒng)信息的處理功能實在不敢說好,如果要實現(xiàn)一些交互的功能目前來說還是比較復(fù)雜的。 該方法直接調(diào)用系統(tǒng)的API函數(shù)來實現(xiàn)功能,理論上
24、只要是fortran編譯器支持API調(diào)用,就可以使用該方法,也就是說可以用于win7和vista(linux的不在本次討論范圍,上面的幾種方法思路在linux均需要變換才能使用)。目前我還沒有測試在MPF4.0等其他的編譯器中使用API函數(shù)的情況,感興趣的測試后不要忘了來分享啊v。 該方法主要使用了一下三個系統(tǒng)函數(shù):FindFirstFile,F(xiàn)indNextFile和FindClose,這三個函數(shù)存在于系統(tǒng)的Kernel32.dll函數(shù)中,因此調(diào)用之前需要先引用這個函數(shù)庫。簡單給出這三個函數(shù)的介紹:HRESULT FindFirstFile(
25、 in,string LPCWSTR wsSearchFile out LPWIN32_FIND_DATAW pFindFileData
26、60; out LPHANDLE pSearchHandle );wsSearchFile:字符串類型的變量,也就是上面說的篩選值, pFindFileData,表示所找到的文件的信息,類似上面方法中的那個FILE$INFO類型,也是在函數(shù)調(diào)用過程中生成信息,他的類型就是WIN32_FIND_D
27、ATA(一個結(jié)構(gòu)體,在fortran中使用TYPE定義)。pSearchHandle:這是一個表示文件地址的變量,類似于我們用OPEN命令打開一個文件時,前面給一個unit的意思,他可以用在后面的FindNextFile和FindClose函數(shù)中。該函數(shù)的返回值為0表示文件未找到。 HRESULT FindNextFile( in HANDLE hSear
28、chHandle out LPWIN32_FIND_DATAW pFindFileData ); 該函數(shù)可以用上面所獲得HANDLE句柄來查找下一個符合條件的文件,函數(shù)運行過程中同樣給pFindFileData生成了相關(guān)信息,文件名就從其中獲取。返回值同F(xiàn)indFirstFile。 HRESULT FindClose( in
29、160; HANDLE hSearchHandle ); 根據(jù)上面的文件句柄關(guān)閉文件,返回值同上。 有了對這三個函數(shù)的了解,接下來的事情就是如何使用這三個函數(shù)了,給出關(guān)鍵的子程序并作說明:subroutine FindName(FileExt,outFile,iFile) Usekernel32 !載入函數(shù)庫integer,parameter:maxlen=80 ! 設(shè)置一個文
30、件名長度的閾值CHARACTER*(*) FileExt,OutFile !篩選值和目標路徑Integer(4) hFind,res !文件句柄和返回值integer(4),intent(inout):iFile !已找到的文件個數(shù)(不含dir.txt)Type(t_WIN32_FIND_DATA) FindFileData !系統(tǒng)定義的一個結(jié)構(gòu)體信息,具體的可以自行查閱WIN32API手冊character*maxlen cname ! 這個變量用來存放獲得的文件名,長度為上
31、面所設(shè)定的,不宜太長 res=1iFile=0 hFind = FindFirstFile(FileExt,FindFileData) !找第一個文件 If(hFind = INVALID_HANDLE_VALUE)then Return ! 沒有找到匹配文件,返回結(jié)果=-1 else
32、60; !繼續(xù)循環(huán)尋找下一個 do while(res) iFile=iFile+1 !先把已有的寫入文件 cname=F
33、indFileData.cFileName !這一段代碼很特殊,主要是因為調(diào)用API之后,默認的文件名長度非常之長,用常用的trim()函數(shù)無法縮短,因為文件名后面并不是空格,而是一個值為0的ASCII字符,因此用循環(huán)將這個字符替換為空格,以便于后面的處理,這也是上面說閾值不宜過大的愿意,否則浪費時間
34、 do i=1,maxlen if(ichar(cname(i:i)=0) cname(i:i)=' ' enddo callWriteFileName(trim
35、(cname),outFile,iFile) !調(diào)用子函數(shù)寫出文件名 res=FindNextFile(hFind,FindFileData) 繼續(xù)查找下一個,用res的值來控制循環(huán)是否退出 enddo res=FindClose(hFind)
36、160; !退出循環(huán)后關(guān)閉文件 endifendsubroutine 腫么樣,API函數(shù)看下來是否有點暈暈的,能看到這里相信你對fortran的理解又加深了一些吧。該方法和上一種方法如出一轍,優(yōu)缺點也近乎相同,同樣沒有包含子目錄(你有興趣的話可以試試能否使用FindFileData里面的信息讓這個子程序包含子目錄,如果有了結(jié)果,同樣不要忘了來分享哦)。 總結(jié)一下上面的幾種方法,手工輸入適用于文件比較少,而且路徑比較復(fù)雜的時候;使用
37、dir命令幾乎可以通吃,但是無法直接給出文件數(shù)目;PI函數(shù)功能較為一般,但是可以直接獲得找到的文件個數(shù),而且通過writefile子函數(shù)的處理,可以讓dir.txt直接存在于當前目錄下但不包含在本身的文件列表中。選哪一種,完全看你的需要和喜好啦! 一個小小的例子(使用SYSTEMQQ實現(xiàn)):在當前目錄下有 1.txt4.txt這樣4個文本文件(注意路徑以及文件名中不要有空格,否則fortran中就得按字符讀取了),分別存放一個數(shù)字:1,2,3,4,要求循環(huán)讀取這些文件中的數(shù)字,并且相加,給出最終的和,程序如下:program listfilecharacter*100 fPathcharacter*200 pathcharacter*7 outPutinteger a,bb=0fPath="*.txt"outPut="dir.txt"call ListToFile(fPath,outPut) !先生
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 《美人魚》觀后感(合集15篇)
- 海洋科技創(chuàng)新實施的具體操作方案
- 供水管網(wǎng)優(yōu)化升級計劃可行性研究報告(模板)
- 新疆烏魯木齊市六校聯(lián)考2022-2023學年高二下學期期末英語 含解析
- 河南省開封市五縣聯(lián)考2023-2024學年高二上學期期中考物理含解析
- 甲狀腺癌核醫(yī)學診療體系
- 福州大學《計算機網(wǎng)絡(luò)與通信課程設(shè)計》2023-2024學年第二學期期末試卷
- 幾何畫板制作函數(shù)課件
- 上海中華職業(yè)技術(shù)學院《非織造復(fù)合材料》2023-2024學年第二學期期末試卷
- 泉州海洋職業(yè)學院《知識產(chǎn)權(quán)法經(jīng)典著作》2023-2024學年第二學期期末試卷
- 網(wǎng)絡(luò)安全宣傳周網(wǎng)絡(luò)安全知識手冊學習課件
- 2024年公文寫作基礎(chǔ)知識競賽試題庫及答案(共220題)
- 2024年江蘇省鎮(zhèn)江市中考化學試卷(含答案解析)
- 黃金卷06(解析版)-【贏在高考·黃金8卷】備戰(zhàn)2024年高考生物模擬卷(河北專用)
- 實驗:驗證動量守恒定律 說課課件-2024-2025學年高二上學期物理人教版(2019)選擇性必修第一冊
- 管道大開挖穿越公路施工方案
- 創(chuàng)新創(chuàng)業(yè)理論與實踐(西安工業(yè)大學)智慧樹知到期末考試答案章節(jié)答案2024年西安工業(yè)大學
- 2024-2030年中國桑蠶絲市場消費需求潛力與前景競爭優(yōu)勢分析研究報告
- 骨傷科常見疾病中醫(yī)診療規(guī)范診療指南2023版
- 省級一網(wǎng)統(tǒng)管網(wǎng)格化社會治理指揮手冊(含事項清單)
- 四川省成都市青羊區(qū)2024年四年級數(shù)學第二學期期末調(diào)研試題含解析
評論
0/150
提交評論