2015-06-29 79 views
0

我想創建一個通用上傳代碼,它可以將所有數據,文本,圖像,視頻文件等插入blob字段,從相同的數據中檢索數據。我有 認爲將文件轉換爲字節,然後上傳它,並使用類似的方法下載它將工作。 有什麼比我更喜歡的是,儘管我能夠使用字節方法成功下載任何格式的文件,但通過將文件轉換爲字節上傳文件, 只能使用pdf和文本相關文檔。在上傳圖像文件或甚至xls文件時,我觀察到blob字段的字節大小比原始文件的字節大小更新(更新:不匹配)。下載後發現這些文件是不可讀的。在使用字節數組插入圖像,xls文件到blob時丟失字節和數據損壞

(我所遇到的過程中https://community.oracle.com/thread/1128742?tstart=0這將幫助我實現我想要的東西。但是,這將意味着我當前的代碼 相當重寫。我希望有一個出路在我當前的代碼本身。)

我 '插入到斑點' 代碼現在是:

表結構:

desc project_storage 
Name  Null Type   
---------- ---- ------------- 
PROJECT_ID  NUMBER(38)  
FILE_NAME  VARCHAR2(200) 
DOCUMENTS  BLOB   
ALIAS   VARCHAR2(50) 
FILE_TYPE  VARCHAR2(200) 

代碼:

@RequestMapping(value="/insertProject.htm", method = { RequestMethod.POST}, headers="Accept=*/*") 
    public String insert(@RequestParam Map<String,Object> parameters,@RequestParam CommonsMultipartFile file,Model model,HttpServletRequest req){ 
     try 
     { 
      log.info("Datasource || attempt to insert into project storage -Start()"); 
      if(file!=null) 
      { 
       String file_type=file.getContentType(); 
       String file_name=file.getOriginalFlename(); 
       String file_storage=file.getStorageDescription(); 
       long file_size=file.getSize(); 
       System.out.println("File type is : "+file_type); 
       System.out.println("File name is :"+file_name); 
       System.out.println("File size is"+file_size); 
       System.out.println("Storage Description :"+file_storage); 
      ByteArrayOutputStream barr = new ByteArrayOutputStream(); 
       ObjectOutputStream objOstream = new ObjectOutputStream(barr); 
       objOstream.writeObject(file); 
       objOstream.flush(); 
       objOstream.close(); 
       byte[] bArray = barr.toByteArray(); 

      // byte [] bArray=file.getBytes(); 
      // InputStream inputStream = new ByteArrayInputStream(bArray); 
       //inputStream.read(); 
       Object objArray[]=new Object[]{file_name,bArray,parameters.get("alias"),file_type}; //bArray is our target. 
      int result=dbUtil.saveData("Insert into Project_Storage(Project_Id,File_Name,Documents,Alias,File_Type) values(to_number(?),?,?,?,?)", objArray); 
      model.addAttribute(result); 

      } 
     } 
     catch(Exception e){ 
      System.out.println("Exception while inserting the documents"+e.toString()); 
      e.printStackTrace(); 
     } 

     log.info("Datasource || attempt to insert new project -end()"); 
     return "admin/Result"; 
     } 

我哪裏錯了?當文件是xls,圖像或文件時,到底是什麼填充到blob字段?

編輯:嘗試上載一個虛設excel文件是如下: Game.xls file

The console output is as follows : 
    [6/29/15 20:28:41:803 IST] 0000004d SystemOut  O File type is : application/octet-stream 
    [6/29/15 20:28:41:803 IST] 0000004d SystemOut  O File name is :Game.xls 
    [6/29/15 20:28:41:804 IST] 0000004d SystemOut  O File size is: 6144 //this is original size of file. 
    [6/29/15 20:28:41:804 IST] 0000004d SystemOut  O Storage Description :in memory 
    [6/29/15 20:28:41:805 IST] 0000004d SystemOut  O DBUtil || saveData || Query : Insert into Project_Storage(Project_Id,File_Name,Documents,Alias,File_Type) values(to_number(?),?,?,?,?)|| Object : [Ljava.lang.Object;@1eecbb7 
    [6/29/15 20:28:42:020 IST] 0000004d servlet  I 

下載的文件是大小6.7 KB的,幷包含數據如下: enter image description here

由此可見這是數據損壞的問題。我以前認爲只有部分輸入數據發生。 編輯: - 正在通過表單讀取文件。

<span class="btn btn-default btn-file" id="btn_upload"> 
    Browse <input type="file" name="file"></span> 
+1

我不熟悉java,但是我遇到過一次blob問題。檢查是否有任何這樣的答案可以幫助你:http://stackoverflow.com/questions/31030744/how-to-get-bmp-image-from-from-binary-blob-data-with-php – Clyff

+0

@Clyff,I不要認爲這是一個大小/長度的限制..雖然我也是編程新手。然而,今天從你身上學到了一件新事物:-) –

+0

爲什麼要保存在Blob中,或者就此而言,即使在DB中,也可以在數據庫中使用一個bytea並保存爲字節數組。優點是處理較少。您可以通過指定atBasic註釋並延遲加載來延遲加載bytea變量,因此不會總是獲取文檔。 –

回答

0

您正在存儲一個java對象:file。檢索看起來是錯誤的,因爲您會看到Excel文件中的一些序列化對象。

由於上傳數據(file)是臨時性質(上傳的文件應該得到處理和刪除),我不認爲file將包含的全部內容(不知道,但!),最好的店顯式地將內容字節與元數據分開,如文件大小和類型。這將允許立即將文件內容傳送給用戶。這同樣適用於上傳:而不是提供用於存儲blob的InputStream的ByteArrayOutputStream將減少服務器負載。

將元數據分開還允許有一個很好的「目錄概覽」。

+0

如果文件無法包含整個內容,那麼無法插入相當大尺寸的pdf文件是無能爲力的。嘗試實施您的建議以提高性能。 –

+0

對不起,我想你應該顯示閱讀代碼。仍然有希望,像塊讀取錯誤或類似這樣的事情是微不足道的。 –

+0

也許我錯過了應該發佈的內容,正在通過表單讀取文件。 瀏覽。任何與此有關的事情? –

0

我看到了問題。 這是它的工作原理。 原始文件內容= 6144字節 這包含excel/pdf/jpeg的正確頭文件。

我們稱之爲「A」。「A」通常由兩部分組成。 [「Ah」+「Ab」] = [「A」] 「Ah」是頭文件,告訴excel這是一個excel文檔,告訴pdf閱讀器這是一個pdf文檔。通常是幾個字節。也許3或4,也許稍微多一些。

「Ab」是身體。

尺寸( 「A」)= 6144字節 尺寸( 「啊」 + 「AB」)= 6144個字節

確定。用6114字節完成。

接下來是您存儲爲blob的6.7kb。 這包含更多數據。

尺寸( 「斑點」)=尺寸(CommonsMultipartFile文件)= 6.7kb

這包含[文件大小,mime類型,( 「啊」 + 「AB」),其他數據]

所以你有2個選項。

選項a:

更改存儲代碼並且沒有更改您的檢索代碼。

使用byte[] bArray = barr.toByteArray();

和存儲( 「阿」 + 「AB」)

選項B: 更改檢索代碼和存儲的代碼沒有變化。 當您從數據庫獲取數據時,將其轉換爲CommonsMultipartFile file,並從中使用file.getBytes並將字節的內容寫入servlet輸出流。

+0

嗨,看來我能夠獲得移動現在成爲完美另一個文件夾中的文件,內容如下:「嘗試{ \t \t \t \t \t文件文件2 =新的文件(‘C:\\ \\審判’+ FILE_NAME) ; \t \t \t \t \t \t file2.getParentFile()。mkdir(); \t \t \t \t \t file2.createNewFile(); \t \t \t \t \t file.transferTo(file2); \t \t \t \t \t \t \t \t \t} \t \t \t \t趕上(拋出:SecurityException E){ \t \t \t \t的System.out.println( 「文件不能由於安全異常創建」); \t \t \t \t e.printStackTrace(); \t \t \t \t}' –

+1

用於下載文件的代碼位於我的其他問題中:http://stackoverflow.com/questions/31054428/extract-blob-value-and-pass-to-controller-in-spring -mvc-without-using-hibernate目前它的工作非常完美,因此不打算更改此代碼。所以這給我留下了一個選項a,我想我現在正在執行這個選項。謝謝你的見解:-) –