2011-06-24 45 views
12

Tôi mới sử dụng OSGi và đã tạo một gói OSGi mà tôi chạy trong vùng chứa Apache OSGi của Apache. Có một tài nguyên tệp có trong gói, mà tôi cần chuyển sang phương thức dưới dạng java.io.File. Để khởi tạo một đối tượng File, hoặc một URI trong "file" -scheme hoặc đường dẫn như chuỗi là cần thiết. Làm thế nào để tôi lấy lại bất kỳ thứ gì trong một cách sạch sẽ?Làm cách nào để truy cập tệp trong gói OSGi?

Tôi đã thử sử dụng context.getBundle().getResource("/myfile") (trong đó ngữ cảnh thuộc loại org.osgi.framework.BundleContext) trả về URI bundle://6.0:0/myfile. Nhưng URI này không thể được chuyển đổi thành một thể hiện tệp bằng cách sử dụng hàm tạo File(URI uri) vì nó có "bó" -scheme.

Người ta có thể cố gắng xây dựng đường dẫn đến vị trí biết thư mục làm việc và khai thác bundleId của gói của tôi, nhưng tôi nghi ngờ đây là phương pháp hay nhất.

Bất kỳ ý tưởng nào?

+0

Equinox có lớp tiện ích đặc biệt để làm chuyển đổi như vậy trong tương lai cách chống, nhưng tôi không biết về Felix. Nếu bạn muốn mã chống lại API OSGi sạch, bạn sẽ cần sao chép tệp này ở đâu đó, nơi bạn có thể dễ dàng truy xuất đối tượng Tệp tương ứng (ví dụ trong bộ nhớ Bundle.getDataFile()). –

Trả lời

12

Vì tệp là bên trong gói của bạn, không có cách nào để bạn truy cập vào nó bằng cách sử dụng tiêu chuẩn File. URL bạn nhận được từ Bundle.getResource() là cách chính xác để truy cập các tài nguyên này, vì API OSGi được dự định cũng hoạt động trên các hệ thống không có hệ thống tệp thực. Tôi sẽ luôn cố gắng gắn bó với API OSGi thay vì sử dụng các giải pháp khung công cụ cụ thể.

Vì vậy, nếu bạn có quyền kiểm soát phương pháp, tôi sẽ cập nhật nó để có một URL hoặc thậm chí là InputStream (vì bạn có thể chỉ muốn đọc từ nó). Để thuận tiện, bạn luôn có thể cung cấp phương thức trợ giúp làm chụp File.

Nếu bạn không có quyền kiểm soát phương pháp này, bạn sẽ phải viết một số phương pháp helper mà mất URL, suối nó ra vào một tập tin (ví dụ, File.createTempFile() có thể sẽ làm các trick.

+0

Cảm ơn câu trả lời của bạn.Tôi không kiểm soát được phương thức, vì nó là một sự phụ thuộc mà tôi không thể sửa đổi và sự phụ thuộc này quyết định một đối số của kiểu File. Để diễn giải câu trả lời của bạn: Bạn đề xuất truy cập Tệp qua InputStream và viết tệp đó dưới dạng tệp tạm thời trong khu vực riêng tư của gói được tham chiếu qua API OSGi. Đây có phải là phương pháp hay nhất nói chung không? Bởi vì với kỹ thuật này, tài nguyên được tăng gấp đôi trong bộ nhớ vật lý. Giả sử bạn có nhiều tệp, tất cả chúng sẽ được tăng gấp đôi, có thể là sự cố trên các thiết bị nhỏ. Hay tôi đang thiếu một điểm? – mtsz

+0

Bạn hoàn toàn đúng, đây là sự thiếu hiệu quả, được đưa ra bởi sự khác biệt về triết học giữa OSGi ("mọi tài nguyên đều có URL, ngay cả khi chúng tôi không có tệp") và thư viện của bạn ("Tôi phải có tệp"). Bạn có thể sử dụng các tệp tạm thời hoặc sử dụng bộ nhớ gói của mình; bất cứ điều gì phù hợp với tình hình của bạn tốt nhất. –

+1

Angelo đúng ... thư viện bạn đang sử dụng được thiết kế kém. Nó khẳng định bạn cung cấp cho nó một tập tin, nhưng những gì bạn có không phải là một tập tin, nó là một mảnh của một tập tin (về mặt kỹ thuật, một mục nhập của một ZIP). Do đó không hiệu quả là không thể tránh khỏi. –

6

lẽ API là confusable, nhưng Bạn có thể truy cập vào một tập tin bên trong một bó OSGi như thế này:.

URL url = context.getBundle().getResource("com/my/weager/impl/test.txt"); 

// The url maybe like this: bundle://2.0:2/com/my/weager/impl/test.txt 
// But this url is not a real file path :(, you could't use it as a file. 
// This url should be handled by the specific URLHandlersBundleStreamHandler, 
// you can look up details in BundleRevisionImpl.createURL(int port, String path) 
System.out.println(url.toString()); 

BufferedReader br =new BufferedReader(new InputStreamReader(url.openConnection().getInputStream())); 
while(br.ready()){ 
    System.out.println(br.readLine()); 
} 
br.close(); 

getResource sẽ tìm thấy tài nguyên thông qua container OSGi toàn giống như lý thuyết OSGi classloader
getEntry sẽ tìm thấy resour ce từ gói địa phương. và url trả về có thể chuyển đổi thành tệp nhưng inputStream.
Đây là câu hỏi tương tự với điều này: No access to Bundle Resource/File (OSGi) Hy vọng điều này sẽ giúp bạn.

1

Những gì tôi sử dụng là getClassLoader() getResourceAsStream():.

InputStream inStream = new java.io.BufferedInputStream(this.getClass().getClassLoader().getResourceAsStream(fileName)); 

Bằng cách này, tập tin sẽ được nạp từ dir tài nguyên của bạn. Tên tệp phải chứa đường dẫn sau "src/main/resources".

Full ví dụ ở đây:

static public byte[] readFileAsBytes(Class c, String fileName) throws IOException { 
    InputStream inStream = new java.io.BufferedInputStream(c.getClassLoader().getResourceAsStream(fileName)); 
    ByteArrayOutputStream out = new ByteArrayOutputStream(); 
    int nbytes = 0; 
    byte[] buffer = new byte[100000]; 

    try { 
     while ((nbytes = inStream.read(buffer)) != -1) { 
      out.write(buffer, 0, nbytes); 
     } 
     return out.toByteArray(); 
    } finally { 
     if (inStream != null) { 
      inStream.close(); 
     } 
     if (out != null) { 
      out.close(); 
     } 
    } 
} 
Các vấn đề liên quan