2013-10-29 49 views
0

我正在尝试使用在blob列后面的字段中找到的值从blob中提取文件。我的解决方案有效,但速度很慢。从Oracle blob字段提取文件;

我在大约1小时内提取了169MB(727个不同的文件)。这大概是每分钟12个文件。 大部分文件通常在5KB到50KB之间,但有时可能大到2MB。我正在使用本地Oracle数据库。

有什么我可以做的,使我的代码更有效率?如果不是,还有哪些其他因素可能会影响流程的速度?以下是该方法的代码:

public void beginExtraction(String FileOutDir, String blobSQL, 
     String fileSuffix, Connection conn) { 

    if ((FileOutDir != null) && (blobSQL != null) && (conn != null)) { 
     PreparedStatement selBlobs = null; 
     FileOutputStream fos = null; 

     if (conn != null) { 
      if (blobSQL != null) { 
       try { 

        selBlobs = conn.prepareStatement(blobSQL); 
        ResultSet rs = selBlobs.executeQuery(); 
        int cols = rs.getMetaData().getColumnCount(); 

        while (rs.next()) { 

         Blob blob = rs.getBlob(1); 
         InputStream is = blob.getBinaryStream(); 

         String filepath = ""; 

         filepath += FileOutDir + "/"; 

         for (int c = 2; c <= cols; c++) { 
          filepath += rs.getObject(c).toString() + "_"; 
         } 

         filepath = filepath.substring(0, 
           filepath.length() - 1); 
         filepath += fileSuffix; 
         fos = new FileOutputStream(filepath); 

         int b = 0; 
         while ((b = is.read()) != -1) { 
          fos.write(b); 
         } 

        } 

        selBlobs.close(); 
        fos.close(); 

       } catch (Exception e) { 
        JOptionPane.showMessageDialog(gui, e.toString()); 
       } 
      } 
     } 
    } else { 
     if (conn == null) { 
      JOptionPane.showMessageDialog(gui, 
        "You have not selected a database."); 
     } else { 
      if (FileOutDir == null) { 
       JOptionPane.showMessageDialog(gui, 
         "You have not chosen a directory for your files."); 
      } else { 
       if (blobSQL == null) { 
        JOptionPane.showMessageDialog(gui, 
          "Please insert an SQL statement."); 

       } 
      } 
     } 
    } 
} 
+0

也许尝试使用缓冲输入和输出流? –

+0

不是缓冲输入和缓冲输出与输入和输出相同,但具有更多功能? – Native

+3

缓冲的输入和输出使读取和写入缓冲的操作,所以他们应该更快地读取和写入 - 而不是读取和逐字节写入,你可以做它块。试一试。 –

回答

1

更改为缓冲输出使进程以指数方式更快。我能够在一分钟内导出727个文件。这里的新代码:

//... 

        while (rs.next()) { 

         blob = rs.getBlob(1); 
         is = blob.getBinaryStream(); 
         filepath += "/"; 

         for (int c = 2; c <= cols; c++) { 
          filepath += rs.getObject(c).toString() + "_"; 
         } 
         filepath = filepath.substring(0, 
           filepath.length() - 1); 
         filepath += fileSuffix; 

         fos = new BufferedOutputStream(new FileOutputStream(filepath)); 

         while ((b = is.read()) != -1) { 
          fos.write(b); 
         } 

         filepath = FileOutDir; 
         b = 0; 
        } 

//... 
+0

现在还有其他问题,似乎有些文件丢失了一些数据。我在这里问了另一个问题:http://stackoverflow.com/questions/19686232/extracting-blobs-to-files-some-files-are-missing-data – Native