0

I've seen some answers to this question posted, but nothing exactly like what I am struggling with, and I'm having some trouble.

Basically, I am using an API that returns data in a byte array like so:

byte[] file = Api.getZippedReport(blah, blah);

I'm trying to figure out the best way to spit out the contents of the tab delimited file in C# so I can do something with it.

What is the simplest way to just get the data back so I can use it without actually having to save the file?

Simon MᶜKenzie
  • 8,344
  • 13
  • 50
  • 77
Chris Jenkins
  • 719
  • 7
  • 20
  • GZip is a great library for doing this. Have you looked into that? – Codeman May 10 '13 at 00:12
  • How is the data compressed? Gzip? Deflate (the algorithm used in zip, applied to one data stream instead of multiple files)? Is it an actual Zip archive? (if so, what file(s) in the archive are you looking for?) Something else? In any case, once you know what the data type is, just google for a way to decompress it, then turn it into text (what encoding is used?), probably using `Encoding.Something.GetString(decompressedFile)`, then google for a good way to read a tab-delimited file in .Net. – Tim S. May 10 '13 at 00:16
  • It is an actual zip archive. One directory & one file. I'm able to download the file, and I'm able to open the file in C#, but I don't want any File IO happening with this. – Chris Jenkins May 10 '13 at 00:18
  • Check out http://www.icsharpcode.net/opensource/sharpziplib/ as a ZIP library. – Tim S. May 10 '13 at 00:21

3 Answers3

1

In case this is a .net 4.5 application you can use the newly introduced ZipArchive class which offers a GetEntry() method:

Stream stream = new MemoryStream(file); // file as your byte[]
ZipArchive archive = new ZipArchive(stream )
ZipArchiveEntry entry = archive.GetEntry("ExistingFile.txt");

// Do your logic with the file you get from entry.Open()

entry.LastWriteTime = DateTimeOffset.UtcNow.LocalDateTime;

See ZipArchive Class and ZipArchive.GetEntry Method. There is a property on ZipArchive called Entries that contains all the entries in a readonly collection:

public ReadOnlyCollection<ZipArchiveEntry> Entries { get; }
Chief Wiggum
  • 2,784
  • 2
  • 31
  • 44
  • I think you mean `new MemoryStream(file);` – Simon MᶜKenzie May 10 '13 at 00:49
  • No, I meant: Stream stream = new MemoryStream(byteArray); Since het gets a byte[] from his API and we don't want to use any I/O operations. – Chief Wiggum May 10 '13 at 00:50
  • I meant with reference to the code in the question: `byte[] file = Api.getZippedReport(blah, blah);`... – Simon MᶜKenzie May 10 '13 at 00:54
  • Well to be honest, after reading it a 2nd time I'm actually not sure anymore if he already has the uncompressed file or not. Is he just looking for a in-memory splitting or a decompression as well? :-) – Chief Wiggum May 10 '13 at 00:59
  • I think it's decompression followed by splitting :) – Simon MᶜKenzie May 10 '13 at 01:00
  • Yes I need to decompress and then split. I'm using .net 4.5 but it looks like the ZipArchive Class is still unavailable. Am I missing something super straightforward? – Chris Jenkins May 10 '13 at 17:21
  • Haha, nevermind it's working. I have one more followup question. I only have one entry in the zip directory, but the name changes. How can I get the entry if the name is not static? – Chris Jenkins May 10 '13 at 17:28
  • There's a property on the ZipArchive class with all the entries. Just get the single item in this collection: public ReadOnlyCollection Entries { get; } – Chief Wiggum May 12 '13 at 21:59
0

the best way to spit out the contents of the tab delimited file in C#

byte[] file = Api.getZippedReport(blah, blah);
string fileString = System.Text.Encoding.UTF8.GetString(file);
string[] fileSplit = fileString.Split('\t');

Hope this helps... If it doesn't please let me know.

Display Name
  • 4,672
  • 1
  • 33
  • 43
  • Of course it would probable make sense in general, I was just answering guy's question - how to split by tabs, I guess he'll figure out a way to split the way he likes as soon as he sees splitting it one way. Thanks for the comment. – Display Name May 10 '13 at 12:15
0

I ended up using the native .net 4.5 handler for zip files and it ended up looking like this:

    Stream stream = new MemoryStream(file); // file as your byte[]
    using (ZipArchive archive = new ZipArchive(stream))
    {
        foreach (ZipArchiveEntry entry in archive.Entries)
        {
            if (entry.FullName.EndsWith(".tsv", StringComparison.OrdinalIgnoreCase))
            {
                using (stream = entry.Open())
                using (var reader = new StreamReader(stream)) {
                        string output = reader.ReadToEnd();
            }
        }       
    }

This allowed me to get the file even though the filename changes dynamically. Hope this helps someone!

Chris Jenkins
  • 719
  • 7
  • 20