UTL_FILE 包

UTL_FILE 包为 PL/SQL 程序提供读和写操作系统数据文件的功能。它提供一套严格的使用标准操作系统文件 I/O 方式:open、put、 get 和 close 操作。

当用户想读取或写一个数据文件的时候,可以使用 FOPEN 来返回的文件句柄。这个文件句柄将用于随后在文件上的所有操作。例如,过程 PUT_LINE 写 text 字符串和行终止符到一个已打开的文件句柄,以及使用 GET_LINE 来读取指定文件句柄的一行到提供的缓存。

26.1 数据类型

UTL_FILE 定义了一种 FILE_TYPE 记录类型。FILE_TYPE 类型是 UTL_FILE 专有类型。用户不能引用和改变该记录的内容。FILE_TYPE 记录类型定义如下:

语法如下:

TYPE file_type IS RECORD (

	id INTEGER,

	datatype INTEGER,

	byte_mode BOOLEAN

);

参数详解

  • id 需要处理的外部文件句柄。
  • datatype 文件的类型:1 表示 CHAR 、2 表示 NCHAR、3 表示 binary。
  • byte_mode 文件打开后的类型:TRUE 表示二进制模式;FALSE 表示文本模式。

26.2 相关方法

UTL_FILE 包中的 18 个过程和函数详细介绍如下:

注意

对于打开模式为"w"、"a"、"wb"、"ab"、"r+"、"w+"、"a+"、"rb+"、"wb+"、"ab+"的FOPEN、FREMOVE及FRENAME操作,有如下限制:
1. 如果是非WINDOWS环境,且运行达梦服务器的进程有效用户为root,则禁止文件操作;
2. 执行操作的数据库用户必须有DBA权限;
3. 只能创建、修改在达梦系统目录(含子目录)下的文件。用户可以通过select * from from v$dm_ini where para_name like '%SYSTEM_PATH%';查看系统目录。

以下详细介绍各过程和函数:

  1. FCLOSE

关闭一个已打开文件。

语法如下:

PROCEDURE FCLOSE(

	FILE IN OUT FILE_TYPE

);

参数详解

  • File 通过 FOPEN 或 FOPEN_NCHAR 调用,返回的活动文件句柄。
  1. FCLOSE_ALL

关闭在这个会话里打开的所有文件。用作紧急情况下清理程序,比如,当 PL/SQL 存在异常时。FCLOSE_ALL 不会改变用户打开的文件句柄的状态。即,在调用 FCLOSE_ALL 后用 IS_OPEN 去测试一个文件句柄,返回值仍为 TRUE,即使该文件已经关闭了。在 FCLOSE_ALL 之前打开的所有文件都无法进一步读或写。

语法如下:

PROCEDURE FCLOSE_ALL;
  1. FCOPY

把一个文本文件中指定的连续的行数据拷贝到另外一个文件中。源文件需要以可读模式打开。

语法如下:

PROCEDURE FCOPY(

	SRC_LOCATION IN VARCHAR(128),

	SRC_FILENAME IN VARCHAR(128),

	DEST_LOCATION IN VARCHAR(128),

	DEST_FILENAME IN VARCHAR(128),

	START_LINE IN INTEGER DEFAULT 1,

	END_LINE IN INTEGER DEFAULT NULL

);

参数详解

  • src_location 源文件目录。
  • src_filename 被拷贝的源文件名称。
  • dest_location 新创建的目标文件的目录。
  • dest_filename 源文件的新名称。
  • start_line 拷贝的起始行,默认为文件的第 1 行。
  • end_line 拷贝的终止行,默认为 NULL,即为文件的最后一行。
  1. FFLUSH

以物理写入的方式将待定的数据写入到文件句柄所指定的文件中。通常地,待写入文件的数据是存放在缓冲区中的。FFLUSH 程序强制将缓冲区中的数据写入到文件中。数据必须以换行符结束。

语法如下:

PROCEDURE FFLUSH(

	FILE IN FILE_TYPE

) ;

参数详解

  • file 由 FOPEN 或 FOPEN_NCHAR 调用,返回的文件句柄。
  1. FGETATTR

读取并返回磁盘文件的属性。

语法如下:

