UTL_FILE包可以用來讀寫操作系統上的文本文件,UTL_FILE提供了在客戶端(FORM等等)和服務器端的文件訪問功能。 創建測試目錄: 新建一個command window; 創建目錄:(以system用戶登錄數據庫) Sql代碼 收藏代碼 SQL> create or replace directory cux_log_dir as '/home/appltest/debug'; Directory created 賦權限。 Sql代碼 收藏代碼 SQL> grant read, write on directory cux_log_dir to public; Grant succeeded 檢查目錄是否成功創建 Sql代碼 收藏代碼 select * FROM all_directories dir WHERE dir.DIRECTORY_NAME = 'CUX_LOG_DIR'; Ps:視圖all_directories存放着我們能否訪問的目錄對象。如果要刪除目錄,也需用system用戶登錄數據庫,執行如下命令:Drop directory cux_log_dir; 過程和函數: FOPEN 描述:打開一個文件,基本上在我們對文件進行讀寫動作之前都需要先執行這個function來打開文件先。 語法: UTL_FILE.FOPEN ( location IN VARCHAR2, filename IN VARCHAR2, open_mode IN VARCHAR2, max_linesize IN BINARY_INTEGER DEFAULT 1024) RETURN FILE_TYPE; 參數:location 略。 Filename 略。 open_mode 指明文件打開的模式。有如下幾種: ■r –只讀(文本) ■ w – 只寫(本文) ■ a – 追加(文本) ■ rb – 只讀(字節) ■ wb – 只寫(字節) ■ ab – 追加(字節) (注:當使用模式:a或者ab的時候,如果文件不存在,則會以write模式創建此文件) max_linesize 指定文件文本每一行存放的最大字符數。 返回值:FOPEN返回一個接下來我們的程序將要使用到的文件的指針 FCLOSE 功能:關閉一個打開的文件。 語法:UTL_FILE.FCLOSE (file IN OUT FILE_TYPE); 參數:1. file->調用FOPEN或者FOPEN_NVCHAR返回的活動中的文件指針。 注意事項:當FCLOSE執行的時候,如果還有緩沖數據沒有及時寫入到文件中,那么程序就會raise一個異常:WRITE_ERROR。可以在PUT_LINE的時候加上參數autoflush => TRUE;或者在每次PUT之后執行:FFLUSH。 FCLOSE_ALL 功能:此procedure將會關閉本次session所有打開的文件。它用來緊急情況的清理功能,例如當PL/SQL程序在EXCEPTION部分退出時。 語法:UTL_FILE.FCLOSE_ALL; 注意事項:FCLOSE_ALL不會修改所打開的文件的狀態,也就是說執行了FCLOSE_ALL后,再用IS_OPEN去檢測文件,結果還是打開狀態,但是之后,這些文件任然是不能去read或者write的。而FCLOSE執行后,相關的文件則完全關閉了,測試: 結果為: 結果為: FCOPY 功能:此procedure復制一個文件的連續部分內容或者全部內容到一個新創建的文件。如果參數start_line和end_line省略的話,默認地會復制整個文件。此操作會將源文件以read模式打開,將目標文件以write模式打開。 語法: UTL_FILE.FCOPY ( src_location IN VARCHAR2, src_filename IN VARCHAR2, dest_location IN VARCHAR2, dest_filename IN VARCHAR2, start_line IN BINARY_INTEGER DEFAULT 1, end_line IN BINARY_INTEGER DEFAULT NULL); 參數:src_location來源文件的目錄名。取值來源是視圖ALL_DIRECTORIES的DIRECTORY_NAME; src_filename 將要被復制的來源文件 dest_location 被創建的目標文件存放的目錄名。 dest_filename 從來源文件創建的目標文件。 start_line 要復制的內容起始行號,默認為1,表示從第一行開始復制。 end_line 要復制的內容的終止行號,默認NULL,表示文件的末尾。 測試程序之前: 測試代碼: 測試程序之后: 並且l001-copy.log文件中的內容只有兩行: FFLUSH 描述:FFLUSH強制將緩沖的數據寫入文件。因為通常待寫入文件的數據都是都在緩沖存儲位置。當有必要去read一個任然處於打開狀態的文件時,FFLUSH就起作用了,例如在調試程序中,可以將調試的消息及時沖到文件中,已便於我們馬上就能read這些內容。 語法: UTL_FILE.FFLUSH (file IN FILE_TYPE); FGETATTR 描述:FGETATTR讀取磁盤上的文件並返回文件的屬性。 語法:UTL_FILE.FGETATTR( location IN VARCHAR2, filename IN VARCHAR2, fexists OUT BOOLEAN, file_length OUT NUMBER, block_size OUT BINARY_INTEGER); 參數:location 此處略去X個字。 filename此處略去X個字。 fexists 返回的屬性1:文件是否存在 file_length 返回的屬性2:文件字節長度,如果文件不存在,則返回NULL。 block_size 文件系統塊的字節大小。 測試: Sql代碼 收藏代碼 DECLARE l_loc all_directories.directory_name%TYPE := 'CUX_LOG_DIR'; l_file utl_file.file_type; l_file_exsits BOOLEAN; l_file_length NUMBER; l_block_size BINARY_INTEGER; l_buffer VARCHAR2(1024); BEGIN utl_file.fgetattr(location => l_loc, filename => 'l001.log', fexists => l_file_exsits, file_length => l_file_length, block_size => l_block_size); IF l_file_exsits THEN l_file := utl_file.fopen(location => l_loc, filename => 'l001.log', open_mode => 'R'); dbms_output.put_line('file exsits'); dbms_output.put_line('file length:' || l_file_length); dbms_output.put_line('block sieze :' || l_block_size); END IF; utl_file.fclose_all; END; 輸出結果: file exsits file length:39802 block sieze :4096 FGETPOS 描述:此函數返回一個文件中當前的偏移位置。 語法: UTL_FILE.FGETPOS (file IN FILE_TYPE) RETURN PLS_INTEGER; 注意事項:如果file沒有打開,則會拋出異常。 測試: Sql代碼 收藏代碼 DECLARE l_loc all_directories.directory_name%TYPE := 'CUX_LOG_DIR'; l_file utl_file.file_type; l_buffer VARCHAR2(32767); BEGIN l_file := utl_file.fopen(location => l_loc, filename => 'l001.log', open_mode => 'R'); dbms_output.put_line('before get_line: current position is ' || utl_file.fgetpos(file => l_file)); utl_file.get_line(file => l_file, buffer => l_buffer); dbms_output.put_line('after get_line: current position is ' || utl_file.fgetpos(file => l_file)); utl_file.fclose_all; END; 結果:before get_line: current position is 0 after get_line: current position is 3 FREMOVE 描述:此procedure在你有充足的權限之下,刪除一個磁盤上的文件。 語法: UTL_FILE.FREMOVE ( location IN VARCHAR2, filename IN VARCHAR2); FRENAME 描述:此procedure將一個存在的文件重命名,類似unix命令:mv 語法: UTL_FILE.FRENAME ( src_location IN VARCHAR2, src_filename IN VARCHAR2, dest_location IN VARCHAR2, dest_filename IN VARCHAR2, overwrite IN BOOLEAN DEFAULT FALSE); 參數:介紹略。 GET_LINE 描述:此procedure從一個打開的文件中讀取一行文本,直到遇到換行符。 語法: UTL_FILE.GET_LINE ( file IN FILE_TYPE, buffer OUT VARCHAR2, len IN PLS_INTEGER DEFAULT NULL); 參數:len 從文本中讀取一次的長度,默認是null,oracle就取FOPEN時的max_linesieze。 IS_OPEN 描述:顧名思義。 語法:UTL_FILE.IS_OPEN (file IN FILE_TYPE) RETURN BOOLEAN; PUT 描述:PUT寫入內容到文件中。(每寫一次,不帶換行符) 語法:UTL_FILE.PUT (file IN FILE_TYPE, buffer IN VARCHAR2); PUT_LINE 描述:PUT_LINE寫入內容到文件中。(每寫一次,末尾都加一個換行符) 語法: UTL_FILE.PUT_LINE ( file IN FILE_TYPE, buffer IN VARCHAR2, autoflush IN BOOLEAN DEFAULT FALSE); PUTF 描述: 寫入格式化的內容到文件中。好比C語言的printf() 語法: UTL_FILE.PUTF ( file IN FILE_TYPE, format IN VARCHAR2, [arg1 IN VARCHAR2 DEFAULT NULL, . . . arg5 IN VARCHAR2 DEFAULT NULL]); 參數:format 包含格式化字符[\n,%s]的內容。 \n:代表一個換行符。 %s:用arg1~5的值去代替。 完整例子程序: Sql代碼 收藏代碼 DECLARE l_loc all_directories.directory_name%TYPE := 'CUX_LOG_DIR'; l_file utl_file.file_type; l_file_exsits BOOLEAN; l_file_length NUMBER; l_block_size BINARY_INTEGER; l_buffer VARCHAR2(32767); --data CURSOR c_hander IS SELECT fu.user_name, fu.description FROM fnd_user fu WHERE 1 = 1 AND fu.user_name LIKE 'XXX%' ORDER BY fu.user_name; BEGIN utl_file.fgetattr(location => l_loc, filename => 'test.log', fexists => l_file_exsits, file_length => l_file_length, block_size => l_block_size); --put IF l_file_exsits THEN l_file := utl_file.fopen(location => l_loc, filename => 'test.log', open_mode => 'w'); l_buffer := 'begining of file....'; utl_file.put_line(file => l_file, buffer => l_buffer); FOR l IN c_hander LOOP l_buffer := l.user_name || chr(9) || nvl(l.description, 'no description'); utl_file.put_line(file => l_file, buffer => l_buffer); END LOOP; l_buffer := 'end of file....'; utl_file.put_line(file => l_file, buffer => l_buffer); --flush utl_file.fflush(file => l_file); --get l_file := utl_file.fopen(location => l_loc, filename => 'test.log', open_mode => 'r'); utl_file.fgetattr(location => l_loc, filename => 'test.log', fexists => l_file_exsits, file_length => l_file_length, block_size => l_block_size); LOOP utl_file.get_line(file => l_file, buffer => l_buffer, len => 32767); dbms_output.put_line(a => l_buffer); EXIT WHEN utl_file.fgetpos(file => l_file) = l_file_length; END LOOP; END IF; utl_file.fclose_all; END;
詳細:http://zhangzhongjie.iteye.com/blog/1903024