#UTL_FILE

UTL_FILE包为用户提供了读写系统文件的能力,用户可以通过UTL_FILE操作系统文件。

【注】location、src_location、dest_location参数说明: 1、参数仅支持起始为"."或"/"的路径。 2、参数若被赋值起始为"."的路径,此时是相对于环境变量YASDB_DATA的的路径。

# FCLOSE

UTL_FILE.FCLOSE (
   file IN OUT FILE_TYPE);

FCLOSE函数用于关闭通过FILE_TYPE指定的文件。

参数 描述
file FOPEN成功执行后返回的file值

示例

DECLARE
    HANDLE_R UTL_FILE.FILE_TYPE;
    BUFFER_R VARCHAR2(200);
BEGIN
        HANDLE_R := UTL_FILE.FOPEN('/test','t2.txt','r',200);
        UTL_FILE.FCLOSE(HANDLE_R);
END;
/ 

# FCLOSE_ALL

UTL_FILE.FCLOSEALL (
  );

FCLOSE_ALL函数用于关闭当前session下所有打开的file handle。 多数用于紧急情况下的文件句柄清理。

参数 描述
/ /

示例

DECLARE
   BEGIN
   UTL_FILE.FCLOSE_ALL();
   END;
   /

# FCOPY

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);

FCOPY复制源文件到一个新创建的目标文件中。如果不指定start_line和end_line,将默认复制整个源文件。源文件以只读模式打开,目标文件以只写方式打开。将复制源文件的start_line到end_line的内容到目标文件中。

参数 描述
src_location 源文件所在的路径
src_filename 源文件名字
dest_location 目标文件所在的路径
dest_filename 目标文件名字
start_line 从源文件的第几行开始复制,默认为1
end_line 复制到源文件的第几行,默认为NULL,表示源文件的最后一行

示例

DECLARE
    HANDLE_R UTL_FILE.FILE_TYPE;
    BUFFER_R VARCHAR2(200);
BEGIN
    UTL_FILE.FCOPY('/test','t1.txt','/test','t2.txt');   
END;
/  

# Fflush

UTL_FILE.FFLUSH (
   file  IN FILE_TYPE);

Fflush函数将指定的打开的文件句柄对应的还没有刷盘的数据刷到磁盘上。一般情况下,数据先写到缓冲区再写到磁盘上。

参数 描述
file FOPEN成功执行后返回的file值

示例

DECLARE
    HANDLE_W UTL_FILE.FILE_TYPE;
    BUFFER_W VARCHAR2(200);
    writenNum INT;
BEGIN
      writenNum := 0;
	  BUFFER_W := LPAD('*',150 ,'*');
        HANDLE_W := UTL_FILE.FOPEN('/test','t2.txt','w',200);
    FOR i IN 1 .. 2 LOOP     
      UTL_FILE.PUT_LINE(HANDLE_W,BUFFER_W);
    END LOOP; 
    UTL_FILE.FFLUSH(HANDLE_W);	
END;
/ 


# FGET_ATTR

UTL_FILE.FGETATTR(
   location     IN VARCHAR2, 
   filename     IN VARCHAR2, 
   fexists      OUT BOOLEAN, 
   file_length  OUT NUMBER, 
   block_size   OUT BINARY_INTEGER);

FGET_ATTR函数返回磁盘文件的属性。

参数 描述
location 源文件所在的位置
filename 文件的名字
fexists 一个表示文件是否存在的BOOL值
file_length 文件的字节总长度,如果文件不存在,返回NULL
block_size 文件系统块的长度,如果文件不存在,返回NULL

示例

DECLARE
    HANDLE_R  UTL_FILE.FILE_TYPE;
    BUFFER_W  VARCHAR2(1000);
    fexists   BOOLEAN;
    flen      NUMBER;
    blockSize INT;
BEGIN
    UTL_FILE.FGETATTR('/test','t1.txt',fexists,flen,blockSize);
    DBMS_OUTPUT.PUT_LINE('t1.txt:');
    IF fexists THEN
    DBMS_OUTPUT.PUT_LINE(flen);
    DBMS_OUTPUT.PUT_LINE(blockSize);
    END IF;
  END;