PROCEDURE FGETATTR(

	LOCATION 	IN VARCHAR(128),

	FILENAME 	IN VARCHAR(128),

	FEXISTS 	OUT BOOLEAN,

	FILE_LENGTH OUT NUMBER,

	BLOCKSIZE 	OUT NUMBER

);

参数详解

  • location 源文件路径。
  • filename 被检查的文件。
  • fexists 文件是否存在,存在为 TRUE,不存在为 FALSE。
  • file_length 文件的长度(字节),若文件不存在,则长度为 NULL。
  • blocksize 文件系统中数据块的大小(字节),若文件不存在,则长度为 NULL。
  1. FGETPOS

指定文件中当前相对位置偏移量(字节)。

语法如下:

FUNCTION FGETPOS(

	FILE IN FILE_TYPE

)RETURN INTEGER;

参数详解

  • file 通过 FOPEN 或 FOPEN_NCHAR 调用,返回的活动文件句柄。

返回值

返回值 FGETPOS 以字节的方式返回一个打开文件相对位置偏移量。如果文件未打开则发生异常。如果当前位置在文件的最开始,则返回 0。

注意事项:

如果文件以 byte 的模式打开,那么会发生 INVALID OPERATION。

  1. FOPEN

打开指定文件并返回一个文件句柄。用户指定文件每行最大的字符数,并且同时可以打开文件最多 50 个。

语法如下:

FUNCTION FOPEN(

	LOCATION IN VARCHAR(128),

	FILENAME IN VARCHAR(128),

	OPEN_MODE IN VARCHAR(128),

	MAX_LINESIZE IN INTEGER DEFAULT 1024

)RETURN FILE_TYPE;

参数详解

  • location 源文件路径。
  • filename

文件名称,包括文件类型,但不包含文件路径。如果文件名称中包含路径,则 FOPEN 忽略此处的路径。在 UNIX 系统中,文件名不能包含转义符:“/”。

  • open_mode

文件打开模式。包括:r 只读模式;w 写模式;a 附加模式;rb 只读打开一个二进制文件,只允许读;wb 只写打开或建立一个二进制文件,只允许写数据;ab 追加打开一个二进制文件,并在文件末尾写数据。当以“a”或“ab”的方式打开文件时,若该文件不存在,则以“w”的方式创建该文件。

  • File 通过 FOPEN 或 FOPEN_NCHAR 调用,返回的活动文件句柄。
  • max_linesize 文件每行最大的字符数,包括换行符。最小为 1,最大为 32767。

注意事项:

文件的路径和文件名必须加上引号,以便于和相近的路径名区分开来。

异常:

INVALID_PATH:文件路径无效;

INVALID_MODE:参数 OPEN_MODE 字符串无效;

INVALID_OPERATION:文件无法按照请求打开;

INVALID_MAXLINESIZE:指定的最大行字符数值太大或太小。

  1. FREMOVE

在有足够权限的情况下,从系统中删除一个文件。

语法如下:

PROCEDURE FREMOVE(

	LOCATION IN VARCHAR(128),

	FILENAME IN VARCHAR(128)

);

参数详解

  • location 文件路径。
  • filename 被删除文件名称。

注意事项:

FREMOVE 存储过程不会在删除文件之前验证权限,但是操作系统会验证文件和路径的正确性。没有权限,或者文件和路径不正确,则返回删除失败信息。

  1. FRENAME

修改一个文件的名称。

语法如下:

PROCEDURE FRENAME(

	SRC_LOCATION IN VARCHAR(128),

	SRC_FILENAME IN VARCHAR(128),

	DEST_LOCATION IN VARCHAR(128),

	DEST_FILENAME IN VARCHAR(128),

	OVERWRITE IN BOOLEAN DEFAULT FALSE

);

参数详解

  • src_location 要改名文件的存放目录。
  • src_filename 要改名的源文件名称。
  • dest_location 改名后文件存放的路径。
  • dest_filename 修改后的新名称。
  • overwrite

设置是否能够重写。如果设置为“true”,则在 src_location 目录中覆盖任何名为 dest_filename 的文件。若设置为“false”,就会产生异常。缺省为 FLASE。

  1. FSEEK

根据指定的字节数,调整文件指针前进或后退。

语法如下:

