Length van GZipstream bepalen?

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Avalaxy
  • Registratie: Juni 2006
  • Laatst online: 00:53
Ik wil in .NET data streamen vanuit een file naar AWS S3. Dat probeer ik op de volgende manier te bereiken:

1 Ik lees een file regel voor regel uit met yield return
2 Ik schrijf elke regel naar een MemoryStream
3 Zodra de MemoryStream groter is dan 5MB (hij is niet exact 5MB maar meestal net iets meer omdat ik hele strings uitlees) upload ik een part naar AWS (het is een multi-part upload)
4 Vervolgens set ik de Length van de stream op 0 en ga ik weer verder met naar de stream schrijven van waar ik gebleven was
5 Ik herhaal stap 3 en 4 zo vaak als nodig is tot alle parts geupload zijn

Nu moet ik de data eigenlijk GZippen. Wat ik daarvoor geprobeerd heb is de MemoryStream te encapsulaten in een GZipStream. Het probleem is echter dan je van een GZipStream niet meer de Length op kan vragen en dus niet kan bepalen wanneer ik moet uploaden naar AWS. Ook heb ik dus geen file position (de lengte van de inhoud van de stream).

Dit is de relevante code:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
using (var aws = new AmazonS3Client(_configuration.AccessKeyId, _configuration.AccessKeySecret, RegionEndpoint.EUWest1))
{
    Stream stream = new MemoryStream();
    try
    {
        if (_gzip)
        {
            stream = new GZipStream(stream, CompressionMode.Compress);
        }

        // initiate multi-part upload

        int partNumber = 1;
        long filePosition = 0;

        foreach (string row in GetData())
        {
            stream.WriteString(row);

            long length = stream.Length;

            if (length > 5 * 1024 * 1024)
            {
                FlushToS3(aws, initResponse.UploadId, partNumber, filePosition, stream);
                partNumber++;
                filePosition += length;

                stream.SetLength(0);
            }
        }

        // finish multi-part upload
    }
    finally
    {
        stream.Dispose();
    }
}


Weet iemand een trucje om de lengte van de GZipStream te bepalen, of een andere manier om mijn probleem op te lossen?

[ Voor 11% gewijzigd door Avalaxy op 09-06-2015 21:51 ]


Acties:
  • 0 Henk 'm!

  • Daos
  • Registratie: Oktober 2004
  • Niet online
Bij de constructor van de GZipStream geeft je de stream mee waar (in dit geval) naar geschreven moet worden. Als je dan schrijft naar die GZipStream, komt de gecomprimeerde data in die stream.

Het wordt dan zoiets:
C#:
1
2
3
4
5
6
7
8
9
10
11
string msg = new String('A', 1000); 
Stream srcStream = new MemoryStream(Encoding.UTF8.GetBytes(msg));
            
Stream dstStream = new MemoryStream();
Stream gzStream = new GZipStream(dstStream, CompressionMode.Compress);

// comprimeren
srcStream.CopyTo(gzStream);

Console.WriteLine(srcStream.Length); // 1000
Console.WriteLine(dstStream.Length); // 10