/

# FOPEN

UTL_FILE.FOPEN (
   location     IN VARCHAR2,
   filename     IN VARCHAR2,
   open_mode    IN VARCHAR2,
   max_linesize IN BINARY_INTEGER DEFAULT 1024) 
  RETURN FILE_TYPE;

FOPEN 函数用于打开一个文件,可以指定一行的最大长度max_lineSize的范围在1-32000不指定的话默认为1024。在一个会话下默认打开50个文件,最多支持的打开文件数由 SESSION_MAX_OPEN_FILE指定。

参数 描述
location 文件所在的路径
filename 操作的文件名字
open_mode 打开的方式,目前支持a,w,r三种打开方式,分别是以追加、写、读打开。其中以写打开,会创建一个新的文件并覆盖旧文件; 以追加打开从文件末尾追加,如果没有文件会创建文件。
max_linesize 对文件读写的一行的最大长度

示例

DECLARE  
    HANDLE_R UTL_FILE.FILE_TYPE;
	HANDLE_A UTL_FILE.FILE_TYPE;
	HANDLE_W UTL_FILE.FILE_TYPE;
BEGIN
    HANDLE_R := UTL_FILE.FOPEN('/test','t1.txt','r',100);
    HANDLE_A := UTL_FILE.FOPEN('/test','t1.txt','a');
	HANDLE_W := UTL_FILE.FOPEN('/test','t1.txt','w',32000);
END;
/

--result

# Fremove

UTL_FILE.FREMOVE (
   location IN VARCHAR2,
   filename IN VARCHAR2);

Fremove函数用于删除磁盘的文件,如果有足够的权限的话可以成功删除。

参数 描述
location 文件所在的路径
filename 文件的名字

示例

DECLARE
    HANDLE_R UTL_FILE.FILE_TYPE;
    BUFFER_R VARCHAR2(200);
BEGIN
    UTL_FILE.FREMOVE('/test','t1.txt');   
END;
/

# Frename

UTL_FILE.FRENAME (
   src_location     IN   VARCHAR2,
   src_filename     IN   VARCHAR2, 
   dest_location    IN   VARCHAR2,
   dest_filename    IN   VARCHAR2,
   overwrite        IN   BOOLEAN DEFAULT FALSE);

Frename函数用于重命名一个已经存在的文件。

参数 描述
src_location 源文件所在的路径
src_filename 源文件的名字
dest_locatio 目标文件所在的路径
dest_filename 重命名的文件的名字
overwrite 如果目标文件已经存在,是否要覆盖

# Fseek

UTL_FILE.FSEEK (
   file             IN OUT  UTL_FILE.FILE_TYPE,
   absolute_offset  IN      PLS_INTEGER DEFAULT NULL,
   relative_offset  IN      PLS_INTEGER DEFAULT NULL);

Fseek用来将当前的文件指针向前或者向后移动指定的字节数,只能用于以读方式打开的文件句柄。

参数 描述
file 文件句柄
absolute_offset 文件指针移动的绝对偏移值,默认为NULL。
relative_offset 文件指针移动的相对偏移,基于当前的偏移值,如果<0则向前移动n个字节,如果>0则向后移动n个字节。

示例

DECLARE  
    HANDLE_R UTL_FILE.FILE_TYPE;
    BUFFER_R  VARCHAR2(500);
BEGIN
    IF UTL_FILE.IS_OPEN(HANDLE_R) THEN
        DBMS_OUTPUT.PUT_LINE('HANDLE_R FILE HAS OPENED');
    ELSE
        HANDLE_R := UTL_FILE.FOPEN('/test','t1.txt','r',500);
        DBMS_OUTPUT.PUT_LINE('HANDLE_R FILE FIRST OPEN');
    END IF;
     
    UTL_FILE.FSEEK(HANDLE_R,10,0);
    UTL_FILE.GET_LINE(HANDLE_R,BUFFER_R,200);
    DBMS_OUTPUT.PUT_LINE(BUFFER_R);
     
END;
/

# GET_LINE

