[英]Using an AsyncTask to copy assets to SD card throws an IOException, but creates a 0 byte file
我正在使用以下代碼段將資產目錄中的項目復制到SD卡中。
String DATA_PATH = Environment.getExternalStorageDirectory().toString() + "/MyApp/";
String lang = "eng";
String[] paths = new String[]
{DATA_PATH, DATA_PATH + "mydata/"};
for (String path : paths)
{
File dir = new File(path);
if (!dir.exists())
{
if (!dir.mkdirs())
{
Log.d(TAG, "ERROR: Creation of directory " + path + " on sdcard failed");
// return null;
}
else
{
Log.d(TAG, "Created Directory " + path + " on sd card");
}
}
Log.d(TAG, "Path " + path + "already exists, not creating");
}
if (!(new File(DATA_PATH + "mydata/" + lang + ".dat")).exists())
{
try
{
Log.d(TAG, "Couldn't find any dat files on SD card, attempting to copy new ones");
AssetManager assetManager = getAssets();
String[] filesList = assetManager.list("");
StringBuilder sb = new StringBuilder();
for (String s : filesList)
{
Log.d(TAG, "Found file : " + s);
if (s.contains("dat"))
{
try
{
Log.d(TAG, "Found a dat file, attempting to copy to SD card");
InputStream in = assetManager.open("eng.dat");
Log.d(TAG, "Opened an inputStream to eng.dat");
// GZIPInputStream gin = new GZIPInputStream(in);
OutputStream out = new FileOutputStream(DATA_PATH + "mydata/eng.dat");
Log.d(TAG, "Opened an outputStream to " + DATA_PATH + "mydata/eng.dat");
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
// while ((lenf = gin.read(buff)) > 0) {
while ((len = in.read(buf)) != -1)
{
out.write(buf, 0, len);
}
in.close();
// gin.close();
out.close();
Log.d(TAG, "Copied " + lang + " .dat");
}
catch (IOException ioe)
{
Log.e(TAG, "Was unable to copy " + s + " " + ioe);
}
}
Log.d(TAG, "File : " + s + " is not something we're interested in, not copying to SD card.");
}
}
catch (IOException e)
{
Log.e(TAG, "Was unable to copy assets " + e.toString());
}
}
我的清單文件中也有此行:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
我的logcat的輸出是:
05-22 13:57:57.289: D/SEARCH(14609): Path /mnt/sdcard/MyApp/already exists, not creating
05-22 13:57:57.289: D/SEARCH(14609): Path /mnt/sdcard/MyApp/mydata/already exists, not creating
05-22 13:57:57.289: D/SEARCH(14609): Couldn't find any traindeddata files on SD card, attempting to copy new ones
05-22 13:57:57.449: D/SEARCH(14609): Found file : badges
05-22 13:57:57.449: D/SEARCH(14609): File : badges is not something we're interested in, not copying to SD card.
05-22 13:57:57.449: D/SEARCH(14609): Found file : eng.dat
05-22 13:57:57.449: D/SEARCH(14609): Found a dat file, attempting to copy to SD card
05-22 13:57:57.449: D/SEARCH(14609): Opened an inputStream to eng.dat
05-22 13:57:57.469: D/SEARCH(14609): Opened an outputStream to /mnt/sdcard/MyApp/mydata/eng.dat
05-22 13:57:57.469: E/SEARCH(14609): Was unable to copy eng.dat java.io.IOException
05-22 13:57:57.469: D/SEARCH(14609): File : eng.dat is not something we're interested in, not copying to SD card.
05-22 13:57:57.469: D/SEARCH(14609): Found file : images
05-22 13:57:57.469: D/SEARCH(14609): File : images is not something we're interested in, not copying to SD card.
05-22 13:57:57.469: D/SEARCH(14609): Found file : sounds
05-22 13:57:57.469: D/SEARCH(14609): File : sounds is not something we're interested in, not copying to SD card.
05-22 13:57:57.469: D/SEARCH(14609): Found file : webkit
05-22 13:57:57.469: D/SEARCH(14609): File : webkit is not something we're interested in, not copying to SD card.
似乎已成功在SD卡上創建了文件,但始終為0字節。 卡上有大約700MB的可用空間,而我的dat文件只有3MB,因此沒有容量問題。
我正在使用API級別8。
任何人都可以對導致IOException的原因提出建議嗎?
謝謝
編輯 :這是堆棧跟蹤(感謝Narek的注意)
05-22 14:28:37.043: E/INITIALISATION(22774): java.io.IOException
05-22 14:28:37.043: E/INITIALISATION(22774): at android.content.res.AssetManager.readAsset(Native Method)
05-22 14:28:37.043: E/INITIALISATION(22774): at android.content.res.AssetManager.access$700(AssetManager.java:36)
05-22 14:28:37.043: E/INITIALISATION(22774): at android.content.res.AssetManager$AssetInputStream.read(AssetManager.java:571)
05-22 14:28:37.043: E/INITIALISATION(22774): at com.example.myapp.task.InitialisationTask.doInBackground(InitialisationTask.java:86)
05-22 14:28:37.043: E/INITIALISATION(22774): at com.example.myapp.task.InitialisationTask.doInBackground(InitialisationTask.java:19)
05-22 14:28:37.043: E/INITIALISATION(22774): at android.os.AsyncTask$2.call(AsyncTask.java:185)
05-22 14:28:37.043: E/INITIALISATION(22774): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
05-22 14:28:37.043: E/INITIALISATION(22774): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
05-22 14:28:37.043: E/INITIALISATION(22774): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
05-22 14:28:37.043: E/INITIALISATION(22774): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
05-22 14:28:37.043: E/INITIALISATION(22774): at java.lang.Thread.run(Thread.java:1096)
James.Elsey!我讀了你的代碼,我認為你的問題在這個地方的紅色圓圈內:
byte[] buf = new byte[1024];
int len;
// while ((lenf = gin.read(buff)) > 0) {
while ((len = in.read(buf)) != -1) {
out.write(buf, 0, len);
out.flush();//Refresh the buffer output stream.This forced all buffer output byte iswrite to the bottom of the output stream.
}
in.close();
// gin.close();
out.close();
您可以嘗試解決您的問題。 我的英語不好,不知道我是否把問題弄清楚了。 有關更詳細說明的Flush()方法,您可以轉到參考API文檔。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.