<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _MultiStream(cls, fds):
 """Effectively streams data from multiple opened BlobImage objects. Args: fds: A list of opened AFF4Stream (or AFF4Stream descendants) objects. Yields: Tuples (chunk, fd, exception) where chunk is a binary blob of data and fd is an object from the fds argument. If one or more chunks are missing, exception is a MissingBlobsError object and chunk is None. _MultiStream does its best to skip the file entirely if one of its chunks is missing, but in case of very large files it's still possible to yield a truncated file. """


    broken_fds = set()
    missing_blobs_fd_pairs = []
    for chunk_fd_pairs in collection.Batch(
        cls._GenerateChunkIds(fds), cls.MULTI_STREAM_CHUNKS_READ_AHEAD):
      chunk_fds = list(map(operator.itemgetter(0), chunk_fd_pairs))
      results_map = data_store.BLOBS.ReadBlobs(chunk_fds)

      for chunk_id, fd in chunk_fd_pairs:
        if chunk_id not in results_map or results_map[chunk_id] is None:
          missing_blobs_fd_pairs.append((chunk_id, fd))
          broken_fds.add(fd)

      for chunk, fd in chunk_fd_pairs:
        if fd in broken_fds:
          continue

        yield fd, results_map[chunk], None

    if missing_blobs_fd_pairs:
      missing_blobs_by_fd = {}
      for chunk_id, fd in missing_blobs_fd_pairs:
        missing_blobs_by_fd.setdefault(fd, []).append(chunk_id)

      for fd, missing_blobs in iteritems(missing_blobs_by_fd):
        e = MissingBlobsError(
            "%d missing blobs (multi-stream)" % len(missing_blobs),
            missing_chunks=missing_blobs)
        yield fd, None, e