UTL_FILE.GET_LINE (
   file        IN  FILE_TYPE,
   buffer      OUT VARCHAR2,
   len         IN  PLS_INTEGER DEFAULT NULL);

GET_LINE函数用于从文件中读取一行,但是读取的一行的长度不能超过FOPEN函数中设置的max_linesize。 另外,GET_LINE函数只支持在以只读模式打开的文件句柄中使用。

参数 描述
file 文件句柄
buffer 从文件中读取的一行数据放置的缓冲区
len 从文件中读取几个字节,默认为NULL。如果是NULL,yasdb会将该值设置为max_linesize

示例

DECLARE  
    HANDLE_R UTL_FILE.FILE_TYPE;
    BUFFER_R  VARCHAR2(500);
BEGIN
    IF UTL_FILE.IS_OPEN(HANDLE_R) THEN
        DBMS_OUTPUT.PUT_LINE('HANDLE_R FILE HAS OPENED');
    ELSE
        HANDLE_R := UTL_FILE.FOPEN('/test','t2.txt','r',500);
        DBMS_OUTPUT.PUT_LINE('HANDLE_R FILE FIRST OPEN');
    END IF;
     
    UTL_FILE.FSEEK(HANDLE_R,10,0);
    UTL_FILE.GET_LINE(HANDLE_R,BUFFER_R,200);
    DBMS_OUTPUT.PUT_LINE(BUFFER_R);
     
END;
/

# IS_OPEN

UTL_FILE.IS_OPEN(
   FILE IN FILE_TYPE
)

IS_OPEN用于判断当前fileHandle对应的文件是否已经打开。

参数 描述
FILE_TYPE 对文件进行操作的句柄

示例

DECLARE
    HANDLE_R UTL_FILE.FILE_TYPE;
    BUFFER_R VARCHAR2(200);
BEGIN
    IF UTL_FILE.IS_OPEN(HANDLE_R) THEN
        DBMS_OUTPUT.PUT_LINE('HANDLE_R FILE HAS OPENED');
    ELSE
        HANDLE_R := UTL_FILE.FOPEN('/test','t2.txt','r',200);
        DBMS_OUTPUT.PUT_LINE('HANDLE_R FILE FIRST OPEN');
    END IF;     
END;
/  

--result

# NEW_LINE

UTL_FILE.NEW_LINE (
   file     IN FILE_TYPE,
   lines    IN BINARY_INTEGER := 1);

NEW_LINE函数用于对文件句柄指定的文件增加一行或者多行换行,这个函数和PUT函数配合的效果相当于PUT_LINE。

参数 描述
file 文件句柄
lines 增加几个换行

示例

DECLARE
    HANDLE_R UTL_FILE.FILE_TYPE;
    HANDLE_W UTL_FILE.FILE_TYPE;
    BUFFER_R VARCHAR2(200);
    writenNum INT;
BEGIN
    writenNum := 0;
    HANDLE_R := UTL_FILE.FOPEN('/test','t1.txt','r',200);
    HANDLE_W := UTL_FILE.FOPEN('/test','t2.txt','w',300);
       
    FOR i IN 1 .. 2 LOOP     
      UTL_FILE.GET_LINE(HANDLE_R,BUFFER_R,110);
      DBMS_OUTPUT.PUT_LINE(BUFFER_R);
       
      UTL_FILE.PUT(HANDLE_W,BUFFER_R);
      IF i = 2 THEN
        UTL_FILE.NEW_LINE(HANDLE_W);
        UTL_FILE.FFLUSH(HANDLE_W);
      END IF;
    END LOOP;
    UTL_FILE.FFLUSH(HANDLE_W);
END;
/

# PUT

UTL_FILE.PUT (
   file      IN FILE_TYPE,
   buffer    IN VARCHAR2);

PUT函数将buffer中的数写入到file指定的文件中,但是PUT函数中使用的file必须是以写模式打开的。PUT函数不会为数据添加换行符,如果要添加换行符可以使用NEW_LINE或者PUT_LINE函数。

参数 描述
file 文件句柄
buffer 需要写入到文件的数据存放的位置。

示例

