我有以下脚本来创建3个文件:
set serveroutput on
declare
nombreArchivo varchar2(30);
f_out UTL_FILE.FILE_TYPE;
begin
nombreArchivo :='fich_fseek.txt';
dbms_output.put_line('Abrir el fichero '||nombrearchivo||' en modo escritura.');
f_out:=UTL_FILE.FOPEN('TEMPORAL',nombreArchivo,'w');
UTL_FILE.PUT_LINE(f_out,'Hola, me llamo Álvaro.');
UTL_FILE.PUT_LINE(f_out,'Esto es una prueba para ver cómo funcionan las funciones FSEEK y FGETPOS.');
UTL_FILE.PUT_LINE(f_out,'Espero que te diviertas.');
UTL_FILE.NEW_LINE(f_out,1);
UTL_FILE.PUT_LINE(f_out,'Atentamente,');
UTL_FILE.PUT_LINE(f_out,'el que esto escribe');
UTL_FILE.FCLOSE(f_out);
nombreArchivo :='caracter.txt';
dbms_output.put_line('Abrir el fichero '||nombrearchivo||' en modo escritura.');
f_out:=UTL_FILE.FOPEN('TEMPORAL',nombreArchivo,'w');
UTL_FILE.PUT(f_out,'a');
UTL_FILE.FCLOSE(f_out);
nombreArchivo :='vacio.txt';
dbms_output.put_line('Abrir el fichero '||nombrearchivo||' en modo escritura.');
f_out:=UTL_FILE.FOPEN('TEMPORAL',nombreArchivo,'w');
UTL_FILE.FCLOSE(f_out);
exception
when others then -- así me aseguro que cualquier flujo abierto será cerrado
dbms_output.put_line('Se ha producido un error: '||SQLERRM);
UTL_FILE.FCLOSE_ALL;
end;
/
当我创建另一个脚本来读取文件而不使用异常子句时出现了问题:
set serveroutput on
declare
nombreArchivo varchar2(30):='fich_fseek.txt';
--nombreArchivo varchar2(30):='caracter.txt';
--nombreArchivo varchar2(30):='vacio.txt';
f_out UTL_FILE.FILE_TYPE;
texto varchar2(100);
posición pls_integer := 0;
existe boolean;
tamaño_archivo number;
tamaño_bloque number;
begin
UTL_FILE.FGETATTR('TEMPORAL', nombreArchivo, existe, tamaño_archivo, tamaño_bloque);
if existe then
if tamaño_archivo > 0 then
dbms_output.put_line('Abrir el fichero '||nombrearchivo||' en modo lectura, que tiene un tamaño de '||tamaño_archivo||' bytes.');
f_out:=UTL_FILE.FOPEN('TEMPORAL',nombreArchivo,'r');
posición := UTL_FILE.FGETPOS(f_out);
while posición < tamaño_archivo loop
UTL_FILE.GET_LINE(f_out, texto);
dbms_output.put_line('pre Posición '||posición);
dbms_output.put_line(texto);
posición := UTL_FILE.FGETPOS(f_out);
dbms_output.put_line('post Posición '||posición);
end loop;
UTL_FILE.FCLOSE(f_out);
else
dbms_output.put_line('El fichero '||nombrearchivo||' está vacío (0 bytes).');
end if;
else
dbms_output.put_line('El archivo '||nombrearchivo||' no existe');
end if;
end;
/
然后ORA-01403“找不到数据”,但只能使用'fich_fseek.txt'文件。
答案 0 :(得分:0)
感谢Alex Poole的评论。实际上,如果在Windows中以错误的方式计算新行字符,那么在readed_bytes小于file_size之前,我将使用correction_size:循环直到readed_bytes小于correction_size,而不是读取。校正非常简单,在起始点corre_size等于file_size,但每次读取新行时,correct_size将减少一个单位(字节):
set serveroutput on
declare
nombreArchivo varchar2(30):='fich_fseek.txt';
--nombreArchivo varchar2(30):='caracter.txt';
--nombreArchivo varchar2(30):='vacio.txt';
f_out UTL_FILE.FILE_TYPE;
texto varchar2(100);
posición pls_integer := 0;
existe boolean;
tamaño_archivo number;
tamaño_bloque number;
tamaño_corregido number;
begin
UTL_FILE.FGETATTR('TEMPORAL', nombreArchivo, existe, tamaño_archivo, tamaño_bloque);
if existe then
if tamaño_archivo > 0 then
dbms_output.put_line('Abrir el fichero '||nombrearchivo||' en modo lectura, que tiene un tamaño de '||tamaño_archivo||' bytes.');
f_out:=UTL_FILE.FOPEN('TEMPORAL',nombreArchivo,'r');
posición := UTL_FILE.FGETPOS(f_out);
tamaño_corregido := tamaño_archivo;
while posición < tamaño_corregido loop -- hay que poner el -6 para evitar un error no_data_found
UTL_FILE.GET_LINE(f_out, texto);
--dbms_output.put_line('pre Posición '||posición);
dbms_output.put_line(texto);
posición := UTL_FILE.FGETPOS(f_out);
--dbms_output.put_line('post Posición '||posición);
tamaño_corregido := tamaño_corregido-1;
end loop;
UTL_FILE.FCLOSE(f_out);
else
dbms_output.put_line('El fichero '||nombrearchivo||' está vacío (0 bytes).');
end if;
else
dbms_output.put_line('El archivo '||nombrearchivo||' no existe');
end if;
end;
/
使用逐字节读取的替代版本:
set serveroutput on
declare
nombreArchivo varchar2(30):='fich_fseek.txt';
--nombreArchivo varchar2(30):='caracter.txt';
--nombreArchivo varchar2(30):='vacio.txt';
f_out UTL_FILE.FILE_TYPE;
texto varchar2(100) := '';
posición pls_integer := 0;
existe boolean;
tamaño_archivo number;
tamaño_bloque number;
flag_acento boolean := false;
tamaño_corregido number;
begin
UTL_FILE.FGETATTR('TEMPORAL', nombreArchivo, existe, tamaño_archivo, tamaño_bloque);
if existe then
if tamaño_archivo > 0 then
dbms_output.put_line('Abrir el fichero '||nombrearchivo||' en modo lectura, que tiene un tamaño de '||tamaño_archivo||' bytes.');
f_out:=UTL_FILE.FOPEN('TEMPORAL',nombreArchivo,'r');
posición := UTL_FILE.FGETPOS(f_out);
tamaño_corregido := tamaño_archivo;
while posición < tamaño_corregido loop
UTL_FILE.GET_RAW(f_out, texto, 1);
if texto = 'C3' then
--dbms_output.put_line('Encontrado');
flag_acento := true; --TODO
goto CONTINUE;
end if;
if flag_acento then
dbms_output.put_line('Posición '||rpad(posición,3)||' '||texto||': '||utl_raw.cast_to_varchar2('C3'||texto));
flag_acento := false;
else
dbms_output.put_line('Posición '||rpad(posición,3)||' '||texto||': '||CHR(TO_NUMBER(texto,'xx')));
end if;
if texto = '0A' then -- caracter de sálto de línea
--exit;
tamaño_corregido := tamaño_corregido-1;
end if;
<<CONTINUE>> posición := UTL_FILE.FGETPOS(f_out);
end loop;
--dbms_output.put_line('ASDF '||CHR(TO_NUMBER('C3','xx'))||CHR(TO_NUMBER('81','xx')));
/*unión := utl_raw.cast_to_varchar2('C381');
dbms_output.put_line('ASDF '||unión );*/
UTL_FILE.FCLOSE(f_out);
else
dbms_output.put_line('El fichero '||nombrearchivo||' está vacío (0 bytes).');
end if;
else
dbms_output.put_line('El archivo '||nombrearchivo||' no existe');
end if;
end;
/