2016-03-05 48 views
-1

我不明白 - 我試圖獲取文件的路徑,以便文件(圖像)可以作爲附件包含在電子郵件中。作爲字符串的資源文件路徑(不是流式傳輸)

我的系統由兩部分組成 - 一個web應用程序和一個jar。 (實際上有三個部分 - 一個包含DAO的通用共享jar等)

它們都是使用maven構建的。 它們都包含在這個形象該路徑:

的src /主/資源/ logo_48.png

Web應用程序:

String logo1 = getClass().getClassLoader().getResource("logo_48.png").getPath(); 

這完美的作品 - 無論是本地(Windows)和Linux的

罐應用:

String logo1 = getClass().getClassLoader().getResource("logo_48.png").getPath(); //doesn't work 

我已經採取了從這裏DVICE: How to access resources in JAR file? 這裏: Reading a resource file from within jar 這裏: http://www.coderanch.com/t/552720/java/java/access-text-file-JAR

和其他

大多數的答案提供加載該文件作爲流等,但我只希望得到的路徑分配給字符串。其他資源導致我只能在幾小時內盜用代碼才能發現最終結果不起作用。

/home/kalton/daily.jar!logo_48.png這麼多的情況下,後不存在錯誤,我很沮喪,並在以下解決方法解決:

直接拷貝的logo_48.png到所在文件夾罐子所在(/家/ kalton /)

改變我的罐子應用代碼:

String logo1 = "/home/kalton/logo_48.png"; 

和它的作品。

任何人都可以讓我看到正確的方式從未打開的JAR獲取資源文件夾中文件的PATH(作爲字符串)嗎? 這個問題讓我瘋狂了幾個星期! 在此先感謝。 KA。

添加 '路徑' 的實際使用代碼使用的清晰度:

public static MimeMultipart assemble4SO(String logoTop, String emailHTMLText) throws MessagingException, IOException { 
    MimeMultipart content = new MimeMultipart("related"); 
    String cid = Long.toString(System.currentTimeMillis()); 
    String cidB = cid + "b"; 
    String cssStyle = ""; 

    String body = "<html><head>" + cssStyle + "</head><body><div>" + "<img src='cid:" + cid + "'/>" + emailHTMLText + "<img src='cid:" + cidB + "'/></div></body></html>"; 
    MimeBodyPart textPart = new MimeBodyPart(); 

    textPart.setContent(body, "text/html; charset=utf-8"); 
    content.addBodyPart(textPart); 

    //add an inline image 
    MimeBodyPart imagePart = new MimeBodyPart(); 
    imagePart.attachFile(logoTop); 
    imagePart.setContentID("<" + cid + ">"); 
    imagePart.setDisposition(MimeBodyPart.INLINE); 
    content.addBodyPart(imagePart); 

.............

+0

我建議您停止從coderanch.com獲取建議。有98%的答案完全錯誤。 – VGR

+1

由於jar文件中的資源不是文件系統上的文件,因此無法獲取jar文件中資源的文件路徑。這是一個zip條目。你爲什麼需要這條路?您使用哪個API發送電子郵件並創建附件?你的代碼是什麼? –

回答

1

從頂部...

.jar文件實際上是一個zip文件。一個zip文件是一個充當存檔的單個文件。該歸檔中的條目不是單獨的文件,它們只是壓縮文件中的壓縮字節序列。它們不能作爲單獨的文件名或File對象訪問。

同樣重要的是:URL類getPath方法不會將URL轉換爲文件名。它返回URL的路徑部分,該部分只是主機之後的部分(以及任何查詢和/或片段之前)。許多字符在URL中是非法的,並且需要使用百分比編碼進行「轉義」,所以如果您只是直接從URL中提取路徑,那麼通常會得到含有百分號轉義的內容,因此它不是有效的文件名字。

一些例子:根據您的編輯

String path = "C:\\Program Files"; 

URL url = new File(path).toURI().toURL(); 
System.out.println(url);   // prints file:/C:/Program%20Files 
System.out.println(url.getPath()); // prints /C:/Program%20Files 

File file = new File(url.getPath()); 
System.out.println(file.exists()); // prints false, because 
            // "Program%20Files" ≠ "Program Files" 

String path = "C:\\Users\\VGR\\Documents\\résumé.txt"; 

URL url = new File(path).toURI().toURL(); 

// Prints file:/C:/Users/VGR/Documents/r%C3%A9sum%C3%A9.txt 
System.out.println(url); 

// Prints /C:/Users/VGR/Documents/r%C3%A9sum%C3%A9.txt 
System.out.println(url.getPath()); 

File file = new File(url.getPath()); 
System.out.println(file.exists()); // prints false, because 
            // "r%C3%A9sum%C3%A9.txt" ≠ "résumé.txt" 

,我看到了真正的原因,你想有一個字符串是這樣,你可以調用MimeBodyPart.attachFile。你有兩個選擇:

  1. 不要自己的attachFile工作:

    URL logo = getClass().getLoader().getResource("logo_48.png"); 
    imagePart.setDataHandler(new DataHandler(logo)); 
    imagePart.setDisposition(Part.ATTACHMENT); 
    
  2. 複製的資源到一個臨時文件,然後傳遞文件:

    Path logoFile = Files.createTempFile("logo", ".png"); 
    try (InputStream stream = 
        getClass().getLoader().getResourceAsStream("logo_48.png")) { 
    
        Files.copy(stream, logoFile, StandardCopyOption.REPLACE_EXISTING); 
    } 
    imagePart.attachFile(logoFile.toFile()); 
    

正如你所看到的,第一種選擇更容易。第二個選項也需要清理臨時文件,但在發送消息之前您不想這樣做,這可能需要使用TransportListener。

+0

謝謝你的精彩答案,也包括爲什麼答案是這樣的! –

相關問題