Read Text from large txt file inside zip file - c#

I am trying to read all text of a TXT file that is inside a ZIP file. The unzipped file has 1GB.
The following code does not throw errors but never ends, is there any way to speed up the process?
var fileText = string.Empty;
using (var file = File.OpenRead(System.Configuration.ConfigurationManager.AppSettings["zipPath"]))
using (var zip = new ZipArchive(file, ZipArchiveMode.Read))
{
using (var stream = zip.Entries.First().Open())
{
using (var streamReader = new StreamReader(stream))
{
try
{
while (streamReader.Peek() >= 0)
{
var line = streamReader.ReadLine();
fileText = fileText + line;
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
}

Try:
var fileText = string.Empty;
using (var file = File.OpenRead(System.Configuration.ConfigurationManager.AppSettings["zipPath"]))
using (var zip = new ZipArchive(file, ZipArchiveMode.Read))
{
using (var stream = zip.Entries.First().Open())
{
using (var streamReader = new StreamReader(stream))
{
try
{
while (!streamReader.EndOfStream)
{
var line = streamReader.ReadLine();
fileText = fileText + line;
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
}
However, consider using ReadAllLines for easiest solution.

Related

How can I put a txt file (that is in a zip file) in a string, without extracting the zip?

Here is my code:
using (ZipArchive zip = ZipFile.Open(path, ZipArchiveMode.Read))
foreach (ZipArchiveEntry entry in zip.Entries)
if (entry.Name == "example.txt")
entry.ExtractToFile(???);
The ??? is what I'm having trouble with. I want it to go to a string, not a file on disk.
The first code will get you an Array of String, as if it were "ReadAllLines". The second one will get you a single String (as if it were "ReadAllText").
List<string> lines = new List<string>();
using (ZipArchive archive = ZipFile.OpenRead(zipPath))
{
foreach (ZipArchiveEntry entry in archive.Entries.Where(e_ => e_.Name == "example.txt"))
{
Stream stream = entry.Open();
using (var sr = new StreamReader(stream, Encoding.UTF8))
{
string line;
while ((line = sr.ReadLine()) != null)
{
lines.Add(line);
}
}
}
}
string[] result = lines.ToArray();
string result = "";
using (ZipArchive archive = ZipFile.OpenRead(zipPath))
{
foreach (ZipArchiveEntry entry in archive.Entries.Where(e_ => e_.Name == "example.txt"))
{
Stream stream = entry.Open();
using (var sr = new StreamReader(stream, Encoding.UTF8))
{
result = sr.ReadToEnd();
}
}
}

getting error in Merge PDF's In C# using Itextsharpdll

when i am trying the merge the PDF's in C# using itextsharp, i used below code It worked for 2 or 3 times. But after that Output file is creating with 0 kb, when i am trying open file it showing file is in use or already open by other. Please help if missed anything Thanks in Adavance.
iTextSharp.text.pdf.PdfReader reader = null;
PdfImportedPage page = null;
FileStream stream = null;
Document pdfDoc = null;
try
{
using(pdfDoc = new Document())
stream = new FileStream(targetPDF, FileMode.Create);
{
using (PdfCopy pdf = new PdfCopy(pdfDoc, stream))
{
pdfDoc.Open();
var files = Directory.GetFiles(sourceDir);
foreach (string file in files)
{
reader = new iTextSharp.text.pdf.PdfReader(file);
for (int i = 0; i < reader.NumberOfPages; i++)
{
page = pdf.GetImportedPage(reader, i + 1);
pdf.AddPage(page);
}
pdf.FreeReader(reader);
reader.Close();
}
}
}
}
catch (Exception ex)
{
if (reader != null)
{
reader.Close();
}
}
enter image description here
I don't know what happen with your code but I can give a function (I'm using in my project working 100%) that merge a list of file
private bool MergePDFs(IEnumerable<string> fileNames, string targetPdf)
{
bool merged = true;
using (FileStream stream = new FileStream(targetPdf, FileMode.Create))
{
Document document = new Document();
PdfCopy pdf = new PdfCopy(document, stream);
PdfReader reader = null;
try
{
document.Open();
foreach (string file in fileNames)
{
System.Threading.Thread.Sleep(1500);
reader = new PdfReader(file);
pdf.AddDocument(reader);
reader.Close();
}
}
catch (Exception)
{
merged = false;
if (reader != null)
{
reader.Close();
}
}
finally
{
if (document != null)
{
document.Close();
}
}
}
return merged;
}
so for fileNames : you give the list of your files (construct a list
from your folder by listing files)
targetPdf is the outPut file name

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;
}
}

Trying to merge two zip files into 1 using c# and Ionic.dll

Here is the code
ZipFile zipnew = ZipFile.Read(strPath);
if (!File.Exists(path))
{
using (ZipFile zip = new ZipFile())
{
zip.Save(path);
}
}
string tmpname = fpath + "\\abtemp";
ZipFile zipold = ZipFile.Read(path);
foreach (ZipEntry zenew in zipnew)
{
string flna = zenew.FileName.ToString();
string tfn = '#' + flna.Replace("\\", "/");
Stream fstream = File.Open(tmpname, FileMode.OpenOrCreate, FileAccess.Write);
zenew.Extract(fstream);
string l = fstream.Length.ToString();
fstream.Close();
using (StreamReader sr = new StreamReader(tmpname))
{
var zn = zipold.UpdateEntry(flna, sr.BaseStream);
sr.Close();
sr.Dispose();
fstream.Dispose();
}
}
zipnew.Dispose();
File.Delete(tmpname);
File.Delete(strPath);
The problem is: I get no error and there are no files merged into zipold from zipnew.
Zipold is a blank zip file
You're code isn't 100% clear to me, the variable tfn doesn't seem to be used and i'm not quite following with all the disposes / deletes. But on the bright side i did get your code working, the main problem was that you're not calling the save method of zipold.
string path = "d:\\zipold.zip";
ZipFile zipnew = ZipFile.Read("d:\\zipnew.zip");
if (!File.Exists(path))
{
using (ZipFile zip = new ZipFile())
{
zip.Save(path);
}
}
string tmpname = "d:" + "\\temp.dat";
ZipFile zipold = ZipFile.Read(path);
foreach (ZipEntry zenew in zipnew)
{
string flna = zenew.FileName.ToString();
//string tfn = '\\' + flna.Replace("\\", "/"); useless line
Stream fstream = File.Open(tmpname, FileMode.OpenOrCreate, FileAccess.Write);
zenew.Extract(fstream);
string l = fstream.Length.ToString();
fstream.Close();
using (StreamReader sr = new StreamReader(tmpname))
{
var zn = zipold.UpdateEntry(flna, sr.BaseStream);
zipold.Save();
sr.Close();
sr.Dispose();
fstream.Dispose();
}
}
zipnew.Dispose();
static void Main(string[] args)
{
try
{
using (ZipFile zip1 = new ZipFile())
{
zip1.AddFile(#"SCAN0002.PDF");
zip1.AddFile(#"SCAN0003.PDF");
zip1.Save("SCAN0002.ZIP");
}
using (ZipFile zip2 = new ZipFile())
{
zip2.AddFile(#"SCAN0004.PDF");
zip2.AddFile(#"SCAN0005.PDF");
zip2.AddFile(#"SCAN0006.PDF");
zip2.Save("SCAN0003.ZIP");
}
ZipFile z3 = new ZipFile().Read2(File.ReadAllBytes("SCAN0002.ZIP"));
ZipFile z4 = new ZipFile().Read2(File.ReadAllBytes("SCAN0003.ZIP"));
using (ZipFile zip3 = new ZipFile())
{
zip3.Marge(z3).Marge(z4);
zip3.Save("SCAN0004.ZIP");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
and extend class
public static class ZipFileExt
{
public static ZipFile Read2(this ZipFile item, byte[] data)
{
return ZipFile.Read(new MemoryStream(data));
}
public static ZipFile Marge(this ZipFile item, ZipFile file)
{
foreach (var entry in file)
item.AddEntry(entry.FileName, entry.Extract2Byte());
return item;
}
public static byte[] Extract2Byte(this ZipEntry entry)
{
using (var ms = new MemoryStream())
{
entry.Extract(ms);
return ms.ToArray();
}
}
}
\P/
http://www.youtube.com/watch?v=Y7dRBmMsevk&list=RD02xcFzsvnMmXY

Writing a file adding random characters to start of each line

I'm overwriting a file using C# in Windows Phone 7. When I do this a seemingly random character is added to the start of each line.
Why is this happening?
Code:
public static bool overwriteFile(string filename, string[] inputArray)
{
try
{
IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication();
FileStream stream = store.OpenFile(filename, FileMode.Create);
BinaryWriter writer = new BinaryWriter(stream);
foreach (string input in inputArray)
{
writer.Write(input + "\n");
}
writer.Close();
return true;
}
catch (IOException ex)
{
return false;
}
}
Lodaing Code:
public static Idea[] getFile(string filename)
{
try
{
IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication();
string fileContents = null;
if (store.FileExists(filename)) // Check if file exists
{
IsolatedStorageFileStream save = new IsolatedStorageFileStream(filename, FileMode.Open, store);
StreamReader streamReader = new StreamReader(save);
fileContents = streamReader.ReadToEnd();
save.Close();
}
string[] lines = null;
if (fileContents != null)
{
lines = fileContents.Split('\n');
}
Idea[] ideaList = null;
if (lines != null)
{
ideaList = new Idea[lines.Length];
for (int i = 0; i < lines.Length; i++)
{
ideaList[i] = new Idea(lines[i].TrimEnd('\r'));
}
}
return ideaList;
}
catch (IOException ex)
{
return null;
}
}
The random character is a length prefix; see http://msdn.microsoft.com/en-us/library/yzxa6408.aspx.
You should be using some type of TextWriter to write strings to the file; NOT a BinaryWriter.
A StreamWriter might be the best and then you could use the WriteLine method.
Instead of using '\n', try using Environment.NewLine
You are using a BinaryWriter to write, and a TextReader to read. Change your write code to use a StreamWriter (which is a TextWriter) instead of a BinaryWriter. This will also get you the WriteLine method that Naveed recommends.
try changing this
writer.Write(input + "\n");
to
writer.WriteLine(input);

Categories