PROCEDURE FSEEK(

	FILE IN FILE_TYPE,

	ABSOLUTE_OFFSET IN INTEGER DEFAULT NULL,

	RELATIVE_OFFSET IN INTEGER DEFAULT NULL

);

参数详解

  • file 通过 FOPEN 或 FOPEN_NCHAR 调用,返回的活动文件句柄。
  • absolute_offset 要寻找的字节的绝对路径,默认为 NULL。
  • relative_offset 指针前进或后退的字节数。用正整数表示向前查找,负整数表示向后查找。

注意事项:

使用 FSEEK,可以读取先前的行而不用关闭文件再重新找开。但是你必须知道要跳过的字符数。

该存储过程根据 relative_offset 参数指定的字节数进行查找。

如果在指定字节数之前就已经到达了文件的开头,那么文件指针指定在文件开头。如果在指定字节数之前就已经到达了文件的尾部,那么 INVALID_OFFSET 错误就会发生。

如果文件是以 byte 的模式打开的,那么 INVALID OPERATION 异常就会发生。

  1. GET_LINE

读取指定文件的一行到提供的缓存。读取的文本不包括该行的终结符,或者直到文件的末尾,或者到指定的长度。并且不能超过 FOPEN 时指定的 max_linesize。

语法如下:

PROCEDURE GET_LINE(

	FILE IN FILE_TYPE,

	BUFFER OUT VARCHAR,

	LEN IN INTEGER DEFAULT NULL

);

参数详解

  • file 通过 FOPEN 调用,返回的活动文件句柄。
  • buffer 接收数据文件中行读的数据缓冲区。
  • len 从文件中读取的字节数。默认情况为 NULL,NULL 表示读取的字节数 max_linesize。

注意事项:

如果该行不匹配缓冲区,则发生 READ_ERROR 异常。如果到文件结束了仍没有文本读取,发生 NO_DATA_FOUND 异常。如果 file 是以 byte 模式打开的,则产生 INVALID_OPERATION 异常。

由于行的结束符不被读取,读取空行则返回空字符串。

缓冲区最大大小为 32767 字节,除非 FOPEN 指定了更小的值。如果未指定,默认值为 1024。

  1. GET_RAW

从文件中读取原始字符串值,并通过读取的字节数调整文件指针的头部。GET_RAW 函数忽略掉行结束符,并返回通过 GET_RAW 的 len 参数请求的实际字节数。

语法如下:

FUNCTION GET_RAW(

	FILE IN FILE_TYPE,

	BUFFER OUT BLOB,

	LEN IN INTEGER DEFAULT NULL

)RETURN INTEGER;

参数详解

  • File 通过 FOPEN 或 FOPEN_NCHAR 调用,返回的活动文件句柄。
  • Buffer 接收从文件中读取的数据行的缓冲区。
  • len 从文件中读取的字节数。默认情况为 NULL,NULL 表示读取的字节数为 max_linesize。

注意事项:

如果子程序读取超过文件末尾,那么将产生 DATA_NO_FOUND 的异常。程序在执行循环时应该允许捕获这个异常。

  1. IS_OPEN

判断文件句柄指定的文件是否已打开,如果已打开则返回 TRUE,否则 FALSE。不保证用户在尝试使用该文件句柄时没有操作系统的权限。

语法如下:

FUNCTION IS_OPEN(

	FILE IN FILE_TYPE

)RETURN BOOLEAN;

参数详解

  • file 通过 FOPEN 或 FOPEN_NCHAR 调用,返回的活动文件句柄。
  1. NEW_LINE

在当前位置输出一个或多个行终止符。

语法如下:

PROCEDURE NEW_LINE(

	FILE IN FILE_TYPE,

LINES IN INTEGER DEFAULT 1

);

参数详解

  • file 通过 FOPEN 或 FOPEN_NCHAR 调用,返回的活动文件句柄。
  • lines 写入文件的行终结符数量。

异常:

INVALID_FILEHANDLE

INVALID_OPERATION

WRITE_ERROR

  1. PUT

把缓冲区中的文本字符写入到数据文件。文件必须是以写模式打开的。UTL_FILE.PUT 输出数据时不会附加行终止符。使用 NEW_LINE 来添加行结束符或者使用 PUT_LINE 来写一行带有结束符的数据。

