utl_file包可以用來讀寫作業系統上的文本檔案,utl_file提供了在用戶端(form等等)和伺服器端的檔案通路功能。
建立測試目錄:
建立一個command window;
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
-- utl_file.fclose(file => l_file);
utl_file.fclose_all;
open
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,表示檔案的末尾。
測試程式之前:
測試代碼:
l_loc all_directories.directory_name%type := 'utl_dir';
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);
dbms_output.put_line(sqlerrm);
測試程式之後:
[oracle@dbserver ~]$ cat efg.log
并且efg.log檔案中的内容隻有兩行:
fflush
描述:fflush強制将緩沖的資料寫入檔案。因為通常待寫入檔案的資料都是都在緩沖存儲位置。當有必要去read一個任然處于打開狀态的檔案時,fflush就起作用了,例如在調試程式中,可以将調試的消息及時沖到檔案中,已便于我們馬上就能read這些内容。
utl_file.fflush (file in file_type);
fgetattr
描述:fgetattr讀取磁盤上的檔案并傳回檔案的屬性。
文法:utl_file.fgetattr( location 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_buffer varchar2(1000);
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));
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);
測試
l_loc varchar2(100) := 'utl_dir';
l_file utl_file.file_type;
l_buffer varchar2(1000);
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);
open_mode => 'a');
l_buffer := 'add one more line!!!';
utl_file.put_line(file => l_file,
buffer => l_buffer);
end;
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的值去代替。
完整例子程式:
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....';
--flush
utl_file.fflush(file => l_file);
--get
l_file := utl_file.fopen(location => l_loc,
filename => 'test.log',
open_mode => 'r');
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 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
如有錯誤,歡迎指正
作者:czmmiao 文章出處:http://czmmiao.iteye.com/blog/2142705