【问题标题】:AsyncTask: Not Writing data to fileAsyncTask:不将数据写入文件
【发布时间】:2015-04-13 14:08:35
【问题描述】:

我是 Android 编程的新手,我一直在提供一些代码来解决一个我似乎有一段时间无法弄清楚的问题。

我有一个 AsyncTask 正在尝试将一些数据保存到放置在设备内部存储上的文件中。该文件已创建,但填充了 0 个字节

public void exportFile(final Context mContext, boolean debug) {

    try {
        final String path = Environment.getExternalStorageDirectory()
                .getAbsolutePath() + "/DroidP";
        File dir = new File(path);
        dir.mkdirs();

        final File file = new File(dir, "Droid_export.txt");

        if (file.exists()) {
            file.delete();                          
        }

        file.createNewFile();

        final FileWriter out = new FileWriter(file,true);



        final int totalLines = recordsIdList.size();
        new AsyncTask<Void, String, Void>() {
            ProgressDialog progressDialog;

            @Override
            protected Void doInBackground(Void... arg0) {
                try {



                    List<byte[]> mainBuffer = new ArrayList<byte[]>();

                    int i = 0;
                    int size = 0;

                    for (Integer r : recordsIdList) {
                        Log.i("test", db.getRecord(r).toExportSQL());

                        byte[] buffer = db.getRecord(r).toExportSQL().getBytes(); 
                        mainBuffer.add(buffer);
                        size += buffer.length;

                        publishProgress("Writing " + (i++) + " from "+ totalLines);
                    }

                    int pos = 0;
                    char[] outBuffer = new char[size];
                    for(byte[] chunk : mainBuffer) {
                        for(i=0;i<chunk.length;i++) {
                            outBuffer[pos] = (char)chunk[i];
                            pos++;
                        }                           
                    }

                    out.write(outBuffer);

                    out.flush();



                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            }
      }

            @Override
            protected void onProgressUpdate(String... progress) {
                progressDialog.setMessage(progress[0]);
            }

            @Override
            protected void onPostExecute(Void result) {
                super.onPostExecute(result);
                try {
                    out.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                progressDialog.dismiss();
            }

            @Override
            protected void onPreExecute() {
                progressDialog = ProgressDialog.show(mContext,
                        "Exporting file", "", true);
            }
        }.execute((Void) null);
        Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        intent.setData(Uri.fromFile(file.getAbsoluteFile()));
        sendBroadcast(intent);
    } catch (Exception e) {

    }
}

当我查看日志时,我可以看到我试图保存到文件中的数据,这是正确的,但是一旦 AsyncTask 完成,文件就会创建为 0 字节。我是遗漏了什么?请记住,我对 Android 编程还很陌生。

【问题讨论】:

  • 我很困惑。您要读取还是写入文件?
  • 不,你不是——这可能是你想要做的,但你发布的代码读取文件。它不会写入到一个。
  • 你在哪里关闭out?你如何调用 AsyncTask?
  • 你在哪里检查文件的内容?
  • AsyncTask 中包含“Async”一词的原因暗示了它的本质——它在另一个线程(后台线程)中执行。您在另一个线程(又名主线程)中启动媒体扫描过程这一事实意味着存在竞争条件。尝试将媒体扫描码移至protected void onPostExecute(Void result),看看是否有帮助。其实你也应该把所有关于FileWriter out的代码移动到doInBackground,现在你正在从不同的线程调用out对象,没有任何同步。

标签: java android file android-asynctask


【解决方案1】:

我尚未测试您的错误,但您可以通过跳过 bytechar 的转换并将文件处理移动到 async 任务中来简化您的问题,正如许多人所建议的那样。

试试这样的:

private Boolean isExporting = false;

public void exportFile(final Context mContext, boolean debug) {
    if (!isExporting) {
        isExporting = true;
        new AsyncTask<Void, String, Void>() {
            ProgressDialog progressDialog;

            @Override
            protected Void doInBackground(Void... arg0) {
                try {
                    // read data into byte array
                    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    int i = 0;
                    for (Integer r : recordsIdList) {
                        byte[] buffer = db.getRecord(r).toExportSQL().getBytes();
                        Log.i("test", new String(buffer));
                        baos.write(buffer);
                        publishProgress("Writing " + (i++) + " from " + totalLines);
                    }
                    baos.close();
                    // write data to file
                    final String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/DroidP";
                    final File dir = new File(path);
                    dir.mkdirs();
                    final File file = new File(dir, "Droid_export.txt");
                    file.createNewFile();
                    final FileOutputStream fos = new FileOutputStream(file);
                    fos.write(baos.toByteArray());
                    fos.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            }

            @Override
            protected void onProgressUpdate(String... progress) {
                progressDialog.setMessage(progress[0]);
            }

            @Override
            protected void onPostExecute(Void result) {
                super.onPostExecute(result);
                isExporting = false;
                progressDialog.dismiss();
            }

            @Override
            protected void onPreExecute() {
                progressDialog = ProgressDialog.show(mContext,
                        "Exporting file", "", true);
            }
        }.execute();
    }
}

【讨论】:

  • 非常感谢!问题解决了! 14 小时后,我会奖励你赏金。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-20
  • 2018-10-21
  • 2021-11-14
  • 2018-05-26
  • 1970-01-01
相关资源
最近更新 更多