Чтение файла Parquet из Azure blob без локальной загрузки c#. net - PullRequest
0 голосов
/ 30 января 2020

У нас есть файл формата паркета (500 МБ), который находится в Azure blob. Как прочитать файл непосредственно из blob и сохранить в памяти c#, скажем, например: Datatable.

Я могу прочитать паркетный файл, который физически находится в папке, используя приведенный ниже код.

public void ReadParqueFile()
    {
         using (Stream fileStream = System.IO.File.OpenRead("D:/../userdata1.parquet"))     
        {
            using (var parquetReader = new ParquetReader(fileStream))
            {
                DataField[] dataFields = parquetReader.Schema.GetDataFields();

                for (int i = 0; i < parquetReader.RowGroupCount; i++)
                {

                    using (ParquetRowGroupReader groupReader = parquetReader.OpenRowGroupReader(i))
                    {
                        DataColumn[] columns = dataFields.Select(groupReader.ReadColumn).ToArray();

                        DataColumn firstColumn = columns[0];

                        Array data = firstColumn.Data;
                        //int[] ids = (int[])data;
                    }
                }
           }
        }

    }
}

(я могу читать CSV-файл напрямую из BLOB-объекта, используя sourcestream). Пожалуйста, любезно предложить самый быстрый способ чтения файла паркета прямо из blob

1 Ответ

0 голосов
/ 30 января 2020

По моему опыту, решение для непосредственного чтения файла партера из BLOB-объекта заключается в том, чтобы сначала сгенерировать URL-адрес большого двоичного объекта с токеном sas, а затем получить поток HttpClient из URL-адреса с помощью sas и, наконец, прочитать поток ответа http через ParquetReader.

Сначала ознакомьтесь с примером кода ниже в разделе Create a service SAS for a blob официального документа Create a service SAS for a container or blob with .NET, используя Azure Blob Storage SDK для. NET Core.

private static string GetBlobSasUri(CloudBlobContainer container, string blobName, string policyName = null)
{
    string sasBlobToken;

    // Get a reference to a blob within the container.
    // Note that the blob may not exist yet, but a SAS can still be created for it.
    CloudBlockBlob blob = container.GetBlockBlobReference(blobName);

    if (policyName == null)
    {
        // Create a new access policy and define its constraints.
        // Note that the SharedAccessBlobPolicy class is used both to define the parameters of an ad hoc SAS, and
        // to construct a shared access policy that is saved to the container's shared access policies.
        SharedAccessBlobPolicy adHocSAS = new SharedAccessBlobPolicy()
        {
            // When the start time for the SAS is omitted, the start time is assumed to be the time when the storage service receives the request.
            // Omitting the start time for a SAS that is effective immediately helps to avoid clock skew.
            SharedAccessExpiryTime = DateTime.UtcNow.AddHours(24),
            Permissions = SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.Create
        };

        // Generate the shared access signature on the blob, setting the constraints directly on the signature.
        sasBlobToken = blob.GetSharedAccessSignature(adHocSAS);

        Console.WriteLine("SAS for blob (ad hoc): {0}", sasBlobToken);
        Console.WriteLine();
    }
    else
    {
        // Generate the shared access signature on the blob. In this case, all of the constraints for the
        // shared access signature are specified on the container's stored access policy.
        sasBlobToken = blob.GetSharedAccessSignature(null, policyName);

        Console.WriteLine("SAS for blob (stored access policy): {0}", sasBlobToken);
        Console.WriteLine();
    }

    // Return the URI string for the container, including the SAS token.
    return blob.Uri + sasBlobToken;
}

Затем получить http-поток ответа HttpClient из URL-адреса с токеном sas.

var blobUrlWithSAS = GetBlobSasUri(container, blobName);
var client = new HttpClient();
var stream = await client.GetStreamAsync(blobUrlWithSAS);

Наконец, чтобы прочитать его с помощью ParquetReader, код происходит от Reading Data репозитория GitHub aloneguid/parquet-dotnet.

var options = new ParquetOptions { TreatByteArrayAsString = true };
var reader = new ParquetReader(stream, options);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...