生成的 blob 不包含完整的数据集
Generated blob doesn't contain full dataset
我正在尝试在 JavaScript 中拼凑一个二进制包(字符串、整数和文件的组合),然后将其传递给 C# WebSocket 服务器,但我无法将整个数据集获取到被包含在 blob 中。我看到的是最终输出的 blob 比它的各个部分的总和小得多。
比如数据文件本身是8890,但是finalBlob.size只有119.
最终我只需要一个小型简洁的二进制包,它组装在 Javascript 混合数据中,我可以 运行 通过 C# 内存流,而无需将所有内容都转换为 UTF8 文本。
fetch(request).then(data => AssemblePackage(data)).catch(error => {
console.error("Unable to retrieve asset: " + error);
});
async function AssemblePackage(data){
//Example Data
var token = "3F73B3E6-7351-416F-ACA3-AE639A3F587F";
var requestKey = 3;
var requestId = "6BFF91D6-4346-424C-AE01-62E5C7F3C9BC";
var assetName = "MyAssetFile.dat";
let parts = [];
//36 UTF8 chars (Includes guid '-' chars)
parts.push(token);
//2 UTF8 bytes max '00'-'99' (workaround for blob not storing an int as
//an int but a UTF8 string...)
let chars = requestKey.toString().split('');
while(chars.length < 2){
chars.unshift('0');
}
parts.push(chars.join(''));
//36 UTF8 chars (Includes guid '-' chars)
parts.push(requestId);
//3 UTF8 bytes max '000'-'999' (workaround for blob not storing an int as
//an int but a UTF8 string...)
chars = assetName.length.toString().split('');
while(chars.length < 3){
chars.unshift('0');
}
parts.push(chars.join(''));
//1-999 character string
parts.push(assetName);
//
let fileBlob = await data.blob();
parts.push(await this.ReadFileBlobAsUint8(fileBlob));
var finalBlob = new Blob([parts], {type: "application/octet-stream"});
}
ReadFileBlobAsUint8(fileBlob){
return new Promise((resolve, reject) =>{
let rdr = new FileReader();
rdr.onerror = () => {
rdr.abort();
reject(rdr.error);
};
rdr.onload = () =>{
resolve(new Uint8Array(rdr.result));
};
rdr.readAsArrayBuffer(fileBlob);
});
}
这就是我最终需要做的。这不是很优雅,但它可以解决问题。
提取请求。
fetch(request).then(data => AssemblePackage(data)).catch(error => {
console.error("Unable to retrieve asset: " + error);
});
Assemble数据
async AssemblePackage(data){
var token = "3F73B3E6-7351-416F-ACA3-AE639A3F587F";
var requestKey = 3;
var requestId = "6BFF91D6-4346-424C-AE01-62E5C7F3C9BC";
var assetName = "MyAssetFile.dat";
if(data.ok){
let textEnc = new TextEncoder();
//36 char UTF8 GUID (Includes guid '-' chars)
let rawToken = textEnc.encode(token);
//single uint representing request Key
let rawKey = new Uint8Array(1);
rawKey[0] = requestKey;
//36 char UTF8 GUID (Includes guid '-' chars)
let rawId = textEnc.encode(requestId);
//UTF8 string representing asset name max-length: 255
let rawName = textEnc.encode(assetName);
//Single uint representing the length of the assetName
let nameSize = new Uint8Array(1);
nameSize[0] = rawName.byteLength;
//byte[] representing the fetched asset
let asset = new Uint8Array(await data.arrayBuffer());
//Calculate combined size
let size = rawToken.byteLength + rawKey.byteLength + rawId.byteLength;
size += nameSize.byteLength + rawName.byteLength + asset.byteLength;
//Alloclate new buffer
let result = new Uint8Array(size);
// Build the new array
let offset = 0;
result.set(rawToken, offset);
offset += rawToken.byteLength;
result.set(rawKey, offset);
offset += rawKey.byteLength;
result.set(rawId, offset);
offset += rawId.byteLength;
result.set(nameSize, offset);
offset += nameSize.byteLength;
result.set(rawName, offset);
offset += rawName.byteLength;
result.set(asset, offset);
offset += asset.byteLength;
//Do something with your byte[]
SendData(result.buffer);
}else{
//Text Message
console.error("Asset fetch failed: "+ data);
}
}
我正在尝试在 JavaScript 中拼凑一个二进制包(字符串、整数和文件的组合),然后将其传递给 C# WebSocket 服务器,但我无法将整个数据集获取到被包含在 blob 中。我看到的是最终输出的 blob 比它的各个部分的总和小得多。
比如数据文件本身是8890,但是finalBlob.size只有119.
最终我只需要一个小型简洁的二进制包,它组装在 Javascript 混合数据中,我可以 运行 通过 C# 内存流,而无需将所有内容都转换为 UTF8 文本。
fetch(request).then(data => AssemblePackage(data)).catch(error => {
console.error("Unable to retrieve asset: " + error);
});
async function AssemblePackage(data){
//Example Data
var token = "3F73B3E6-7351-416F-ACA3-AE639A3F587F";
var requestKey = 3;
var requestId = "6BFF91D6-4346-424C-AE01-62E5C7F3C9BC";
var assetName = "MyAssetFile.dat";
let parts = [];
//36 UTF8 chars (Includes guid '-' chars)
parts.push(token);
//2 UTF8 bytes max '00'-'99' (workaround for blob not storing an int as
//an int but a UTF8 string...)
let chars = requestKey.toString().split('');
while(chars.length < 2){
chars.unshift('0');
}
parts.push(chars.join(''));
//36 UTF8 chars (Includes guid '-' chars)
parts.push(requestId);
//3 UTF8 bytes max '000'-'999' (workaround for blob not storing an int as
//an int but a UTF8 string...)
chars = assetName.length.toString().split('');
while(chars.length < 3){
chars.unshift('0');
}
parts.push(chars.join(''));
//1-999 character string
parts.push(assetName);
//
let fileBlob = await data.blob();
parts.push(await this.ReadFileBlobAsUint8(fileBlob));
var finalBlob = new Blob([parts], {type: "application/octet-stream"});
}
ReadFileBlobAsUint8(fileBlob){
return new Promise((resolve, reject) =>{
let rdr = new FileReader();
rdr.onerror = () => {
rdr.abort();
reject(rdr.error);
};
rdr.onload = () =>{
resolve(new Uint8Array(rdr.result));
};
rdr.readAsArrayBuffer(fileBlob);
});
}
这就是我最终需要做的。这不是很优雅,但它可以解决问题。
提取请求。
fetch(request).then(data => AssemblePackage(data)).catch(error => {
console.error("Unable to retrieve asset: " + error);
});
Assemble数据
async AssemblePackage(data){
var token = "3F73B3E6-7351-416F-ACA3-AE639A3F587F";
var requestKey = 3;
var requestId = "6BFF91D6-4346-424C-AE01-62E5C7F3C9BC";
var assetName = "MyAssetFile.dat";
if(data.ok){
let textEnc = new TextEncoder();
//36 char UTF8 GUID (Includes guid '-' chars)
let rawToken = textEnc.encode(token);
//single uint representing request Key
let rawKey = new Uint8Array(1);
rawKey[0] = requestKey;
//36 char UTF8 GUID (Includes guid '-' chars)
let rawId = textEnc.encode(requestId);
//UTF8 string representing asset name max-length: 255
let rawName = textEnc.encode(assetName);
//Single uint representing the length of the assetName
let nameSize = new Uint8Array(1);
nameSize[0] = rawName.byteLength;
//byte[] representing the fetched asset
let asset = new Uint8Array(await data.arrayBuffer());
//Calculate combined size
let size = rawToken.byteLength + rawKey.byteLength + rawId.byteLength;
size += nameSize.byteLength + rawName.byteLength + asset.byteLength;
//Alloclate new buffer
let result = new Uint8Array(size);
// Build the new array
let offset = 0;
result.set(rawToken, offset);
offset += rawToken.byteLength;
result.set(rawKey, offset);
offset += rawKey.byteLength;
result.set(rawId, offset);
offset += rawId.byteLength;
result.set(nameSize, offset);
offset += nameSize.byteLength;
result.set(rawName, offset);
offset += rawName.byteLength;
result.set(asset, offset);
offset += asset.byteLength;
//Do something with your byte[]
SendData(result.buffer);
}else{
//Text Message
console.error("Asset fetch failed: "+ data);
}
}