Read an Excel File from an Amazon S3 Bucket using c# - c#

I'm trying to read excel file from my S3 bucket. In the Response Stream, I am getting values like "PK\u0003\u0004\n\0\0\0\0\0�N0\0\0\0\0\t\0\0\0docProps". Could anyone help to map the stream to a data table or convert to string. And also when I see quick watch, the Read and Write Timeout has thrown some errors.
using (var _client = new AmazonS3Client(accKey, secKey, Amazon.RegionEndpoint.USEast1))
using (var response1 = await _client.GetObjectAsync("rrrrr","mmm.xls"))
using (var responseStream = response1.ResponseStream)
using (var reader = new StreamReader(responseStream))
{
var title = response1.Metadata["x-amz-meta-title"];
var contentType = response1.Headers["Content-Type"];
responseBody = reader.ReadToEnd();
string line;
string[] columns = null;
// Here the reader.ReadLine receiving only null values
while ((line = reader.ReadLine()) != null)
{
columns = line.Split(',');
string col1 = columns[0]; }
}

Related

Changing from MemoryStream to Stream in C#

Below is the code where I am passing memory stream and reading it and doing the necessary operation afterwards. Now the requirement has changed and instead of Memory stream, I will be passing Stream and that starts giving me error. I would like to know how can I handle the below method if contents returned here is of Stream type. Now it works fine when my contents is of type MemoryStream.
public async Task<string> ReadStream(string containerName, string digestFileName, string fileName, string connectionString)
{
string data = string.Empty;
string fileExtension = Path.GetExtension(fileName);
var contents = await DownloadBlob(containerName, digestFileName, connectionString);
if (fileExtension == ".gz")
{
using (var unzipper = new GZipStream(contents, CompressionMode.Decompress))
{
using (StreamReader reader = new StreamReader(unzipper, Encoding.UTF8))
{
data = reader.ReadToEnd();
}
}
}
else
{
data = Encoding.UTF8.GetString(contents.ToArray());
}
return data;
}
I'm going to assume the issue is contents.ToArray(), since Stream desn't have a ToArray() method.
In this case, you'll be better off using a StreamReader:
using (var reader = new StreamReader(contents))
{
data = reader.ReadToEnd();
}
StreamReader uses Encoding.UTF8 by default, but you can specify it explicitly if you want: new StreamReader(contents, Encoding.UTF8).
You'll note that you're already doing this a few lines above, to read from the unzipper stream.

Update file content on Google Drive with .NET

I want to add text in specific file content.
I used:
var file = await dataService.Files.Get(fileId).ExecuteAsync();
if (file == null)
{
throw new Exception(nameof(fileId));
}
using (var stream = new MemoryStream())
{
using (var sw = new StreamWriter(stream, Encoding.UTF8))
{
sw.Write(content); //there is a simple text like: bblablllbalblba
var request = dataService.Files.Update(file, fileId, stream, file.MimeType);
await request.UploadAsync();
}
}
but seems that content is not updated/written. I don't get any error.
Where I'm wrong ?

Read GZip Compressed file into datatable, then parse this data into another datatable

I have an application which reads and parses txt files into datatables (for upload later). Some of these files are compressed (GZip). I have gotten as far as to identify and read the compressed files into a datatable with a single row (basically a reproduction of the file). What I need to do now is parse this data (on "|") into another datatable (or in-situ in the same datatable if possible).
var ReadTable = new DataTable();
ReadTable.Columns.Add("Col1");
ReadTable.Columns.Add("Col2");
ReadTable.Columns.Add("Col3");
ReadTable.Columns.Add("Col4");
ReadTable.Columns.Add("Col5");
var ZipReadTable = new DataTable();
ZipReadTable.Columns.Add("ZipCol1");
if (isZip == false)
{
TextFieldParser parser = new TextFieldParser(FileLocationNameOriginal);
parser.TextFieldType = FieldType.Delimited;
parser.SetDelimiters("|");
//Read and parse all data in the file into a datatable
while (!parser.EndOfData)
{
ReadTable.Rows.Add(parser.ReadFields());
}
parser.Close();
}
else
{
using (Stream fileStream = File.OpenRead(FileLocationNameOriginal),
zippedStream = new GZipStream(fileStream, CompressionMode.Decompress))
{
using (StreamReader reader = new StreamReader(zippedStream))
{
string line;
while ((line = reader.ReadLine()) != null)
{
ZipReadTable.Rows.Add(reader.ReadLine());
}
}
}
}
I have tried converting the datatable to a string again, but the TextFieldParser isn't working with it (I think it is only for reading files?). Is the StreamWriter what I should be using? Thanks in advance StackOverFlow!
I figured out a fairly simple solution:
var ZipReadTable = new DataTable();
ZipReadTable.Columns.Add("ZipCol1");
using (Stream fileStream = File.OpenRead(FileName),
zippedStream = new GZipStream(fileStream, CompressionMode.Decompress))
{
using (StreamReader reader = new StreamReader(zippedStream))
{
while (!reader.EndOfStream)
{
ZipReadTable.Rows.Add(reader.ReadLine());
}
}
}
string[] ParsedLine = null;
string NotParsedLine = null;
char Delimiter = '|';
for (int k = 0; k < ZipReadTable.Rows.Count; k++)
{
NotParsedLine = ZipReadTable.Rows[k][0].ToString();
ParsedLine = NotParsedLine.Split(Delimiter);
OutputTable.Rows.Add(ParsedLine);
}
return (OutputTable);

