DotnetZip problems with silverlight(lightswitch) - c#

so I am having this problem that I can't figure out at the moment. I have already Grabbed the patched Ionic.zip from "http://dotnetzip.codeplex.com/workitem/14049".
I tested my code on a non-silverlight project using the ionic.zip for regular c# and its working. But when modifying the code for silverlight(lightswitch) I keep on getting the 'IBM437' Error.
Here is what my code looks like
void selectFileWindow_Closed(object sender, EventArgs e)
{
SelectFileWindow selectFileWindow = (SelectFileWindow)sender;
string selectFileStream = sender.ToString();
var parsedString = selectFileStream.Split(',');
if (selectFileWindow.DialogResult == true && (selectFileWindow.myStream != null))
{
foreach (FileStream myZippedStream in selectFileWindow.myStream)
{
string zippedLocation = myZippedStream.Name;
var parsedLocation = zippedLocation.Split('\\');
string fileName = parsedLocation[parsedLocation.Length - 1];
//filename is equal to something like "myfile.zip"
// We want to turn that to "myfile.txt)
fileName = (fileName.Substring(0, fileName.Length - 3)) + "txt";
using (FileStream fs = File.Create("c:\\temp\\gftTempFile.txt"))
{
using (var ms = new MemoryStream())
{
//ReadOptions myOptions = new ReadOptions();
//myOptions.Encoding = System.Text.Encoding.UTF8;
//using (ZipFile myZip = ZipFile.Read(myZippedStream, myOptions))
// I have tried using the commentted code but it gives the same error
using (ZipFile myZip = ZipFile.Read(myZippedStream))
{
ZipEntry myEntry = myZip[fileName];
myEntry.Extract(ms);
ms.WriteTo(fs);
fs.Close();
ImportGift.importGift(fs, this.DataWorkspace);
try
{
fs.Close();
fs.Dispose();
ms.Close();
ms.Dispose();
File.Delete("c:\\temp\\gftTempFile.txt");
}
catch { }
}
}
}
}
doneLoading = true;
}
}

I'm not sure error the "IBM437" is, or where in your code that happens, but I do know that SilverLight doesn't allow you to access the file system from code without showing a SelectFileWindow first.
In other words: your lines that have a hardcoded "c:\temp\gftTempFile.txt" will definitely not work in a SL app without elevated permissions.

Related

C# WebClient Downloads empty file