DECLARE
    HANDLE_W UTL_FILE.FILE_TYPE;
    BUFFER_W VARCHAR2(200);
    writenNum INT;
BEGIN
    writenNum := 0;
    BUFFER_W := LPAD('*', 20, '*');
    IF UTL_FILE.IS_OPEN(HANDLE_W) THEN
        DBMS_OUTPUT.PUT_LINE('HANDLE_W FILE HAS OPENED');
    ELSE
        HANDLE_W := UTL_FILE.FOPEN('/test','t2.txt','w',130);
        DBMS_OUTPUT.PUT_LINE('HANDLE_W FILE FIRST OPEN');
    END IF;
    FOR i IN 1 .. 2 LOOP     
      UTL_FILE.PUT(HANDLE_W,BUFFER_W);
      IF i = 2 THEN
        UTL_FILE.NEW_LINE(HANDLE_W);
        UTL_FILE.FFLUSH(HANDLE_W);
      END IF;
    END LOOP;
     
    UTL_FILE.FFLUSH(HANDLE_W);
     
END;
/

# PUT_LINE

UTL_FILE.PUT_LINE (
   file      IN FILE_TYPE,
   buffer    IN VARCHAR2,
   autoflush IN BOOLEAN DEFAULT FALSE);

PUT函数将buffer中的数写入到file指定的文件中。文件必须以写打开,PUT_LINE会在数据后面自动添加换行符。

参数 描述
file 文件句柄
buffer 需要写入到文件的缓冲buffer
autoflush bool值,用于表示在写之后是否立即刷到磁盘,默认是false

示例

DECLARE
    HANDLE_W UTL_FILE.FILE_TYPE;
    BUFFER_W VARCHAR2(200);
    writenNum INT;
BEGIN
    writenNum := 0;
    BUFFER_W := LPAD('*', 20, '*');
    IF UTL_FILE.IS_OPEN(HANDLE_W) THEN
        DBMS_OUTPUT.PUT_LINE('HANDLE_W FILE HAS OPENED');
    ELSE
        HANDLE_W := UTL_FILE.FOPEN('/test','t2.txt','w',130);
        DBMS_OUTPUT.PUT_LINE('HANDLE_W FILE HAS OPENED');
    END IF;
    FOR i IN 1 .. 2 LOOP     
      UTL_FILE.PUT_LINE(HANDLE_W,BUFFER_W,false);
    END LOOP;
    UTL_FILE.FFLUSH(HANDLE_W);
     
END;
/

# 错误码

参数 描述
INVALID_PATH 文件所在的路径不存在
INVALID_MODE 文件打开模式不对
INVALID_FILEHANDLE 文件句柄无效
INVALID_OPERATION 操作错误
READ_ERROR 在读操作的时候发生了错误
WRITE_ERROR 在写操作的时候发生了错误
INVALID_MAXLINESIZE 无效的max_linesize值,正常范围在1-32000
INVALID_FILENAME 无效的文件名
ACCESS_DENIED 文件拒绝被访问
INVALID_OFFSET 无效的偏移地址,当absolute_offset和relative_offset同时为NULL,或者absolute_offset<0,或者没有一个可以有效地指定需要跳转到文件的哪个位置
DELETE_FAILED 删除失败
RENAME_FAILED 重命名失败

错误码使用示例

DECLARE 
       HANDLE_R UTL_FILE.FILE_TYPE;
	    fexists   BOOLEAN;
    flen      NUMBER;
    blockSize INT;
    BUFFER_R VARCHAR(10);
    BEGIN
		UTL_FILE.FREMOVE('./a','t2.txtrttt');   
       DBMS_OUTPUT.PUT_LINE(SQLCODE||':'||SQLERRM);
	  EXCEPTION WHEN UTL_FILE.INVALID_PATH THEN
	   DBMS_OUTPUT.PUT_LINE('test invalid path success!');
	   DBMS_OUTPUT.PUT_LINE(SQLCODE||':'||SQLERRM);
	WHEN UTL_FILE.INVALID_FILENAME   THEN
	   DBMS_OUTPUT.PUT_LINE('test invalid fileName success!');
   END;
   /