title: Read and copy file with Coroutines
body: <p>I created the following application to illustrate some doubts. <a href="https://github.com/onimur/example-copy-file-coroutines" rel="nofollow noreferrer">My Example on the Github</a></p>
  <p>In this example, I copy a file to another package.</p>
  <p><strong>My doubts are as follows:</strong></p>
  <ol>
  <li><p>Performing the tasks in parallel, is it possible to return the values that were completed before the cancellation?</p>
  </li>
  <li><p>Why in <code>contentResolver.openInputStream (uri)</code> the message &quot;Inappropriate blocking method call&quot; appears, while I am working with IO context?</p>
  </li>
  <li><p>While I am reading the file entry to copy to output, I always check the job status so that when this task is canceled, it is stopped immediately, the output file that was created is deleted and returns the cancellation exception, is that correct?</p>
  </li>
  <li><p>Can I delimit the amount of tasks that are performed?</p>
  </li>
  </ol>
  <p>My onCreate:</p>
  <pre><code>private val listUri = mutableListOf&lt;Uri&gt;()
  private val job = Job()
  
  override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState)
      setContentView(R.layout.activity_main)
      
      //get files from 1 to 40
      val packageName = &quot;android.resource://${packageName}/raw/&quot;
      for (i in 1..40) {
          listUri.add(Uri.parse(&quot;${packageName}file$i&quot;))
      }
  }
  </code></pre>
  <p>My button action:</p>
  <pre><code>  //Button action
     fun onClickStartTask(view: View) {
          var listNewPath = emptyList&lt;String&gt;()
          CoroutineScope(Main + job).launch {
              try {
                  //shows something in the UI - progressBar
                  withContext(IO) {
                      listNewPath = listUri.map { uri -&gt;
                          async {
                              //path to file temp
                              val pathFileTemp =
                                  &quot;${getExternalFilesDir(&quot;Temp&quot;).toString()}/${uri.lastPathSegment}&quot;
                              val file = File(pathFileTemp)
                              val inputStream = contentResolver.openInputStream(uri)
                              inputStream?.use { input -&gt;
                                  FileOutputStream(file).use { output -&gt;
                                      val buffer = ByteArray(1024)
                                      var read: Int = input.read(buffer)
                                      while (read != -1) {
                                          if (isActive) {
                                              output.write(buffer, 0, read)
                                              read = input.read(buffer)
                                          } else {
                                              input.close()
                                              output.close()
                                              file.deleteRecursively()
                                              throw CancellationException()
                                          }
                                      }
                                  }
                              }
                              //If completed then it returns the new path.
                              return@async pathFileTemp
                          }
                      }.awaitAll()
                  }
              } finally {
                  //shows list complete in the UI
              }
          }
      }
  </code></pre>
  <p>My button to cancel job:</p>
  <pre><code>fun onClickCancelTask(view: View) {
      if (job.isActive) {
          job.cancelChildren()
          println(&quot;Cancel children&quot;)
      }
  }
  </code></pre>
  <p>This would be the button action to perform the task.</p>
  <p>I thank all the help.</p>