I'm working on an app that uses Bing's API to search and download images.
Bing's API provides a set of image links and I iterate over them and download each one.
The problem that I'm having is that sometimes the downloaded file size is 0Kb.
I assume that happens because WebClient first creates the filename and then tries to write to it. So when it can't write to it for some reason this happens. The problem is that it happens without throwing an exception so my 'Catch' statement can't catch this and delete the file.
public void imageFetcher(string performerName, int maxNumberOfImages, RichTextBox richTextBox)
{
string performersDirPath = Environment.CurrentDirectory + #"\Performers\";
string performerPath = performersDirPath + performerName + #"\";
if (!Directory.Exists(performersDirPath))
{
Directory.CreateDirectory(performersDirPath);
}
if (!Directory.Exists(performerPath))
{
Directory.CreateDirectory(performerPath);
}
// Searching for Images using bing api
IEnumerable<Bing.ImageResult> bingSearch = bingImageSearch(performerName);
int i = 0;
foreach (var result in bingSearch)
{
downloadImage(result.MediaUrl, performerPath + performerName + i + ".jpg",richTextBox);
i++;
if (i == maxNumberOfImages)
{
break;
}
}
}
The download method:
public void downloadImage(string imgUrl, string saveDestination, RichTextBox richTextBox)
{
if (File.Exists(saveDestination))
{
richTextBox.ForeColor = System.Drawing.Color.Red;
richTextBox.AppendText("The File: " + saveDestination + "Already exists");
}
else
{
try
{
using (WebClient client = new WebClient())
{
client.DownloadFileCompleted += new AsyncCompletedEventHandler(((sender, e) => downloadFinished(sender, e, saveDestination , richTextBox)));
Uri imgURI = new Uri(imgUrl, UriKind.Absolute);
client.DownloadFileAsync(imgURI, saveDestination);
}
}
catch (Exception e)
{
richTextBox.AppendText("There was an exception downloading the file" + imgUrl);
richTextBox.AppendText("Deleteing" + saveDestination);
File.Delete(saveDestination);
richTextBox.AppendText("File deleted!");
}
}
}
This happens also when I try to wait for the client to finish using:
client.DownloadFileAsync(imgURI, saveDestination);
while (client.IsBusy)
{
}
Can anyone please tell me what I'm doing wrong?
In other simular question the solution was to keep the Webclient instance open until download is finished.. I'm doing this with this loop:
while (client.IsBusy){}
Yet the results are the same.
Update:
I resorted to not use webclient, instead I used this code:
try
{
byte[] lnBuffer;
byte[] lnFile;
using (BinaryReader lxBR = new BinaryReader(stream))
{
using (MemoryStream lxMS = new MemoryStream())
{
lnBuffer = lxBR.ReadBytes(1024);
while (lnBuffer.Length > 0)
{
lxMS.Write(lnBuffer, 0, lnBuffer.Length);
lnBuffer = lxBR.ReadBytes(1024);
}
lnFile = new byte[(int)lxMS.Length];
lxMS.Position = 0;
lxMS.Read(lnFile, 0, lnFile.Length);
}
using (System.IO.FileStream lxFS = new FileStream(saveDestination, FileMode.Create))
{
lxFS.Write(lnFile, 0, lnFile.Length);
}
This solves the problem almost complelty, there are still one or two 0KB files but I assume it's because of network errors.
To see possible exceptions - try changing DownloadFileAsync to just DownloadFile - my problem was "Can not create SSL/TLS secure channel". Hope this will help someone.

OutOfMemoryException error in Loop

I am trying to create a Windows app which uploads files to FTP. Essentially, it looks for .jpeg files in a given folder, it reads through the barcodes found in the .jpg files before uploading it into the FTP server, and entering the URL into the database for our records.
As there will be multiple files at any given time in the folder, I am essentially trying to read them in a loop, and process them accordingly. However, I get an OutOfMemoryException whenever the loop starts again. I am trying to figure out what I'm doing wrong here. I have appended my code below:
private void btnProcess_Click(object sender, RoutedEventArgs e)
{
podPath = Directory.GetFiles(DestPath, "*.jpg");
List<string> scans = new List<string>(podPath.Length);
List<string> badscans = new List<string>();
byte[] imageBytes;
string filename, result;
POD conpod = new POD();
OTPOD otpod = new OTPOD();
ConsignmentObj scanJob;
//Pickup OTScan;
//Consolidate ccv;
for (int i = 0; i < podPath.Count(); i++ )
{
filename = podPath[i].ToString();
using (Bitmap bm = (Bitmap)Bitmap.FromFile(filename))
{
var results = barcodeReader.Decode(bm);
result = results.ToString();
bm.Dispose();
}
if (result != null)
{
//if barcode can be read, we throw the value into the database to pull out relevant information
if (result.Contains(ConNotePrefix))
{
#region Consignments
scanJob = getCon(result.ToString());
final = ImageFolder + "\\" + result.ToString() + ".jpg";
using (System.Drawing.Image img = System.Drawing.Image.FromFile(filename))
{
MemoryStream ms = new MemoryStream();
try
{
img.Save(ms, ImageFormat.Jpeg);
imageBytes = ms.ToArray();
img.Dispose();
}
finally
{
ms.Flush();
ms.Close();
ms.Dispose();
}
}
lock (filename)
{
if (System.IO.File.Exists(filename))
{
File.Delete(filename);
}
}
using (var stream = File.Create(final)) { }
File.WriteAllBytes(final, imageBytes);
File.Delete(filename);
conpod.ConsignmentID = scanJob.ConsignmentID;
conpod.UserID = 1;
conpod.Location = ftpUrl + "//" + result.ToString() + ".jpg";
conpod.rowguid = Guid.NewGuid();
UploadFilesToFtp(ftpUrl, ftpUser, ftpPass, final, result.ToString() + ".jpg");
insertPOD(conpod);
scans.Add(result.ToString());
#endregion
}
}
else
{
badscans.Add(filename);
}
}
this.lbScans.ItemsSource = scans;
this.lbBadScans.ItemsSource = badscans;
}
The FTP method, UploadFilesToFtp(x, x, x, x, x, x) is not a problem here. All feedback will be much appreciated.
An OutOfMemoryException can also be thrown by the method FromFile of the Image class when
The file does not have a valid image format.
or
GDI+ does not support the pixel format of the file.
So i think there is a problem with one of your image files you are reading. One solution is to catch the OutOfMemoryException and adding the file to the badscans.
try{
using (Bitmap bm = (Bitmap)Bitmap.FromFile(filename)) {
var results = barcodeReader.Decode(bm);
result = results.ToString();
bm.Dispose();
}
}
catch(OutOfMemoryException) {
badscans.add(filename);
}

writing to text file does not alway work/save

i have this code that compares two text files and write the difference to a log file but for some reason the log.txt file is some times blank even when is test with some lines starting with a * these are not always written either do I have to save the text file when finished writing although this does not explain why sometimes it works any help would be great
private void compare()
{
string FilePath = #"c:\snapshot\1.txt";
string Filepath2 = #"c:\snapshot\2.txt";
int counter = 0;
string line;
string line2;
var dir = "c:\\snapshot\\log.txt";
using (FileStream fs = File.Create(dir))
{
fs.Dispose();
}
StreamWriter dest = new StreamWriter(dir);
if (File.Exists(FilePath) & File.Exists(Filepath2))
{
// Read the file and display it line by line.
using (var file = File.OpenText(FilePath))
using (var file2 = File.OpenText(Filepath2))
{
while (((line = file.ReadLine()) != null & (line2 = file2.ReadLine()) != null))
{
if (line.Contains("*"))
{
dest.WriteLine(line2);
}
else if (!line.Contains(line2))
{
dest.WriteLine(line2);
}
counter++;
}
}
}
dest.Close();
}
Everything left in the buffer should be written out once you hit the close statement on your StreamReader. If you are missing stuff then it might be that you aren't reaching that line for some reason (i.e. you crash). Also, if you are trying to look at the file while it's being written (i.e. while the program is still running), you won't necessarily see everything (since it hasn't closed).
Generally, it's better to use a using statement with the StreamReader. That should ensure that it always gets closed.
private void compare()
{
string FileName1 = #"c:\snapshot\1.txt";
string FileName2 = #"c:\snapshot\2.txt";
string FileNameOutput = #"c:\snapshot\log.txt"; //dir ???
int counter = 0; // um what's this for you aren't using it.
using (FileStream fso = new FileStream(FileNameOutput, FileMode.Create, FileAccess.Write))
{
TextWriter dest = new StreamWriter(fso);
using(FileStream fs1 = new FileStream(FileName1, FileMode.Open, FileAccess.Read))
{
using (FileStream fs2 = new FileStream(FileName2, FileMode.Open, FileAccess.Read))
{
TextReader firstFile = new StreamReader(fs1);
TextReader secondFile = new StreamReader(fs2);
while (((line1 = firstFile.ReadLine()) != null & (line2 = secondFile.ReadLine()) != null))
{
if ((line1.Contains("*") || (!line1.Contains(line2)))
{
dest.Write(line2); // Writeline would give you an extra line?
}
counter++; //
}
}
}
fso.Flush();
}
I commend the overloads of FileStream to you. Do it the way I have and the code will crash at the point you instance the stream if the user running it doesn't have all the required permissions. It's a nice way of showing what you intend, and what you don't.
PS You do know contains is case and culture sensitive?
Not sure if I'm understanding your comparing logic right, but as long as I separated comparing from whole code you can adjust it to your own needs:
public static void WriteDifferences(string sourcePath, string destinationPath, string differencesPath)
{
var sourceLines = File.ReadAllLines(sourcePath).ToList();
var destinationLines = File.ReadAllLines(destinationPath).ToList();
// make lists equal size
if (sourceLines.Count > destinationLines.Count)
{
destinationLines.AddRange(Enumerable.Range(0, sourceLines.Count - destinationLines.Count).Select(x => (string)null));
}
else
{
sourceLines.AddRange(Enumerable.Range(0, destinationLines.Count - sourceLines.Count).Select(x => (string)null));
}
var differences = sourceLines.Zip(destinationLines, (source, destination) => Compare(source, destination));
File.WriteAllLines(differencesPath, differences.Where(x => x != null));
}
private static string Compare(string source, string destination)
{
return !source.Contains(destination) || source.Contains("*") ? destination : null;
}

File.Move throws error when used with BackgroundWorkerr in C#

Solved
I figured out that the GetNewFolderNameBasedOnDate method internally didn't close the file. I have that method fixed and it working normal now
I am trying to move selected files from one folder to another using BackgroundWorker process in C#. Here is my DoWork() method that determine whether to move the files or just copy. My File.Move() throws an exception that "The process cannot access the file because it is being used by another process". I tried different methods as mentioned in the threads here in stackoverflow.
private void FileProcessor_DoWork(object sender, DoWorkEventArgs e)
{
// Copy files
long bytes = 0;
string destSubFolder = String.Empty;
string destFile = string.Empty;
foreach (FileInfo file in oSettings.SourceFiles)
{
try
{
this.BeginInvoke(OnChange, new object[] { new UIProgress(file.Name, bytes, oSettings.MaxBytes) });
destSubFolder = GetNewFolderNameBasedOnDate(file);
//Create a new subfolder under the current active folder
string newPath = Path.Combine(oSettings.TargetFolder, destSubFolder);
// Create a new target folder, if necessary.
if (!System.IO.Directory.Exists(newPath))
{
System.IO.Directory.CreateDirectory(newPath);
}
destFile = Path.Combine(oSettings.TargetFolder, destSubFolder, file.Name);
if (chkDeleteSourceFiles.Checked)
{
FileInfo f = new FileInfo(file.FullName);
if (f.Exists)
{
File.Move(file.FullName, destFile);
}
}
else
{
File.Copy(file.FullName, destFile, true);
}
//Thread.Sleep(2000);
}
catch (Exception ex)
{
UIError err = new UIError(ex, file.FullName);
this.Invoke(OnError, new object[] { err });
if (err.result == DialogResult.Cancel) break;
}
bytes += file.Length;
}
}
I tried to delete the files in "RunWorkerCompleted" method too. But didn't resolve the problem. This fails when it tries to delete the last file in the list.
private void FileProcessor_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Operation completed, update UI
ChangeUI(false);
foreach (FileInfo file in oSettings.SourceFiles)
{
File.Delete(file.FullName);
}
}
GetNewFolderNameBasedOnDate() calls GetDateTaken() which was the culprit. Earlier I didn't use FileStream object but used Image myImage = Image.FromFile(filename); I didn't know that Image.FromFile locks the file.
private DateTime GetDateTaken(string fileName)
{
try
{
using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
Image myImage = Image.FromStream(fs);
PropertyItem propItem = myImage.GetPropertyItem(36867);
DateTime dtaken;
//Convert date taken metadata to a DateTime object
string sdate = Encoding.UTF8.GetString(propItem.Value).Trim();
string secondhalf = sdate.Substring(sdate.IndexOf(" "), (sdate.Length - sdate.IndexOf(" ")));
string firsthalf = sdate.Substring(0, 10);
firsthalf = firsthalf.Replace(":", "-");
sdate = firsthalf + secondhalf;
dtaken = DateTime.Parse(sdate);
return dtaken;
}
}
catch (Exception ex)
{
return DateTime.Now;
}
}
Instead of creating new FileInfo objects, keep it simple and re-use the same one. I suspect the problem is that you have multiple references to the same file in your code, which prevents it from being removed. Try something like this to move it:
if (chkDeleteSourceFiles.Checked)
{
if (file.Exists)
{
file.MoveTo(destFile);
}
}
My guess is that it is the BeginInvoke call to OnChange and the new UIProgress() object that is holding onto the file. Does UIProgress open the file? You could try just using Invoke() and see if that helps.

Error "EOF In Header" with version SharpZipLib 0.86.0.518

I use VS 2008 SP1 in Windows XP.
I have updated ICSharpCode.SharpZipLib.dll from older 0.85.4.369 to new 0.86.0.518.
I have been using it successfully for older 0.85.4.369.
I have been able to zip and unzip both files and folders without a problem - well, until now.
But now, I get error "EOF In Header" when read a ZIP file that I have generated using ICSharpCode.SharpZipLib.dll too.
My code C# is the same, no changes about it.
Fails: theEntry = z.GetNextEntry();
public static string LeerEtiquetaEmpaquetado(string zipFic)
{
ZipInputStream z = null;
DatosEmpaquetado datEmp;
try
{
z = new ZipInputStream(File.OpenRead(zipFic));
ZipEntry theEntry;
do
{
theEntry = z.GetNextEntry();
if (theEntry != null)
{
if (theEntry.Name.EndsWith("empaquetado.xml"))
{
using (MemoryStream memWrt = new MemoryStream())
{
int size = 2048;
byte[] data = new byte[2048];
do
{
size = z.Read(data, 0, data.Length);
if ((size > 0))
{
memWrt.Write(data, 0, size);
}
else
{
break;
}
} while (true);
datEmp = LeerEmpaquetado(memWrt);
return datEmp.Etiqueta;
}
break;
}
}
else
{
break;
}
} while (true);
return null;
}
catch (Exception exc)
{
System.Diagnostics.Trace.WriteLine("Excepción: " + exc.Message);
System.Diagnostics.Trace.WriteLine(exc.StackTrace);
throw;
}
finally
{
if (z != null)
{
z.Close();
z.Dispose();
}
}
}
The ICSharpCode.SharpZipLib.dll ( 0.86.0.518 ) seems unable to open the ZIPs it just created.
Very Strange thing is:
The newly-created files open just fine in WinRAR.
ZIP files created with previous versions of the DLL open just fine with the new DLL.
Code for ZIP file:
public static void EmpaquetarProyecto(string dirOutput, string nombre, string dirDestino)
{
string dirActual = Environment.CurrentDirectory;
Environment.CurrentDirectory = dirOutput;
string[] fileNames = Directory.GetFiles(".", "*.*", SearchOption.AllDirectories);
try
{
Crc32 objCrc32 = new Crc32();
ZipOutputStream strmZipOutputStream;
nombre = Path.Combine(dirDestino, nombre + ".zip");
strmZipOutputStream = new ZipOutputStream(File.Create(nombre));
strmZipOutputStream.SetLevel(6);
foreach (string aux in fileNames)
{
string strFile = aux;
if (strFile.StartsWith(".\\"))
{
strFile = strFile.Substring(2);
}
FileStream strmFile = File.OpenRead(strFile);
byte[] abyBuffer = new byte[(Convert.ToInt32(strmFile.Length))];
strmFile.Read(abyBuffer, 0, abyBuffer.Length);
ZipEntry theEntry = new ZipEntry(strFile);
FileInfo fi = new FileInfo(strFile);
theEntry.DateTime = fi.LastWriteTime;
theEntry.Size = strmFile.Length;
strmFile.Close();
objCrc32.Reset();
objCrc32.Update(abyBuffer);
theEntry.Crc = objCrc32.Value;
strmZipOutputStream.PutNextEntry(theEntry);
strmZipOutputStream.Write(abyBuffer, 0, abyBuffer.Length);
}
strmZipOutputStream.Finish();
strmZipOutputStream.Close();
}
finally
{
Environment.CurrentDirectory = dirActual;
}
}
Perhaps error is aboutCRC, I think.
Any ideas about it? any changes in my code ?
edit: If delete code about CRC , it works, but why ??

Categories

Resources