Wednesday, October 26, 2011

FileStream and MemoryStream Conversions

Once upon a time, I was had some code like the following:

using (FileStream destStream = new FileStream(writePath, FileMode.Create))
{
 /* 3rd party lib writes to destStream */
}

Trouble was... the 3rd party call had the potential to throw an error. Of course, by then, the file at "writePath" had already been created. This was no good.

Lucky for me, the 3rd party call didn't require a FileStream for writing -- any old Stream implementation would work. So why not a MemoryStream? This way, if the write fails, all I've lost is some to-be-garbage-collected memory.

The following methods helped me move my data between FileStream and MemoryStream objects:

public static MemoryStream ReadFileToMemoryStream(string filePath)
{
 MemoryStream memStream = new MemoryStream();
 using (FileStream fileStream = File.OpenRead(filePath))
 {
  memStream.SetLength(fileStream.Length);
  fileStream.Read(memStream.GetBuffer(), 0, (int)fileStream.Length);
 }
 return memStream;
}

public static void WriteMemoryStreamToFile(MemoryStream memoryStream, string filePath)
{
 WriteMemoryStreamToFile(memoryStream, filePath, FileMode.Create);
}

public static void WriteMemoryStreamToFile(MemoryStream memoryStream, string filePath, FileMode fileMode)
{
 WriteMemoryStreamToFile(memoryStream, filePath, FileMode.Create, FileAccess.Write);
}

public static void WriteMemoryStreamToFile(MemoryStream memoryStream, string filePath, FileMode fileMode, FileAccess fileAccess)
{
 using (var fileStream = new FileStream(filePath, fileMode, fileAccess))
 {
  byte[] data = memoryStream.ToArray();
  fileStream.Write(data, 0, data.Length);
 }
}

Wednesday, October 19, 2011

PDF Viewing Options in Google Chrome


Google Chrome comes with its very own PDF viewer. However, as of the date of this post, this viewer cannot display most forms of embedded PDF annotations:
Currently, we do not support 100% of the advanced PDF features found in Adobe Reader, such as certain types of embedded media.
For a workaround, use the URL/address bar to navigate to "about:plugins"--you can also reach this screen from Options >> Under the Hood >> Content Settings >> Plug-ins >> Disable individual plug-ins...

From here, you can disable the "Chrome PDF Viewer" plug-in. Chrome should then download PDFs instead of attempting to open them.

Optionally, if you have Adobe Acrobat Reader installed, you can enable the Adobe Acrobat plug-in which will display embedded annotations correctly.

Friday, October 7, 2011

TightVNC Viewer: Save Connection

Son of a ...

<sigh>

I had been looking for this functionality forever! Right-click the TightVNC Viewer title bar to get all kinds of options, including "Save Connection" which lets you save the current connection info (including the password in plain text, just so you know--not that VNC passwords are very secure anyway, being sent unencrypted and whatnot).

Also in the menu: "Refresh Screen"--good for when an open connection gets broken/locked/frozen.

Thursday, October 6, 2011

Linq-to-Entities: EntityFunctions

Jefe: I have put many beautiful methods in the System.Data.Objects.EntityFunctions class, each of them filled with little suprises.
El Guapo: Many methods?
Jefe: Oh yes, many!
El Guapo: Would you say I have a plethora of methods?
Jefe: A what?
El Guapo: A *plethora*.
Jefe: Oh yes, you have a plethora.
El Guapo: Jefe, what is a plethora?
Jefe: Why, El Guapo?
El Guapo: Well, you told me I have a plethora. And I just would like to know if you know what a plethora is. I would not like to think that a person would tell someone he has a plethora, and then find out that that person has *no idea* what it means to have a plethora.
Jefe: Forgive me, El Guapo. I know that I, Jefe, do not have your superior intellect and education. But could it be that once again, you are angry at something else, and are looking to take it out on me?

I ran across this class while attempting some date comparisons with Linq-to-Entities. See, EF won't let you do this:

var orders = db.Orders.Where(order => order.CreatedOn.Date >= model.CreatedOnStart.Date);

It barfs during runtime with "The specified type member 'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.". But with EntityFunctions, we can still get what we need:

var orders = db.Orders.Where(order => EntityFunctions.TruncateTime(order.CreatedOn) >= EntityFunctions.TruncateTime(model.CreatedOnStart));

Handy indeed.