Я хочу отправить большой файл кусками в Web API.Файл будет содержать данные в объектах JSON.
Условие : Один объект JSON никогда не будет превышать 1 МБ. Размер .Мой API будет загружать 1 МБ содержимого JSON из файла по одному , и он будет разбивать 1 МБ на объекты JSON.Если в 1 МБ остался один неполный JSON-объект, его необходимо сохранить, и когда будет получен следующий блок размером 1 МБ, неполный JSON-объект будет объединен для формирования полного JSON-объекта и последующей его обработки.
File Size: 1 GB
API Will receive : 1 MB
API needs to parse all the JSON object in 1 MB (as much as it can)
Incomplete JSON needs to be stored so that it can be merged in next 1 MB.
Ниже приведено то, что у меня есть до сих пор.
public async Task<bool> Upload()
{
const int bufferSize = 1024*1024;
var filesReadToProvider = await Request.Content.ReadAsMultipartAsync();
foreach (var content in filesReadToProvider.Contents)
{
var stream = await content.ReadAsStreamAsync();
using (StreamReader sr = new StreamReader(stream))
{
int dataRead;
char[] buffer = new char[bufferSize];
dataRead = sr.ReadBlock(buffer, 0, bufferSize);
//forloop
var bteArr = Encoding.GetEncoding("UTF-8").GetBytes(buffer);
while ((dataRead) > 0)
{
using (MemoryStream memoryStream = new MemoryStream(bteArr))
{
try
{
// Process 1 COMPLETE JSON OBJECT out of many JSON's present in 1 MB
}
}
dataRead = sr.ReadBlock(buffer, 0, bufferSize);
}
}
}
return true;
}
Пожалуйста, расскажите мне, как мне этого добиться.
Попытка сделана:
Я предпринял попытку новичка, но это не дурак.Тем не менее, он ломается в определенных угловых случаях, и код также слишком шумный.: - |
public async Task<bool> Upload()
{
const int bufferSize = 1024*1024;
var filesReadToProvider = await Request.Content.ReadAsMultipartAsync();
foreach (var content in filesReadToProvider.Contents)
{
var stream = await content.ReadAsStreamAsync();
using (StreamReader sr = new StreamReader(stream))
{
int dataRead;
char[] buffer = new char[bufferSize];
char[] bufferToSend = new char[bufferSize];
char[] stash = new char[bufferSize];
// buffer getting all the content
dataRead = sr.ReadBlock(buffer, 0, bufferSize);
// finding index of where closing bracket in original buffer
var index = Array.IndexOf(buffer, '}');
// create the stash
Array.Copy(buffer, index + 2, stash, 0, bytesRead - index - 2);
// create the actual buffer to send.
Array.Copy(buffer, 0, bufferToSend, 0, index + 1);
// convert to byte to send.
var bteArr = Encoding.GetEncoding("UTF-8").GetBytes(bufferToSend);
while ((index) > 0)
{
using (MemoryStream memoryStream = new MemoryStream(bteArr))
{
// PROCESS JSON ObJects "bufferToSend"
}
// to end the loop
if (index >= dataRead - 1)
{
index = -1;
break;
}
// keep track of old index so that new stash can be created
var oldindex = index;
// increase the index to new place till where we need to create new buffertosend
index = index + Array.IndexOf(stash, '}') + 2;
// this is needed because if current payload is small then copy will keep the old payload intact
bufferToSend = new char[bufferSize];
// now copy the new stash content to buffer to send
Array.Copy(stash, 0, bufferToSend, 0, index - oldindex - 1);
// convert to bytearray
bteArr = Encoding.GetEncoding("UTF-8").GetBytes(bufferToSend);
// update the stash
stash = new char[bufferSize];
Array.Copy(buffer, index + 2, stash, 0, bytesRead - index - 2);
}
dataRead = sr.ReadBlock(buffer, 0, bufferSize);
}
}
return true;
}
Ввод:
{
"id": 5,
"nm": "Edwy",
"cty": "United Kingdom",
"hse": "House of Wessex",
"yrs": "955-959"
},
{
"id": 6,
"nm": "Edgar",
"cty": "United Kingdom",
"hse": "House of Wessex",
"yrs": "959-975"
}
Ожидаемый вывод.
{
"id": 5,
"nm": "Edwy",
"cty": "United Kingdom",
"hse": "House of Wessex",
"yrs": "955-959"
}
Затем в следующем цикле
{
"id": 6,
"nm": "Edgar",
"cty": "United Kingdom",
"hse": "House of Wessex",
"yrs": "959-975"
},