Read last line from website without saving file on disk

I have a website with many large CSV files (up to 100,000 lines each). From each CSV file, I need to read the last line in the file. I know how to solve the problem when I save the file on disk before reading its content:
var url = "http://data.cocorahs.org/cocorahs/export/exportreports.aspx?ReportType=Daily&Format=csv&Date=1/1/2000&Station=UT-UT-24"
var client = new System.Net.WebClient();
var tempFile = System.IO.Path.GetTempFileName();
client.DownloadFile(url, tempFile);
var lastLine = System.IO.File.ReadLines(tempFile).Last();
Is there any way to get the last line without saving a temporary file on disk?
I tried:
using (var stream = client.OpenRead(seriesUrl))
{
using (var reader = new StreamReader(stream))
{
var lastLine = reader.ReadLines("file.txt").Last();
}
}
but the StreamReader class does not have a ReadLines method ...
StreamReader does not have a ReadLines method, but it does have a ReadLine method to read the next line from the stream. You can use it to read the last line from the remote resource like this:
using (var stream = client.OpenRead(seriesUrl))
{
using (var reader = new StreamReader(stream))
{
string lastLine;
while ((lastLine = reader.ReadLine()) != null)
{
// Do nothing...
}
// lastLine now contains the very last line from reader
}
}
Reading one line at a time with ReadLine will use less memory compared to StreamReader.ReadToEnd, which will read the entire stream into memory as a string. For CSV files with 100,000 lines this could be a significant amount of memory.
This worked for me, though the service did not return data (Headers of CSV only):
public void TestMethod1()
{
var url = "http://data.cocorahs.org/cocorahs/export/exportreports.aspx?ReportType=Daily&Format=csv&Date=1/1/2000&Station=UT-UT-24";
var client = new System.Net.WebClient();
using (var stream = client.OpenRead(url))
{
using (var reader = new StreamReader(stream))
{
var str = reader.ReadToEnd().Split('\n').Where(x => !string.IsNullOrEmpty(x)).LastOrDefault();
Debug.WriteLine(str);
Assert.IsNotEmpty(str);
}
}
}

Read the content of an xml file within a zip package

I am required to read the contents of an .xml file using the Stream (Here the xml file is existing with in the zip package). Here in the below code, I need to get the file path at runtime (here I have hardcoded the path for reference). Please let me know how to read the file path at run time.
I have tried to use string s =entry.FullName.ToString(); but get the error "Could not find the Path". I have also tried to hard code the path as shown below. however get the same FileNotFound error.
string metaDataContents;
using (var zipStream = new FileStream(#"C:\OB10LinuxShare\TEST1\Temp" + "\\"+zipFileName+".zip", FileMode.Open))
using (var archive = new ZipArchive(zipStream, ZipArchiveMode.Read))
{
foreach (var entry in archive.Entries)
{
if (entry.Name.EndsWith(".xml"))
{
FileInfo metadataFileInfo = new FileInfo(entry.Name);
string metadataFileName = metadataFileInfo.Name.Replace(metadataFileInfo.Extension, String.Empty);
if (String.Compare(zipFileName, metadataFileName, true) == 0)
{
using (var stream = entry.Open())
using (var reader = new StreamReader(stream))
{
metaDataContents = reader.ReadToEnd();
clientProcessLogWriter.WriteToLog(LogWriter.LogLevel.DEBUG, "metaDataContents : " + metaDataContents);
}
}
}
}
}
I have also tried to get the contents of the .xml file using the Stream object as shown below. But here I get the error "Stream was not readable".
Stream metaDataStream = null;
string metaDataContent = string.Empty;
using (Stream stream = entry.Open())
{
metaDataStream = stream;
}
using (var reader = new StreamReader(metaDataStream))
{
metaDataContent = reader.ReadToEnd();
}
Kindly suggest, how to read the contents of the xml with in a zip file using Stream and StreamReader by specifying the file path at run time
Your section code snippet is failing because when you reach the end of the first using statement:
using (Stream stream = entry.Open())
{
metaDataStream = stream;
}
... the stream will be disposed. That's the point of a using statment. You should be fine with this sort of code, but load the XML file while the stream is open:
XDocument doc;
using (Stream stream = entry.Open())
{
doc = XDocument.Load(stream);
}
That's to load it as XML... if you really just want the text, you could use:
string text;
using (Stream stream = entry.Open())
{
using (StreamReader reader = new StreamReader(stream))
{
text = reader.ReadToEnd();
}
}
Again, note how this is reading before it hits the end of either using statement.
Here is a sample of how to read a zip file using .net 4.5
private void readZipFile(String filePath)
{
String fileContents = "";
try
{
if (System.IO.File.Exists(filePath))
{
System.IO.Compression.ZipArchive apcZipFile = System.IO.Compression.ZipFile.Open(filePath, System.IO.Compression.ZipArchiveMode.Read);
foreach (System.IO.Compression.ZipArchiveEntry entry in apcZipFile.Entries)
{
if (entry.Name.ToUpper().EndsWith(".XML"))
{
System.IO.Compression.ZipArchiveEntry zipEntry = apcZipFile.GetEntry(entry.Name);
using (System.IO.StreamReader sr = new System.IO.StreamReader(zipEntry.Open()))
{
//read the contents into a string
fileContents = sr.ReadToEnd();
}
}
}
}
}
catch (Exception)
{
throw;
}
}

Categories