【问题标题】:Download a file with an AsyncTask使用 AsyncTask 下载文件
【发布时间】:2019-02-17 08:43:03
【问题描述】:

我尝试使用我找到的许多代码通过 AsyncTask 下载文件,但尚未成功。 我在 logcat 上收到错误:E/Error:: No such file or directory。 尽管正在寻找此错误的解决方案,但找不到什么缺失或错误。

这是我认为缺少/错误的 doInBackground 方法:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_splash);

    new DownloadJSON().execute("http://api.androidhive.info/json/movies.json");
}

protected String doInBackground(String...fileUrl) {
        int count;
        try {
            String root = "data/data/com.example.jsonapp2";

            URL url = new URL(fileUrl[0]);

            URLConnection connection = url.openConnection();
            connection.connect();

            // input stream to read file - with 8k buffer
            InputStream input = new BufferedInputStream(url.openStream(), 8192);

            File fileName = new File(root+"/movies.json");
            boolean existsOrNot = fileName.createNewFile(); // if file already exists will do nothing

            // Output stream to write file

            OutputStream output = new FileOutputStream(fileName,false);
            byte data[] = new byte[1024];

            System.out.println("Downloading");
            long total = 0;
            while ((count = input.read(data)) != -1) {
            total += count;

            // writing data to file
            output.write(data, 0, count);
        }
            // flushing output
            output.flush();
            // closing streams
            output.close();
            input.close();
        } catch (Exception e) {
            Log.e("Error: ", e.getMessage());
        }
        return null;
    }

谢谢。

不想用冗余代码轰炸。如果需要其他代码,我很乐意提供。

【问题讨论】:

  • 您的网址似乎没有任何文件
  • 我添加并更改了代码。希望现在什么都没有了。
  • 这个答案可能会有所帮助,stackoverflow.com/questions/25785609/…
  • Log.d(TAG,existsOrNot) 您可以检查文件是否已创建(true)或未创建(false),如果未创建文件,则下面的代码将不会写入任何内容。

标签: android download android-asynctask


【解决方案1】:

更新答案

这对我有用,将文件写入本地存储并在 PostExecute 方法上再次读取

class DownloadJSON extends AsyncTask<String, Void, Void>{

        String fileName;
        String responseTxt;
        String inputLine;
        String folder;

        @Override
        protected Void doInBackground(String... strings) {
            try {
                String root = "data/data/com.example.jsonapp2";
                URL url = new URL(strings[0]);
                HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
                //Set methods and timeouts
                urlConnection.setRequestMethod("GET");
                urlConnection.setReadTimeout(15000);
                urlConnection.setConnectTimeout(15000);

                urlConnection.connect();

                //Create a new InputStreamReader
                InputStreamReader streamReader = new
                        InputStreamReader(urlConnection.getInputStream());
                BufferedReader reader = new BufferedReader(streamReader);

                StringBuilder response  = new StringBuilder();

                //Check if the line we are reading is not null
                while((inputLine = reader.readLine()) != null){
                    response.append(inputLine);
                }

                //Close our InputStream and Buffered reader
                reader.close();
                streamReader.close();

                responseTxt = response.toString();

                Log.d(TAG, "doInBackground: responseText " + responseTxt);

                // PREPARE FOR WRITE FILE TO DEVICE DIRECTORY
                FileOutputStream fos = null;
                fileName = "fileName.json";
                folder = fileFolderDirectory();

                try {
                    fos = new FileOutputStream(new File(folder + fileName));
                    //fos = openFileOutput(folder + fileName, MODE_PRIVATE);
                    fos.write(responseTxt.getBytes());
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if(fos != null){
                        fos.close();
                    }
                }


            } catch (Exception e) {
                Log.e("Error: ", e.getMessage());
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);

            // -- THIS METHOD IS USED TO ENSURE YOUR FILE AVAILABLE INSIDE LOCAL DIRECTORY -- //

            FileInputStream fis = null;
            try {
                fis = new FileInputStream(new File(folder +fileName));
                InputStreamReader isr = new InputStreamReader(fis);
                BufferedReader br = new BufferedReader(isr);
                StringBuilder sb = new StringBuilder();
                String text;

                while ((text = br.readLine()) != null) {
                    sb.append(text).append("\n");
                }

                Toast.makeText(TestActivity.this, "result " + sb.toString(), Toast.LENGTH_SHORT).show();

            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

ops,差点忘了这个方法

public static String fileFolderDirectory() {
        String folder = Environment.getExternalStorageDirectory() + File.separator + "write_your_app_name" + File.separator;
        File directory = new File(folder);
        if(!directory.exists()){
            directory.mkdirs();
        }
        return folder;
    }

【讨论】:

  • 你能告诉我你用的是什么设备模拟器吗?在我这边,那是代码工作
  • 等等,现在我明白为什么这会重现空文件了。这是因为您使用 Rest API 响应而不将其写入文件
  • 我得到一个空指针异常:java.lang.NullPointerException: Attempt to invoke virtual method 'void java.io.FileInputStream.close()' on a null object reference 这意味着 fis 已经被垃圾回收了?
  • 我想我修好了。现在我看到另一个例外是:W/System.err: java.io.FileNotFoundException: /storage/emulated/0/JSONApp/fileName.json (No such file or directory).
  • 我的手机没有sd卡有关系吗?
【解决方案2】:

你的root错了

String root = "data/data/package.appname";

确保您的根目录包含正确的包名或文件路径。

包名应该是你的应用程序ID

【讨论】:

  • data/data/package.appname 仅用于堆栈溢出问题。实际的根目录包含应用程序和包名称。
  • 我添加了缺失的细节。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-02
  • 1970-01-01
  • 2016-11-22
相关资源
最近更新 更多