我当前正在使用Azure Function Apps v2。我将环境设置为64位,并正在编译为.Net Standard 2.0。主持人Json指定了版本2。
我正在读取.csv,它对于较小的文件也可以正常工作。但是,当我将180MB .csv读入string []列表时,在读取时会膨胀到一个GB以上,当我尝试对其进行解析时,它会超过2 GB,但是会引发“内存不足”异常。即使在超过3.5 GB的应用程序服务计划上运行也无法解决问题。
编辑: 我正在使用这个:
Uri blobUri = AppendSasOnUri(blobName); _webClient = new WebClient();
Stream sourceStream = _webClient.OpenRead(blobUri);
_reader = new StreamReader(sourceStream);
但是,由于它是一个csv,因此我要拆分整列数据。很难摆脱这个问题:
internal async Task<List<string[]>> ReadCsvAsync() {
while (!_reader.EndOfStream) {
string[] currentCsvRow = await ReadCsvRowAsync();
_fullBlobCsv.Add(currentCsvRow);
}
return _fullBlobCsv; }
目标是在所有步骤完成后将json存储到blob中。
答案 0 :(得分:0)
尝试使用流(StreamReader
)读取输入的.csv文件并一次处理一行。
我能够使用流解析消费计划中的300mb文件。我的用例可能不相同,但相似。解析大型串联的pdf文件,并将其分离为5000多个较小的文件,并将分离的文件存储到blob容器中。下面是我的代码供参考。
对于您的用例,如果要将所有解析的数据推送到单个blob中,则可能要使用CloudAppendBlob
而不是CloudBlockBlob
。
public async static void ExtractSmallerFiles(CloudBlockBlob myBlob, string fileDate, ILogger log)
{
using (var reader = new StreamReader(await myBlob.OpenReadAsync()))
{
CloudBlockBlob blockBlob = null;
var fileContents = new StringBuilder(string.Empty);
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
if (line.StartsWith("%%MS_SKEY_0000_000_PDF:"))
{
var matches = Regex.Match(line, @"%%MS_SKEY_0000_000_PDF: A(\d+)_SMFL_B1234_D(\d{8})_A\d+_M(\d{15}) _N\d+");
var smallFileDate = matches.Groups[2];
var accountNumber = matches.Groups[3];
var fileName = $"SmallerFiles/{smallFileDate}/{accountNumber}.pdf";
blockBlob = myBlob.Container.GetBlockBlobReference(fileName);
}
fileContents.AppendLine(line);
if (line.Equals("%%EOF"))
{
log.LogInformation($"Uploading {fileContents.Length} bytes to {blockBlob.Name}");
await blockBlob.UploadTextAsync(fileContents.ToString());
fileContents = new StringBuilder(string.Empty);
}
}
await myBlob.DeleteAsync();
log.LogInformation("Extracted Smaller files");
}
}