UTL_FILE包的使用解析
UTL_FILE包可以用來讀寫操作系統上的文本文件,UTL_FILE提供了在客戶端(FORM等等)和服務器端的文件訪問功能。
創建測試目錄:
??? 新建一個command window;
??? 創建目錄:(以system用戶登錄數據庫)
SQL> create or replace directory utl_dir as '/home/oracle';
Directory created.
$ cat abc.log?
the begining of file
Hello World!
Thank you!
Bye!
SQL> grant read, write on directory cux_log_dir to public;??
??? Grant succeeded?
檢查目錄是否成功創建
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執行后,相關的文件則完全關閉了,測試:
declare
? l_loc? VARCHAR2(100) :='UTL_DIR';
? l_file utl_file.file_type;
? l_buffer? varchar2(1024);
begin
? l_file := utl_file.fopen(location??? => l_loc,
?????????????????????????? filename??? => 'abc.log',
?????????????????????????? open_mode?? => 'R');
? utl_file.fclose(file???? => l_file);
--? utl_file.fclose_all;
? if utl_file.is_open(file => l_file) THEN
???? dbms_output.put_line('OPEN');
? ELSE
???? dbms_output.put_line('CLOSE');
? END IF;
?? utl_file.get_line(file => l_file, buffer=> l_buffer);
exception
? when others then
?? dbms_output.put_line(SQLERRM);
end;
/
ClOSE
ORA-29282: invalid file ID
?
declare
? l_loc? VARCHAR2(100) :='UTL_DIR';
? l_file utl_file.file_type;
? l_buffer? varchar2(1024);
begin
? l_file := utl_file.fopen(location??? => l_loc,
?????????????????????????? filename??? => 'abc.log',
?????????????????????????? open_mode?? => 'R');
--?? utl_file.fclose(file???? => l_file);
???? utl_file.fclose_all;
? if utl_file.is_open(file => l_file) THEN
???? dbms_output.put_line('OPEN');
? ELSE
???? dbms_output.put_line('CLOSE');
? END IF;
?? utl_file.get_line(file => l_file, buffer=> l_buffer);
exception
? when others then
?? dbms_output.put_line(SQLERRM);
end;
/
OPEN
ORA-29282: invalid file ID
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,表示文件的末尾。
測試程序之前:
$ cat abc.log?
the begining of file
Hello World!
Thank you!
Bye!
測試代碼:
declare
? l_loc?? all_directories.directory_name%type := 'UTL_DIR';
BEGIN
? utl_file.fcopy(src_location?? => l_loc,
??????????????? src_filename??? => 'abc.log',
??????????????? dest_location?? => l_loc,
??????????????? dest_filename?? => 'efg.log',
??????????????? start_line???? ?? => 1,
??????????????? end_line??????? => 2);
exception
? WHEN OTHERS THEN
??? dbms_output.put_line(SQLERRM);
end;
/
測試程序之后:
[oracle@dbserver ~]$ cat efg.log?
the begining of file
Hello World!
并且efg.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? 文件系統塊的字節大小。
測試:
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沒有打開,則會拋出異常。
測試:
?declare
? l_loc? varchar2(100)? := 'UTL_DIR';
? l_file utl_file.file_type;
? l_buffer? VARCHAR2(1000);
begin
? l_file := utl_file.fopen(location => l_loc,
?????????????????????????? filename => 'abc.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));
end;
/
before get_line: current position is 0
after get_line: current position is 21
PL/SQL procedure successfully completed.
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);
測試
declare
? l_loc??? varchar2(100) := 'UTL_DIR';
? l_file?? utl_file.file_type;
? l_buffer varchar2(1000);
begin
? l_file?? := utl_file.fopen(location => l_loc,
???????????????????????????? filename => 'abc.log',
???????????????????????????? open_mode => 'r');
? utl_file.get_line(file => l_file,
??????????????????? buffer => l_buffer);
? dbms_output.put_line( l_buffer);
? utl_file.fclose(file?? => l_file);
? l_file?? := utl_file.fopen(location => l_loc,
???????????????????????????? filename => 'abc.log',
???????????????????????????? open_mode => 'A');
? l_buffer := 'Add one more line!!!';
? utl_file.put_line(file???? => l_file,
??????????????????? buffer?? => l_buffer);
? utl_file.fclose(file?? => l_file);
end;????
/
the begining of file
PL/SQL procedure successfully completed.
$ cat abc.log?
the begining of file
Hello World!
Thank you!
Bye!
Add one more line!!!
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的值去代替。
完整例子程序:
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://blog.chinaunix.net/uid-7374279-id-3839512.html
http://www.cnblogs.com/advocate/archive/2011/02/18/1957540.html
http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/u_file.htm?bcsi_scan_7B0C6D5865CF5974=0&bcsi_scan_filename=u_file.htm#i1003796
如有錯誤,歡迎指正
郵箱:czmcj@163.com
作者:czmmiao ?文章出處:http://czmmiao.iteye.com/blog/2142705總結
以上是生活随笔為你收集整理的UTL_FILE包的使用解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c++语言生成一个随机数,C++ 快速随
- 下一篇: 字符串中的 ↵ 回车符替换