嘗試 new File("image1") 讀取專案 res/raw 或 assets 目錄下的檔案,拋出 FileNotFoundException。這兩個目錄不對應實體檔案系統路徑,無法用 java.io.File 直接存取。
檔案編譯進 APK,透過 R.raw.filename 取得資源 ID。
public static String readRaw(Context context, @RawRes int resId) throws IOException {
try (InputStream is = context.getResources().openRawResource(resId);
BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) sb.append(line).append('\n');
return sb.toString();
}
}
// 呼叫
String content = readRaw(this, R.raw.my_file); // 檔名不含副檔名
檔案保持原始結構,支援子目錄,需包含副檔名。
public static String readAsset(Context context, String fileName) throws IOException {
try (InputStream is = context.getAssets().open(fileName);
BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) sb.append(line).append('\n');
return sb.toString();
}
}
// 呼叫
String content = readAsset(this, "folder/my_file.txt"); // 含路徑與副檔名
public static byte[] readRawBytes(Context context, @RawRes int resId) throws IOException {
try (InputStream is = context.getResources().openRawResource(resId);
ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
byte[] buffer = new byte[4096];
int len;
while ((len = is.read(buffer)) != -1) bos.write(buffer, 0, len);
return bos.toByteArray();
}
}
res/ 或 assets/。byte[],再用 ByteArrayBody 或寫入暫存檔後上傳。assets 無大小限制,res/raw 單檔建議 < 1MB(受資源表限制)。| 特性 | res/raw | assets |
|---|---|---|
| 資源 ID | 自動產生 R.raw.xxx | 無,需字串路徑 |
| 子目錄 | 不支援 | 支援 |
| 編譯時壓縮 | 可能(PNG 等) | 不壓縮,原樣封裝 |
| 適用場景 | 小型固定資源(JSON、XML、短音訊) | 大檔、結構化資料、字體、資料庫種子 |
理解 Android 資源封裝機制,選對讀取 API,才能避開 FileNotFoundException 坑。