Прерывание загрузки, которое использует dataInputStream - PullRequest
0 голосов
/ 25 сентября 2019

Имеется довольно простой код для загрузки файла.

class Downloader {
private static Downloader Dinstance = null;
private boolean isAborted = false;

void setAborted(boolean isAborted) {
    isAborted = true;
}

int getAborted() {
    return isAborted;
}

static Downloader getInstance(@NonNull Context context) {
        if (Dinstance == null)
            Dinstance = new Downloaderr(context.getApplicationContext());
        return Dinstance;
    }

private Downloader() {
    ...
    }

function download() {
    ...
    try {
            URL url = new URL(RequestedURL);
            InputStream inputStream = url.openStream();
            DataInputStream dataInputStream = new DataInputStream(inputStream);
            FileOutputStream fileOutputStream = new FileOutputStream(FileName);
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = dataInputStream.read(buffer)) > 0) {
                fileOutputStream.write(buffer, 0, bytesRead);
                if (getAborted()) {
                    Log.d(static_variables.TAG, "Aborting 1");
                    fileOutputStream.close();
                    Log.d(static_variables.TAG, "Aborting 2");
                    dataInputStream.close();
                    Log.d(static_variables.TAG, "Aborting 3");
                    inputStream.close();
                    Log.d(static_variables.TAG, "All closed");                        
                    file.delete();
                    downloadFinished = true;
                    Log.d(static_variables.TAG, "Returning");
                    return false;
                    }
            fileOutputStream.close();
            dataInputStream.close();
            inputStream.close();
        } catch (IOException e) {
            downloadFinished = true;
            return false;
        }
    ...
    }
}

В MainActivity

Слушатель первой кнопки (начало загрузки):

function onClick() {
   new Thread(new Runnable() {
       @Override
       public void run() {
           Downloader.getInstance().download(...);
           }
       }).start();
   }

Слушатель второй кнопки:

function onClick() {
   Downloader.getInstance().setAborted(true);
   }

Загрузка идет в теме.В логах время для dataInputStream.close(); самое большое.И другие исследования показывают, что потоки не будут закрываться до того, как файл будет полностью загружен.

Как я могу завершить InputStream в процессе?

1 Ответ

0 голосов
/ 26 сентября 2019

Во время исследования я обнаружил две вещи.

  1. При таком подходе загрузка прерывается, но есть буфер, а для небольших файлов (в моем случае это песни) его практически невозможно отследить.Для загрузки файла размером 500 МБ, когда вы нажимаете abort на загруженной 15 МБ, то после 16-17 он останавливается.

  2. Если вы хотите (как и я) прекратить загрузку быстрее, тогда вам следует использоватьдругой подход.При запуске Thread сохраните указатель int переменной.

Thread threadDownload = new Thread(...);
threadDownload.start();

, а затем прекратите работу, используя

threadDownload.interrupt();

Осторожно.Вам нужно будет удалить временный файл самостоятельно.Файл, который вы используете в OutputStream.

. У вас также будет некоторое количество буфера, но оно будет не 1-2 МБ, а 200-300 КБ.

...