Search code examples
javascriptangularpromise

Chunk downloading of the big files right to the hard drive


I have this method to download files. But I want to have a possibility to download files more than 1GB. Is it possible to do it and download it chunk by chunk, because as for me it is really bad to store so much data in the clients memory.

        const list = this.selectionService.getListValue();
        const areAllSelected = this.selectionService.getIsAllSelectedValue();

        const link = document.createElement('a');

        this.loadingText = 'Exporting images...';
        this.showLoading = true;
        this.absolutePosition = true;

        await this.projectImagesService
            .downloadFilteredZip(event.imageSetId, list, areAllSelected)
            .then(response => {
                const contentDisposition = response.headers.get('Content-Disposition');
                const filename = contentDisposition
                    ? contentDisposition.split('filename=')[1]
                    : `image_set_${event.imageSetId}_${Date.now()}.zip`;

                const href = window.URL.createObjectURL(response.body);
                link.download = filename;
                link.href = href;
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);
                this.showLoading = false;
                this.absolutePosition = false;
                this.loadingText = 'Uploading...';
            });
    }

And this is that is happening in the downloadFilteredZip

downloadFilteredZip(imageSetId: number, list: Array<string | number>, allSelected: boolean) {
        const offsetFilters = this.getOffsetFilters();
        const areAllSelected = list.includes('all');

        const url = `image-sets/${imageSetId}/archive?${this.serverApiService.rebuildObjectToQuery({
            ...this.filters,
            ...(!areAllSelected && offsetFilters),
            ...(!areAllSelected && !allSelected && { ids: list }),
        })}`;

        return this.serverApiService.get<Blob>(url, { responseType: 'blob' });
    }
}

I am using Angular, but I have some restriction from team, so I have to use thi serverApiService predefined methods


Solution

  • So, the solution was to use this https://developer.mozilla.org/en-US/docs/Web/API/File_System_API

    Yes, it doesn't support all browsers,so in the case if the current client is not supporting it I show the alert, that it will be using RAM for this procedure and do it as I did before