bigpotato
bigpotato

Reputation: 27507

Read file slice as bytes and send to server?

I want to read a slice of a file using a FileReader, and then send it to a server. This is what I have so far:

const createReader = onRead => {
  const reader = new FileReader();
  reader.onloadend = function(evt) {
    if (evt.target.readyState === FileReader.DONE) {
      const arrayBuffer = evt.target.result;
      const bytes = new Uint8Array(arrayBuffer);
      console.log("BYTES: ", bytes);
      onRead(evt.target.result);
    }
  };
  return reader;
};

const reader = createReader(fileSlice => {
  console.log("BYTES: ", fileSlice);
  // send to server
});
reader.readAsArrayBuffer(blob);

Here's what it printed when I uploaded a simple .txt file:

However, it returns an array, and I'm not sure how to convert this into a format that I can send over to my server through HTTP.

enter image description here

Does anyone know what I need to do in order to convert that byte array into a format that I can eventually turn back into the original file?

Upvotes: 0

Views: 3615

Answers (2)

Assaf S.
Assaf S.

Reputation: 4874

Read the file chunk, make sure you use readAsArrayBuffer

var readChunck = function (offset, length, file) {
  var r = new FileReader();
  var chunck = file.slice(offset, length + offset);
  r.onload = readEventHandler;
  r.readAsArrayBuffer(chunck)
}

In the vent handler (readEventHandler), convert the ArrayBuffer to Base64String and post to the server:

var readEventHandler = function (evt) {

  var data = {
    data: self.arrayBufferToBase64String(evt.target.result)
  }

  self.httpClient.post(url, data)
    .subscribe(data=> {
     // do stuff 
    });

  // ...
}

And here is the conversion function:

private arrayBufferToBase64String(buffer: ArrayBuffer) {
  let binaryString = ''
  var bytes = new Uint8Array(buffer);
  for (var i = 0; i < bytes.byteLength; i++) {
    binaryString += String.fromCharCode(bytes[i]);
  }

  return window.btoa(binaryString);
}

On the server side (ASP Core Web API in this case):

[HttpPost, DisableRequestSizeLimit]
[Route("{blobId}/uploads/{uploadId}/parts/{partNumber}")]
public async Task<IActionResult> UploadPart(
  [FromRoute] string blobId,
  [FromRoute] string uploadId,
  [FromRoute] int partNumber,
  [FromBody] FilePartModel part)
  {
    if (!GuidValidator.IsValidGuid(blobId)) throw new ArgumentException("Invalid BLOB Id");
    if (!GuidValidator.IsValidGuid(uploadId)) throw new ArgumentException("Invalid Upload Id");

    var bytes = Convert.FromBase64String(part.Data);
    using (var stream = new MemoryStream(bytes))
    {
      var etag = await _blobsService.UploadPartAsync(Guid.Parse(blobId), Guid.Parse(uploadId), partNumber, stream);

      return Ok(new FilePart { ETag = etag, PartNumber = partNumber });
    }
}

FilePartModel is just a simple model class:

public class FilePartModel
{
    public string Data { get; set; }
}

Upvotes: 0

guest271314
guest271314

Reputation: 1

You can POST the Uint8Array to the server. You can convert a Uint8Array to a string using TextDecoder

Upvotes: 2

Related Questions