Intercepting a filestream...Impossible? - c#

No doubt this isn't possible but i would like to see if anyone has an ingenious suggestion. We have a third party assembly which can output an image stored internally within a bespoke database to file using an internal method 'SaveToFile', an example:
3rdParty.Scripting.ImageManager man = new 3rdParty.Scripting.ImageManager("ref");
3rdParty.Scripting.Image itemImg = man.GetImage(orderNumber);
itemImg.SaveToFile("c:\file.jpg")
ItemImg.SaveToFile has no return type and just creates a bitmap internally and writes that to a filestream. We have absolutely no access to the compiled method.
What i need to do is somehow intercept the filestream and read the bitmap, i know this probably isn't possible but i'm no absolute expert so wanted to see if there is a magical way to do this.
If all else fails i'll save the file then read it back, i just want to avoid saving to disk where i might be able to obtain the data directly and eventually convert that to a base64 string value.

Unfortunately unless the 3rd party library provides a SaveToStream method where you could provide the stream from the outside there's no way to achieve what you are after. You will have to save the contents to a temporary file and then read the contents back.
That's why it's usually best practice when designing a library to provide methods taking Streams as I/O parameters as this would give the consumer the control of whether he wants to save it to a file, memory or network stream.

Related

Skip duplicated files on copy

I am moving files from one folder to another destination1 to destination2 however if destination2 already has a copy of the file from destination1 I would like to simply skip and continue the copy process rather than overwriting which will take a longer process.
I have already tried: FileSystem.CopyFile(destination1,destination2, true);which will overwrite the file. Is there anyway I could get some assistance on accomplishing this please.
You can use File.Exists method to check whether the file already exists:
if(!File.Exists(destination2))
{
// copy file
}
You told that you want to avoid overwriting, then why you did pass true for the last parameter?
Have you tried passing false?
FileSystem.CopyFile(destination1, destination2, false);
As side note, remember that the system will never compare two files in order to know if they are identical and then skip the copy.
If you want to accomplish this behavior, then you have to implement it by yourself, but it would usually be heavier than simply overwriting, due to the need to fully read the destination file, unless you implement some caching mechanism or the destination file is already (and still) in system cache.
Regards,
Daniele.

Suppress Console.WriteLine for portion of program

For some reason unknown to me, the developer of a library I am using has decided to Console.WriteLine tons of information whenever a method is called within the library, essentially explaining every step of what is going on.
This is fine, but during development I don't need to be seeing this all of the time, so my question is can I suppress Console.WriteLine from being used when I don't want it to be? I still wish to be able to see my own Console.WriteLines, but not the ones within the Library.
Goes without saying I do not have source for the library.
Regards,
AK
You can use Console.SetOut to redirect Console.Out to something of your choosing (e.g. something that discards all input) before calling into that library and then do the same to set the original value back. It's going to be awkward to do that all the time though.
To make things a bit more manageable, you can create another class that implements IDisposable and use it like this:
using(new StandardOutSink()) {
// call into the third party library
}
The constructor of StandardOutSink (which you need to write) would redirect the output stream to a specially-crafted TextWriter (which you also need to write) and then the Dispose method would set it back to the original stream.

Determining content from StreamReader?

I am forced to work with a crappy 3rd party API where there is no consistency with the return type. So I submit a programmatic web request, grab the Stream back and the underlying content might be an error message (worse still because it can be either raw text, or xml they return) or it returns a binary file. I have no means of knowing what format to expect with any given request so I need a way to introspect this at runtime.
How should I go about tackling this? The stream is non-seekable so I can't do anything other than read it. I usually try not to use exception handling for flow control but it seems like that might be the best way to handle it. Always treat it like it should be the expected binary file type and if anything blows up then catch the exception and try to extract what should be an error message
One thing that comes to mind is to examine the first x number of bytes in the stream. If the first bit is well formed xml, then it's probably xml. The problem is trying to determine the difference between raw text or binary.

Is it possible to restrict/require certain capabilities in a Stream parameter?

I'm writing an application that creates catalogs of files. Currently the catalog information is stored in an XML file, but I'm trying to abstract the interface to a catalog to allow for other future storage mechanisms such as a single ZIP file, SQL server, or HTTP server. So rather than returning a file path the abstract Catalog class returns files as byte Streams. Thus allowing the source of a file to be a disk, but also for files coming from a database or a web server. See my previous related question.
However, the root Stream class includes Streams with different capabilities. Some streams can only be read, others can only be written to. Still some streams support seeking, while other streams do not.
Is there anyway to restrict the capabilities of the stream returns by a property or method? For example my Catalog class looks something like this.
public abstract class Catalog
{
...
public abstract Stream File
{
get;
}
...
}
Is there someway to ensure that File will always return a readable stream that supports seeking?
Well, you can check the CanRead, CanWrite and CanSeek properties of the stream.
I'm not sure I understand your question correctly, though... What are you trying to do exactly ?
Some streams will never be seekable (for instance NetworkStream, GZipStream...), so if you're working on those types of stream, there is no way to force them to seek.
If you just want to restrict the functionality of a stream (for instance, prevent writing to a stream that is normally writable), you can create a wrapper that delegates its implementation to the underlying stream, but throws an exception for "disabled" methods.
howabout abstracting the underlying persistance mechanism. What do your callers need? If they all need the same behaviour from your 'File', can you not create an interface which all your potential stores to implement, rather than have them all return 'Stream' classes?

Save struct into a file In C#

I want to save a struct of data in a file in C#, but I don't want to use serialize and deserialize to implement it.
I want implement this action like I implement it in the C and C++ languages.
System.IO - File and Streams
To implement it in the "old fashioned way" in C#/.NET, based on the assumption C++ might use raw files and streams, you need to start in the .NET Framework's System.IO namespace.
Note: This allows you complete customization over the file reading/writing process so you don't have to rely on implicit mechanisms of serialization.
Files can be managed and opened using System.IO.File and System.IO.FileInfo to access Streams. (See the inheritance hierarchy at the bottom of that page to see the different kinds of streams.)
Helper Classes
So you don't have to manipulate bits and bytes directly (unless you want to).
For binary file access you can use System.IO.BinaryReader and BinaryWriter. For example, it easily converts between native data types and stream bytes.
For text-based access file access use System.IO.StreamReader and StreamWriter. Let's you use strings and characters instead of worrying about bytes.
Random Access
If random access is supported on the stream, use a method such as Stream.Seek(..) to jump around based on on whatever algorithm you decide on for determining record lengths and such.
You can use PtrToStructure and StructureToPtr to just dump the content to/from untyped data in a byte array which you can easily push to the file as one block. Just don't try this if your structure contains references to other objects (try keeping indexes instead, perhaps).
If you don't want to serialize it, you can always just use a BitConverter to convert the members to bytes via GetBytes, and write these directly to a Stream.

Categories

Resources