#UTL_FILE
UTL_FILE包为用户提供了读写系统文件的能力,用户可以通过UTL_FILE操作系统文件。
用户需拥有FILE权限,且操作的目标文件需在SECURE_FILE_PRIV参数指定的安全目录下,可通过SHOW PARAMETER SECURE_FILE_PRIV查看安全目录。
# 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指定。文件打开的默认权限为-rw-r-----,文件所有者可读写,用户组可读。
参数 | 描述 |
---|---|
location | 文件所在的路径,仅支持起始为“.”或“/”的路径。 若被赋值起始为“.”的路径,表示相对于环境变量YASDB_DATA的路径。 |
filename | 操作的文件名字。 |
open_mode | 打开的方式,支持如下方式: * a:表示以追加方式打开文件,默认在文件末尾追加,若不存在指定文件会以写方式创建新文件。 * w:表示以写方式打开文件,此时会创建一个新的文件并覆盖旧文件。 * r:表示以只读方式打开文件。 * ab:表示以二进制、追加方式打开文件。 * wb:表示以二进制、写方式打开文件。 * rb:表示以二进制、读方式打开文件。 |
max_linesize | 对文件读写的一行的最大长度。 |
返回的FILE_TYPE是UTL_FILE包定义的私有RECORD类型(其内容不应被引用或修改)。若HANDLE的成员BYTE_MODE被修改或未被赋值,调用子函数可能会失败。
TYPE file_type IS RECORD (
id BINARY_INTEGER,
datatype BINARY_INTEGER,
byte_mode BOOLEAN);
参数 | 描述 |
---|---|
id | 内部文件句柄编号的数值。 |
datatype | 该参数用于语法兼容,无实际含义,其值恒为1。 |
byte_mode | 文件打开的编码方式,作为二进制文件或作为文本文件。 |
示例
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('/data','yashan.txt','r',100);
HANDLE_A := UTL_FILE.FOPEN('/data','yashan.txt','a');
HANDLE_W := UTL_FILE.FOPEN('/data','yashan.txt','w',32000);
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 | 源文件所在的路径,仅支持起始为“.”或“/”的路径。 若被赋值起始为“.”的路径,表示相对于环境变量YASDB_DATA的路径。 |
src_filename | 源文件名字。 |
dest_location | 目标文件所在的路径,仅支持起始为“.”或“/”的路径。 若被赋值起始为“.”的路径,表示相对于环境变量YASDB_DATA的路径。 |
dest_filename | 目标文件名字。 |
start_line | 从源文件的第几行开始复制,默认为1。 |
end_line | 复制到源文件的第几行,默认为NULL,表示源文件的最后一行。 |
示例
BEGIN
UTL_FILE.FCOPY('/data','yashan.txt','/data','yashan1.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('/data','yashan.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;
/
# FGETATTR
UTL_FILE.FGETATTR(
location IN VARCHAR2,
filename IN VARCHAR2,
fexists OUT BOOLEAN,
file_length OUT NUMBER,
block_size OUT BINARY_INTEGER);
FGETATTR函数返回磁盘文件的属性。
参数 | 描述 |
---|---|
location | 源文件所在的位置,仅支持起始为“.”或“/”的路径。 若被赋值起始为“.”的路径,表示相对于环境变量YASDB_DATA的路径。 |
filename | 文件的名字。 |
fexists | 一个表示文件是否存在的BOOL值。 |
file_length | 文件的字节总长度,如果文件不存在,返回NULL。 |
block_size | 该参数用于语法兼容,无实际含义。 |
示例
DECLARE
HANDLE_R UTL_FILE.FILE_TYPE;
BUFFER_W VARCHAR2(1000);
fexists BOOLEAN;
flen NUMBER;
blockSize INT;
BEGIN
UTL_FILE.FGETATTR('/data','yashan.txt',fexists,flen,blockSize);
DBMS_OUTPUT.PUT_LINE('yashan.txt:');
IF fexists THEN
DBMS_OUTPUT.PUT_LINE(flen);
DBMS_OUTPUT.PUT_LINE(blockSize);
END IF;
END;
/
--result
yashan.txt:
302
0
# 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 | 源文件所在的路径,仅支持起始为“.”或“/”的路径。 若被赋值起始为“.”的路径,表示相对于环境变量YASDB_DATA的路径。 |
src_filename | 源文件的名字。 |
dest_location | 目标文件所在的路径,仅支持起始为“.”或“/”的路径。 若被赋值起始为“.”的路径,表示相对于环境变量YASDB_DATA的路径。 |
dest_filename | 重命名的文件的名字。 |
overwrite | 如果目标文件已经存在,是否要覆盖。 |
示例
BEGIN
UTL_FILE.FRENAME('/data','yashan1.txt','/data','yashan2.txt');
END;
/
# FREMOVE
UTL_FILE.FREMOVE (
location IN VARCHAR2,
filename IN VARCHAR2);
FREMOVE函数用于删除磁盘的文件,如果有足够的权限的话可以成功删除。
参数 | 描述 |
---|---|
location | 文件所在的路径,仅支持起始为“.”或“/”的路径。 若被赋值起始为“.”的路径,表示相对于环境变量YASDB_DATA的路径。 |
filename | 文件的名字。 |
示例
BEGIN
UTL_FILE.FREMOVE('/data','yashan2.txt');
END;
/
# FSEEK
UTL_FILE.FSEEK (
file IN OUT UTL_FILE.FILE_TYPE,
absolute_offset IN PLS_INTEGER,
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('/data','yashan.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;
/
--result
HANDLE_R FILE FIRST OPEN
********************************************************************************************************************************************
# 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,数据库会将该值设置为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('/data','yashan.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;
/
--result
HANDLE_R FILE FIRST OPEN
********************************************************************************************************************************************
# IS_OPEN
UTL_FILE.IS_OPEN(
FILE IN FILE_TYPE)
RETURN BOOLEAN;
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('/data','yashan.txt','r',200);
DBMS_OUTPUT.PUT_LINE('HANDLE_R FILE FIRST OPEN');
END IF;
END;
/
--result
HANDLE_R FILE FIRST OPEN
# NEW_LINE
UTL_FILE.NEW_LINE (
file IN FILE_TYPE,
lines IN BINARY_INTEGER DEFAULT 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('/data','yashan.txt','r',200);
HANDLE_W := UTL_FILE.FOPEN('/data','yashan1.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;
/
--result
**************************************************************************************************************
****************************************
# 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('/data','yashan1.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;
/
--result
HANDLE_W FILE FIRST OPEN
# PUT_LINE
UTL_FILE.PUT_LINE (
file IN FILE_TYPE,
buffer IN VARCHAR2,
autoflush IN BOOLEAN DEFAULT FALSE);
PUT_LINE函数将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('/data','yashan1.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;
/
--result
HANDLE_W FILE HAS OPENED
# FGETPOS
UTL_FILE.FGETPOS (
file IN FILE_TYPE)
RETURN PLS_INTEGER;
FGETPOS函数返回文件中当前打开文件的相对偏移位置(以字节为单位)。操作以二进制模式打开的文件时会报错。
参数 | 描述 |
---|---|
file | 文件句柄。 |
示例
DECLARE
HANDLE_R UTL_FILE.FILE_TYPE;
BUFFER_R VARCHAR2(500);
POS INTEGER;
BEGIN
IF UTL_FILE.IS_OPEN(HANDLE_R) THEN
DBMS_OUTPUT.PUT_LINE('HANDLE_R FILE HAS OPENED');
ELSE
HANDLE_R := UTL_FILE.FOPEN('/data','yashan1.txt','r',500);
DBMS_OUTPUT.PUT_LINE('HANDLE_R FILE FIRST OPEN');
END IF;
UTL_FILE.GET_LINE (HANDLE_R, BUFFER_R);
POS := UTL_FILE.FGETPOS(HANDLE_R);
DBMS_OUTPUT.PUT_LINE('BEFORE_SEEK_POS:'||POS);
UTL_FILE.FSEEK(HANDLE_R, NULL, -10);
POS := UTL_FILE.FGETPOS(HANDLE_R);
DBMS_OUTPUT.PUT_LINE('AFTER_SEEK_POS:'||POS);
UTL_FILE.FCLOSE (HANDLE_R);
END;
/
--result
HANDLE_R FILE FIRST OPEN
BEFORE_SEEK_POS:21
AFTER_SEEK_POS:11
# 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('/data','yashan1.txt','r',200);
UTL_FILE.FCLOSE(HANDLE_R);
END;
/
# FCLOSE_ALL
UTL_FILE.FCLOSE_ALL (
);
FCLOSE_ALL函数用于关闭当前session下所有打开的file handle,多数用于紧急情况下的文件句柄清理。
示例
DECLARE
BEGIN
UTL_FILE.FCLOSE_ALL();
END;
/
# PUT_RAW
UTL_FILE.PUT_RAW (
file IN FILE_TYPE,
buffer IN RAW,
autoflush IN BOOLEAN DEFAULT FALSE);
PUT_RAW函数将buffer中的RAW数据写入到file指定的文件中。文件必须以写打开,支持二进制打开模式。当以二进制打开时,不会追加换行符。
参数 | 描述 |
---|---|
file | 文件句柄。 |
buffer | 需要写入到文件的RAW数据buffer。 |
autoflush | bool值,用于表示在写之后是否立即刷到磁盘,默认是false。 |
示例
DECLARE
HANDLE_W UTL_FILE.FILE_TYPE;
BUFFER_RAW RAW(200);
BEGIN
HANDLE_W := UTL_FILE.FOPEN('/data','file1.txt','WB',200);
UTL_FILE.PUT_RAW(HANDLE_W, '313233203535354348454E0AE99988');
DBMS_OUTPUT.PUT_LINE('put_raw 313233203535354348454E0AE99988 to file1.txt done');
UTL_FILE.FCLOSE(HANDLE_W);
END;
/
-- result
put_raw 313233203535354348454E0AE99988 to file1.txt done
# GET_RAW
UTL_FILE.GET_RAW (
file IN UTL_FILE.FILE_TYPE,
buffer OUT NOCOPY RAW,
len IN PLS_INTEGER DEFAULT NULL);
GET_RAW函数用于从文件中读取RAW数据,读取长度不受FOPEN函数中设置的max_linesize影响。文件必须以只读打开,支持二进制打开模式。
参数 | 描述 |
---|---|
file | 文件句柄。 |
buffer | 出参,从文件中读取RAW数据的存放缓冲区。 |
len | 指定读取的长度,单位为字节,最大值为8000;默认为NULL,表示读取到文件末尾或RAW数据的最大长度(8000字节)。 |
示例
DECLARE
HANDLE_W UTL_FILE.FILE_TYPE;
HANDLE_R UTL_FILE.FILE_TYPE;
BUFFER_R VARCHAR2(200);
BUFFER_RAW RAW(200);
BEGIN
HANDLE_W := UTL_FILE.FOPEN('/data','file1.txt','WB',200);
UTL_FILE.PUT_RAW(HANDLE_W, '313233203535354348454E0AE99988');
DBMS_OUTPUT.PUT_LINE('put_raw 313233203535354348454E0AE99988 to file1.txt done');
UTL_FILE.FCLOSE(HANDLE_W);
HANDLE_R := UTL_FILE.FOPEN('/data','file1.txt','R',200);
DBMS_OUTPUT.PUT_LINE('get_raw from file1');
UTL_FILE.GET_RAW(HANDLE_R, BUFFER_RAW);
DBMS_OUTPUT.PUT_LINE(BUFFER_RAW);
UTL_FILE.FCLOSE(HANDLE_R);
END;
/
-- result
put_raw 313233203535354348454E0AE99988 to file1.txt done
get_raw from file1
313233203535354348454E0AE999880A
# 异常说明
参数 | 描述 |
---|---|
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;
/
--result
test invalid path success!
330:YAS-00330 invalid path