语法如下:

PROCEDURE PUT(

	FILE IN FILE_TYPE,

	BUFFER IN VARCHAR

);

参数详解

  • file 由 FOPEN_NCHAR 返回的文件句柄。
  • buffer 包含要写入文件的数据缓存。

注意事项:

如果 FOPEN 没有指定一个更小的值,buffer 参数的最大值将是 32767。如果未指定,FOPEN 默认的行最大值为 1024。连续调用 PUT 的总和在没有缓冲区刷页的情况下不能超过 32767。

异常:

INVALID_FILEHANDLE

INVALID_OPERATION

WRITE_ERROR

  1. PUT_LINE

把缓冲区中的文本字符串写入数据文件,同时输出一个与系统有关的行终止符。

语法如下:

PROCEDURE PUT_LINE(

	FILE IN FILE_TYPE,

	BUFFER IN VARCHAR,

	AUTOFLUSH IN BOOLEAN DEFAULT FALSE

);

参数详解

  • file 由 FOPEN 返回的文件句柄。
  • buffer 包含要写入文件的数据缓存。
  • autoflush 数据写完后,自动清理缓冲区。

注意事项:

缓区大小最大为 32767。

如果文件有 byte 模式打开,则产生 INVALID_OPERATION 异常。

异常:

INVALID_FILEHANDLE

INVALID_OPERATION

WRITE_ERROR

  1. PUT_RAW

接收输入的原始数据并将其写入缓存。

语法如下:

PROCEDURE PUT_RAW(

	FILE IN FILE_TYPE,

	BUFFER IN BLOB,

	AUTOFLUSH IN BOOLEAN DEFAULT FALSE

);

参数详解

  • file 由 FOPEN 返回的文件句柄。
  • buffer 包含要写入文件的数据缓存;
  • autoflush 数据写完后,自动清理缓冲区。

注意事项:

通过设置第三个参数可以使缓冲区自动冲刷。

Buffer 最大值为 32767。

  1. PUTF

以一个模版样式输出至多 5 个字符串,类似 C 中的 printf()。

语法如下:

PROCEDURE PUTF(

	FILE IN FILE_TYPE,

	FORMAT IN VARCHAR,

	ARG1 IN VARCHAR DEFAULT NULL,

	ARG2 IN VARCHAR DEFAULT NULL,

	ARG3 IN VARCHAR DEFAULT NULL,

	ARG4 IN VARCHAR DEFAULT NULL,

	ARG5 IN VARCHAR DEFAULT NULL

);

参数详解

  • file 由 FOPEN 返回的文件句柄。
  • format 决定格式的格式串。格式串可使用以下样式:1)%s 在格式串中可以使用最多 5 个 %s,与后面的 5 个参数一一对应。%s 会被后面的参数依次填充,如果没有足够的参数,%s 会被忽视,不被写入文件;2)\n 换行符。在格式串中没有个数限制。
  • argN 可选的 5 个参数,最多 5 个。

注意事项:

如果文件以 byte 模式打开,返回 INVALID_OPERATION 错误。

%s,\n 与 c 语言中的类似。

26.3 错误处理

错误、异常情况释义:

1、EC_OPEN_FILE_FAILED:打开文件失败

2、EC_RN_INVALID_MODE_NAME:无效的文件模式名

3、EC_WRITE_FILE_FAILED:写入文件失败

4、EC_FILE_CLOSE_FAILED:文件关闭失败

5、EC_FILE_REMOVE_FAILED:文件删除失败

6、EC_FILE_NAME_TOO_LONG:文件名过长

7、EC_FILE_PATH_TOO_LONG:文件路径名过长

8、EC_CANNOT_FIND_DATA:无法获取数据

9、EC_INVALID_OPERATION:无效的操作

10、EC_INVALID_OFFSET:无效的偏移

11、EC_RN_INVALID_STRINGFORMAT:无效的字符串格式

12、EC_RN_TOO_MANY_FILES:打开文件数目过多

13、EC_FILE_EXIST:文件已存在

26.4 举例说明

使用包内的过程和函数之前,如果还未创建过系统包。请先调用系统过程创建系统包。

