Lendo campo BFILE
Sergio, tudo bem ?
Preciso ler um campo BFILE e reconstruir o arquivo com outro nome no diretório. Tentei várias abordagens e não tive sucesso.
Você poderia me orientar em como fazer isso ?
Abraço,
Anderson
Anderson, vou dar uma exemplo de como ler esse campo, e de quebra, você pode modificá-lo para inclusive alterar o arquivo se for necessário. Como não tenho nada do tipo pronto, vou montar um agora ! 🙂
Preparando o nosso ambiente de testes:
CREATE OR REPLACE DIRECTORY blobfile_dir AS 'C:\temp'
/
Directory BLOBFILE_DIR created.
CREATE TABLE bfile_test (BFILE BFILE)
/
Table bfile_test created.
CREATE TABLE blob_test
(
id NUMBER
,nfile BLOB
)
/
Table blob_test created.
INSERT INTO bfile_test VALUES ( BFILENAME('ORACLE_HOME','teste.txt'))
/
1 row inserted.
COMMIT
/
Commit complete.
SELECT * FROM bfile_test
/
BFILE
--------------------------------------
bfilename('blobfile_dir','teste.txt')
Criei o diretory com o path onde o arquivo teste1.txt está localizado. Inseri o arquivo na tabela bfile_test para simularmos a leitura do arquivo.
Agora vamos ao código:
DECLARE
v_blob_file BLOB default EMPTY_BLOB();
v_bfile BFILE;
v_directory VARCHAR2(100) := 'blobfile_dir' ;
dest_offset integer := 1;
src_offset integer := 1;
v_file_name VARCHAR2(100) := 'teste2.txt' ;
-- Remonta o arquivo
PROCEDURE rebuild_file
(
p_data IN BLOB
,p_dir IN VARCHAR2
,p_file IN VARCHAR2
)
IS
l_out_file UTL_FILE.file_type;
l_buffer RAW(32767);
l_amount BINARY_INTEGER := 32767;
l_pos INTEGER := 1;
l_blob_len INTEGER;
BEGIN
--
l_blob_len := DBMS_LOB.getlength(p_data);
--
l_out_file := UTL_FILE.fopen
(
p_dir
,p_file
,'w'
,32767
);
WHILE l_pos < l_blob_len
LOOP
DBMS_LOB.read
(
p_data
,l_amount
,l_pos
,l_buffer
);
UTL_FILE.put_raw
(
l_out_file
,l_buffer
,TRUE
);
UTL_FILE.fflush(l_out_file);
l_pos := l_pos + l_amount;
DBMS_OUTPUT.put_line(l_buffer);
END LOOP;
UTL_FILE.fclose(l_out_file);
EXCEPTION
WHEN others THEN
IF UTL_FILE.is_open(l_out_file)
THEN
UTL_FILE.fclose(l_out_file);
END IF;
END rebuild_file;
BEGIN
SELECT bfile
INTO v_bfile
FROM bfile_test;
DBMS_LOB.open (v_bfile, DBMS_LOB.file_readonly);
DBMS_LOB.createtemporary
(
v_blob_file
,TRUE
);
DBMS_LOB.loadblobfromfile
(
v_blob_file
,v_bfile
,DBMS_LOB.LOBMAXSIZE
,dest_offset
,src_offset
);
INSERT INTO blob_test VALUES(1,v_blob_file);
DBMS_LOB.close(v_bfile);
COMMIT;
SELECT nfile
INTO v_blob_file
FROM blob_test
WHERE id = 1;
rebuild_file
(
p_data => v_blob_file
,p_dir => v_directory
,p_file => v_file_name
);
END;
Esse bloco anônimo irá ler o arquivo do BFILE e criar um novo arquivo chamado teste2.txt. Esse código pode ser melhorado, e muito ! Porém, com certeza já atende a sua necessidade.
Referências
Espero ter ajudado !
Abraço