天天看點

UTL_FILE 包的使用詳解

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

如有錯誤,歡迎指正

郵箱:[email protected]

作者:czmmiao  文章出處:http://czmmiao.iteye.com/blog/2142705