使用JAVA从Oracle数据库中读取网络文件

时间:2015-12-11 08:44:13

标签: java oracle plsql readfile

我正在尝试在Oracle数据库中创建一个函数,该函数使用JAVA类从网络驱动器读取文件并将文件内容作为BLOB返回。

直到现在,这是进展

JAVA代码 - FileAPI.java

import java.lang.*;
import java.io.*;
import java.sql.*;

public class FileAPI
{  
  public static String readFile (String path, Blob[] outLob)
  {
    FileInputStream fileStream = null;
    try {       
        fileStream = new FileInputStream(path);

        byte[] buffer = new byte[100];
        int i = 0;
        /* for testing just read 100 bytes */
        /* code required for reading full file */
        i = fileStream.read(buffer, 1, 100);        
        outLob[0] = new javax.sql.rowset.serial.SerialBlob(buffer); 

        if(fileStream != null)
                fileStream.close();         

        return "success";
        }
    catch (Exception e) {       
        return e.getMessage();
        }
  }
};

Oracle PL / SQL函数

CREATE OR REPLACE FUNCTION readFile (p_path IN VARCHAR2, p_outlob IN OUT NOCOPY BLOB)
RETURN VARCHAR2
AS LANGUAGE JAVA
NAME 'FileAPI.readFile(
        java.lang.String,
        java.sql.Blob[]) return java.lang.String';

PL / SQL匿名块来测试上面的函数

SET SERVEROUTPUT ON;
DECLARE
    l_temp BLOB;
    l_res VARCHAR2(1000);
BEGIN   
    l_res := readFile('/mnt/servername/foldername/filename.txt',l_temp);
    IF l_res = 'success'
    THEN
        DBMS_OUTPUT.PUT_LINE('Success, length '||dbms_lob.getlength(l_temp));
    ELSE
        DBMS_OUTPUT.PUT_LINE('Error info '|| l_res);
    END IF;
END;
/

当我在阻止上面运行时,我没有收到任何错误信息。它只是打印“错误信息”。没有详细的例外情况。

有些人可以说明这里出了什么问题。

您还可以建议阅读完整文件的内容并将其附加到JAVA中的BLOB变量(outLob [0])吗?

JAVA详细信息

java版“1.7.0_79” Java(TM)SE运行时环境(版本1.7.0_79-b15) Java HotSpot(TM)64位服务器VM(内置24.79-b02,混合模式)

Oracle DB - Oracle 11g r2 EE

最诚挚的问候,

[更新JAVA代码]

import java.lang.*;
import java.io.*;
import java.sql.*;

public class FileAPI
{  
  public static String readFile (String path, Blob[] outLob)
  {
    FileInputStream fileStream = null;
    Blob tmp = outLob[0];
    try {       
        fileStream = new FileInputStream(path);

        byte[] buffer = new byte[100];
        int i = 0;
        /* for testing just read 100 bytes */
        /* code required for reading full file */
        i = fileStream.read(buffer, 0, 100);        
        tmp = new javax.sql.rowset.serial.SerialBlob(buffer);
        outLob[0] = tmp;

        if(fileStream != null)
                fileStream.close();         

        return "success";
        }
    catch (Exception e) {       
        //return e.getMessage();
        return e.toString();
        }
  }
};

2 个答案:

答案 0 :(得分:1)

要直接从Java创建Blob,您必须访问Connection对象并告诉数据库通过它创建blob;然后获取blob对象的输出流并写入它。

import oracle.jdbc.OracleDriver;

import oracle.sql.BLOB;

import java.io.FileInputStream;
import java.io.OutputStream;

import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;

public class FileAPI
{
    public static String readFile(String path, Blob[] outLob)
    {
        try
        {
            DriverManager.registerDriver(new OracleDriver());
            Connection conn = DriverManager.getConnection("jdbc:default:connection:");
            FileInputStream fileStream = null;
            fileStream = new FileInputStream(path);

            outLob[0] = BLOB.createTemporary(conn, true, BLOB.DURATION_SESSION);
            OutputStream BlobOS = outLob[0].setBinaryStream(0);
            byte[] buffer = new byte[100];

            int len = fileStream.read(buffer, 0, 100);
            while (len > -1)
            {
                BlobOS.write(buffer, 0, len);
                len = fileStream.read(buffer, 0, 100);
            }
            BlobOS.close();
            fileStream.close();

            return "success";
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return e.toString();
        }
    }
}

您需要包含Oracle JDBC才能进行编译。 BLOB.createTemporary()甚至适用于Java 1.4.2(oracle 10);从1.6开始,在sql.Connection中有createBlob函数,它也应该这样做。

此外,这与您的问题有点无关,但请注意您可以在数据库服务器上的udump日志中读取Java存储过程的标准输出(System.out和System.err),因此不要犹豫使用e.printStackTrace() - 这有助于极大地调试。

答案 1 :(得分:0)

JAVA代码

import java.lang.*;
import java.io.*;
import java.sql.Blob;

public class FileAPI {
    public static String readFile(String path, Blob[] outLob) {
        FileInputStream fileStream = null;
        Blob tmp = outLob[0];
        OutputStream ous = null;
        try {
            ous = tmp.setBinaryStream(1);
            fileStream = new FileInputStream(path);
            //System.out.println("fileStream:" + fileStream);           
            byte[] buffer = new byte[4096];
            int read = 0;
            while ((read = fileStream.read(buffer)) != -1) {
                ous.write(buffer, 0, read);
            }
            outLob[0] = tmp;            
        } catch (Exception e) {
            return e.toString();
            //System.out.println(e.toString());
        } finally {
            try {
                if (fileStream != null) fileStream.close();
                if (ous != null) ous.close();
            } catch (IOException e) {}
        }
        return "success";
    }
}

Oracle功能

CREATE OR REPLACE FUNCTION readFile (p_path IN VARCHAR2
    , p_outlob IN OUT NOCOPY BLOB
    )
RETURN VARCHAR2
AS LANGUAGE JAVA
NAME 'FileAPI.readFile(
        java.lang.String,
        java.sql.Blob[]) return java.lang.String';

用于测试的匿名阻止

SET SERVEROUTPUT ON;
DECLARE
    l_temp BLOB;
    l_res VARCHAR2(1000);
BEGIN
    -- important, this is required so that LOB pointer is passed to JAVA
    DBMS_LOB.CREATETEMPORARY(l_temp,TRUE);
    l_res := readFile('/mnt/servername/foldername/filename.txt',l_temp);
    IF l_temp IS NOT NULL
    THEN
        DBMS_OUTPUT.PUT_LINE('Success, length '||dbms_lob.getlength(l_temp));
    ELSE
        DBMS_OUTPUT.PUT_LINE('Error info '|| l_res);
    END IF;
    DBMS_LOB.FREETEMPORARY(l_temp);
END;
/

注意:应使用dbms_java.grant_permission API向Oracle用户提供所需的访问权限。服务器用户(运行Oracle的用户)应具有对网络共享的读访问权。