SP_CREATE_SYSTEM_PACKAGES (1,'utl_FILE');

在成功调用下面 3 个例子中的过程和函数之前,先要在达梦库文件所在的系统目录 d:\dmdbms\data\DAMENG 下创建文件 utl_file_temp\u12345.tmp。文件的内容为:

This is line 1.

This is line 2.

This is line 3.

This is line 4.

This is line 5.

**例 1 **使用 GET_LINE 过程读文件

DECLARE

	V1 VARCHAR2(8186);

	F1 UTL_FILE.FILE_TYPE;

BEGIN

-- 本例子中 MAX_LINESIZE小于 GET_LINE的长度要求,所以返回的字节数小于等于256。

 F1 :=UTL_FILE.FOPEN('d:\dmdbms\data\DAMENG\UTL_FILE_TEMP','u12345.tmp','R',256);

  UTL_FILE.GET_LINE(F1,V1,32767);

  print 'get_line:'||v1;

  UTL_FILE.FCLOSE(F1);

-- FOPEN的MAX_LINESIZE 是NULL ,NULL即为默认的1024,所以返回的字节数小于等于1024。

  F1 UTL_FILE.FOPEN('d:\dmdbms\data\DAMENG\UTL_FILE_TEMP','u12345.tmp','R');
   

  UTL_FILE.GET_LINE(F1,V1,32767);

  print 'get_line:'||v1;

  UTL_FILE.FCLOSE(F1);

 -- GET_LINE 未指定字节数, 所以默认为 NULL1024,NULL即为1024。

  F1 :=   UTL_FILE.FOPEN('d:\dmdbms\data\DAMENG\UTL_FILE_TEMP','u12345.tmp','R');

  UTL_FILE.GET_LINE(F1,V1);

  print 'get_line:'||v1;

  UTL_FILE.FCLOSE(F1);

END;

/

每个过程都是输出第一行,这个例子的结果如下所示:

Get line: This is line 1.

Get line: This is line 1.

Get line: This is line 1.

**例 2 **使用 PUTF 过程向文件尾部添加内容。

DECLARE

	HANDLE UTL_FILE.FILE_TYPE;

	MY_WORLD VARCHAR2(4) := 'ZORK';

BEGIN

	HANDLE :=UTL_FILE.FOPEN('d:\dmdbms\data\DAMENG\UTL_FILE_TEMP','u12345.tmp','A');

	UTL_FILE.PUTF(HANDLE,'\NHELLO, WORLD!\NI COME FROM %s WITH %s.\N',MY_WORLD,'GREETINGS FOR ALL EARTHLINGS');

	UTL_FILE.FFLUSH(HANDLE);

	UTL_FILE.FCLOSE(HANDLE);

END;

/

该例子在 u12345.tmp 文件的末尾添加了如下内容:

Hello, world!

I come from Zork with greetings for all earthlings.

**例 3 **使用 GET_RAW 过程从 utl_file_temp 路径下的 u12345.tmp 文件中读取原始信息。

首先,将 u12345.tmp 文件中的内容写为:hello world!

CREATE OR REPLACE PROCEDURE getraw(n IN VARCHAR2) IS

	h UTL_FILE.FILE_TYPE;

	Buf blob;

	Amnt CONSTANT BINARY_INTEGER := 32767;

BEGIN

	h := UTL_FILE.FOPEN('d:\dmdbms\data\DAMENG\UTL_FILE_TEMP', n, 'r', 			32767);

	UTL_FILE.GET_RAW(h, Buf, Amnt);

	print 'This is the raw data:';

	select Buf;

	UTL_FILE.FCLOSE (h);

END;

/

过程建好后,运行如下语句:

begin

	getraw('u12345.tmp');

end;

/

输出结果为:

This is the raw data:

行号 BUF
---------- -------------------------------------------------------------------
1
0x54484953204953204C494E4520312E0A54484953204953204C494E4520322E0A54484953204953204C494E4520332E0A54484953204953204C494E4520342E0A54484953204953204C494E4520352E5C4E48454C4C4F2C20574F524C44215C4E4920434F4D452046524F4D205A4F524B2057495448204752454554494E475320464F5220414C4C2045415254484C494E47532E5C4E
微信扫码
分享文档
扫一扫
联系客服