2011-12-12 34 views
49

tôi cần phải biết đường dẫn chuỗi vào một tập tin vào thư mục tài sản, bởi vì tôi đang sử dụng một api bản đồ mà cần phải nhận được một đường dây, và bản đồ của tôi phải được lưu trữ trên thư mục nội dungLàm cách nào để nhận chuỗi Đường dẫn android đến tệp trên thư mục Nội dung?

Đây là mã tôi đang cố gắng:

MapView mapView = new MapView(this); 
    mapView.setClickable(true); 
    mapView.setBuiltInZoomControls(true); 
    mapView.setMapFile("file:///android_asset/m1.map"); 
    setContentView(mapView); 

Đã xảy ra sự cố với "file:///android_asset/m1.map" vì bản đồ không được tải.

Đó là tệp đường dẫn chuỗi chính xác cho tệp m1.map được lưu trữ trên thư mục nội dung của tôi?

Cảm ơn

EDIT cho Dimitru: Mã này không hoạt động, nó không thành công trên is.read(buffer); với IOException

 try { 
      InputStream is = getAssets().open("m1.map"); 
      int size = is.available(); 
      byte[] buffer = new byte[size]; 
      is.read(buffer); 
      is.close(); 
      text = new String(buffer); 
     } catch (IOException e) {throw new RuntimeException(e);} 

Trả lời

74

AFAIK các tệp trong thư mục nội dung không được giải nén. Thay vào đó, chúng được đọc trực tiếp từ tệp APK (ZIP).

Vì vậy, bạn thực sự không thể tạo nội dung mong đợi một tệp chấp nhận tệp 'nội dung'.

Thay vào đó, bạn sẽ phải trích xuất các tài sản và ghi nó vào một file riêng biệt, như Dumitru gợi ý:

File f = new File(getCacheDir()+"/m1.map"); 
    if (!f.exists()) try { 

    InputStream is = getAssets().open("m1.map"); 
    int size = is.available(); 
    byte[] buffer = new byte[size]; 
    is.read(buffer); 
    is.close(); 


    FileOutputStream fos = new FileOutputStream(f); 
    fos.write(buffer); 
    fos.close(); 
    } catch (Exception e) { throw new RuntimeException(e); } 

    mapView.setMapFile(f.getPath()); 
+2

tôi nhận ngoại lệ: java.io.FileNotFoundException: m1.map – NullPointerException

+0

ngoại lệ trên dòng InputStream là = getAssets() .open ("m1.map"); – NullPointerException

+1

ok, được giải quyết, nhưng bây giờ tôi có ngoại lệ tương tự với câu trả lời của Dumitru, 12-12 15: 06: 41.452: DEBUG/asset (3760): Dữ liệu vượt quá UNCOMPRESS_DATA_MAX (3491923 vs 1048576) – NullPointerException

8

Có một cái nhìn tại ReadAsset.java từ mẫu API đi kèm với SDK.

 try { 
     InputStream is = getAssets().open("read_asset.txt"); 

     // We guarantee that the available method returns the total 
     // size of the asset... of course, this does mean that a single 
     // asset can't be more than 2 gigs. 
     int size = is.available(); 

     // Read the entire asset into a local byte buffer. 
     byte[] buffer = new byte[size]; 
     is.read(buffer); 
     is.close(); 

     // Convert the buffer into a string. 
     String text = new String(buffer); 

     // Finally stick the string into the text view. 
     TextView tv = (TextView)findViewById(R.id.text); 
     tv.setText(text); 
    } catch (IOException e) { 
     // Should never happen! 
     throw new RuntimeException(e); 
    } 
+0

Nó không có tác dụng với tôi, dòng is.read (buffer); cung cấp cho tôi IOException – NullPointerException

+0

Tôi đã chỉnh sửa câu hỏi của mình bằng mã mới, kiểm tra xem nó có vui lòng – NullPointerException

+0

Ngoại lệ chính xác là gì? –

5

Bạn có thể sử dụng phương pháp này.

public static File getRobotCacheFile(Context context) throws IOException { 
     File cacheFile = new File(context.getCacheDir(), "robot.png"); 
     try { 
      InputStream inputStream = context.getAssets().open("robot.png"); 
      try { 
       FileOutputStream outputStream = new FileOutputStream(cacheFile); 
       try { 
        byte[] buf = new byte[1024]; 
        int len; 
        while ((len = inputStream.read(buf)) > 0) { 
         outputStream.write(buf, 0, len); 
        } 
       } finally { 
        outputStream.close(); 
       } 
      } finally { 
       inputStream.close(); 
      } 
     } catch (IOException e) { 
      throw new IOException("Could not open robot png", e); 
     } 
     return cacheFile; 
    } 

Bạn nên bao giờ sử dụng InputStream.available() trong những trường hợp như vậy. Nó chỉ trả về các byte được đệm. Phương thức với .available() sẽ không bao giờ làm việc với các tệp lớn hơn và sẽ không hoạt động trên một số thiết bị.

1

Chỉ cần thêm vào giải pháp hoàn hảo của Jacek. Nếu bạn đang cố gắng làm điều này trong Kotlin, nó sẽ không hoạt động ngay lập tức. Thay vào đó, bạn sẽ muốn sử dụng điều này:

@Throws(IOException::class) 
fun getSplashVideo(context: Context): File { 
    val cacheFile = File(context.cacheDir, "splash_video") 
    try { 
     val inputStream = context.assets.open("splash_video") 
     val outputStream = FileOutputStream(cacheFile) 
     try { 
      inputStream.copyTo(outputStream) 
     } finally { 
      inputStream.close() 
      outputStream.close() 
     } 
    } catch (e: IOException) { 
     throw IOException("Could not open splash_video", e) 
    } 
    return cacheFile 
} 
Các vấn đề liên quan