|
Hi,
since you dont control the file format, here are the fundamentals you will need, plus
some suggestions:
- use one FileStream for your file
- use BinaryReader.ReadBytes() to read a number of bytes at the current position (it will
advance the current position); problem here is you must specify the byte count
- create a number of classes or structs, one for each possible record type.
- if class/struct RecordType1 is one of the possible record types, you should give it
two static methods:
bool Accept(FileStream) would read some bytes and decide whether or not the data fits the
record type for that class/struct; it should restore the filestream position as if
nothing happened (use FileStream.Position property to remember where you are in the file,
and to return to that position); it should not throw exceptions to the caller.
RecordType1 Load(FileStream) would read all the bytes needed to load a record of that type,
knowing it is of that type (since it will have been Accepted beforehand). Load does
advance the filestream, so it consumes the record and returns the result. It should throw
exceptions when something fails.
- details on Accept: you can try and recognize the first few bytes; JPEG always start
with FF D8 and often with FF D8 FF E0; but nothing prevents other (non JPEG) records
to also start with FF D8 !! So your collection of Accept() methods should be sufficiently
accurate to discern the record types at hand.
- details on Load: you should know the byte count in order to read the right number
of bytes; scanning for an end marker is difficult: even if JPEG always ends on FF D9,
that does not mean the first FF D9 is the end of a JPEG (it could be a bit pattern
in the middle of the pixel info).
- it is rather hard to decode JPEG, so I suggest to let GDI+ try and decode a JPEG image.
One way would be to create a memory stream from your byte array, then call
Image.FromStream(MemoryStream), but I suspect you could directly call
Image.FromStream(FileStream) avoiding the byte count problem completely.
- you can create a new BinaryReader in every Accept and every Load method in each
RecordType class/struct, or reuse a single one all over the place (dont try something
intermediate).
- also provide a class/struct to handle the end-of-file record; it needs an Accept
but does not need a Load() method.
- and now the finale: put all your Accept and Load methods in one loop to decode the
entire file, as in:
try {
FileStream fs=...
for ( ; ; ) {
bool accepted=false;
if (RecordType1.Accept(fs)) {
accepted=true;
RecordType1 rec1=RecordType1.Load(fs);
...do whatever needs to be done with rec1
continue;
}
if (RecordType2.Accept(fs)) {
accepted=true;
RecordType2 rec2=RecordType2.Load(fs);
...do whatever needs to be done with rec2
continue;
}
...etc
if (RecordTypeN.Accept(fs)) {
...this one recognizes end of file
...close the shared BinaryReader if there is one, close the FileStream
break;
}
if (!accepted) throw new ApplicationException("Cant recognize record...");
}
} catch(Exception exc) {
... handle the exception
}
- the order of the RecordType# blocks may be relevant, since the first one that
returns a true on Accept will (have to) consume the data, so put the most strict
acceptors first.
Basically thats it, the rest are details...
|
|
|
|
|
Well, I was finally able to do this in a pretty efficient way.
I just read in the entire file, about 256k, to a byte array. Then I could convert it to a string in order to use string.IndexOf to find the record delimiters. I then used those demlimiter positions and Array.Copy to copy what I wanted out of the original byte[] to it's own byte[]. From there it was easy to get the image because each record has a fixed 223 byte header, so the remainder of the record had to be the embedded image. I just copied what was left of the record after the first 223 bytes to another byte[] and wrote it to disk, named it .jpg, and tada, I had the jpeg image!
|
|
|
|
|
Hi, I'm glad you got something working.
I would not fully trust the string.IndexOf part, since string operations
perform unpredictably on non-string data (such as JPEG images, which can
contain any bit pattern, that could be misinterpreted as Unicode characters).
htres wrote: each record has a fixed 223 byte header
That's new info, makes things easier I guess.
htres wrote: wrote it to disk, named it .jpg, and tada, I had the jpeg image
As I mentioned earlier if you want the image I guess you can do it without
such file using Image.FromStream(); if you need the file, then it is the
way to go.
|
|
|
|
|
Luc Pattyn wrote: I would not fully trust the string.IndexOf part, since string operations
perform unpredictably on non-string data (such as JPEG images, which can
contain any bit pattern, that could be misinterpreted as Unicode characters).
You are right, I had a lot of trouble with string.IndexOf when I was trying to isolate just the jpeg by searching for small strings of 2-4 chars. But after a lot of testing using it to find the record delimiter, which is the same 16 byte string in every record, it works very reliably. Even though it is entirely possible for this particular 16 byte string to show up within the jpeg encoding, the odds are against it.
Luc Pattyn wrote: htres wrote:
each record has a fixed 223 byte header
That's new info, makes things easier I guess.
Yeah it was a lot easier. That 223 byte header contained the fixed length fields that held the information about the image. I probably should have posted an example of the file format...but it would have been ugly since it is mostly binary.
Luc Pattyn wrote: htres wrote:
wrote it to disk, named it .jpg, and tada, I had the jpeg image
As I mentioned earlier if you want the image I guess you can do it without
such file using Image.FromStream(); if you need the file, then it is the
way to go.
I haven't tried the Image.FromStream option yet, though I plan to eventually. Ultimately I'd like to populate a database with the picture and header data as well. But I'll leave that part for a new thread...
Thanks for the help!
|
|
|
|
|
If you have control over the binary file format, this may help. Make sure that one of the attributes in the fixed length header is the length of the following JPEG image data. You could then create a byte array (byte[]) of the length of the JPEG image and read the specified number of bytes to the byte array using:
BinaryReader.Read(byte[], int index, int length)
|
|
|
|
|
I'm working on a custom control that extends DataGridView.
It has a Form as its custom property editor, like property pages we had in VB6.
The property editor is simply another form popped up when a designer verb of the control is selected.
This form contains the interface required to specify the columns to be added to the parent datagridview instance.
When I use the costom datagridview control in a form and specify some columns to it, they are visible in design time, this is what i was upto. The problem is that every time I edit the grid instance throught the custom property editor a new set of columns are added into froms source. However, the previous ones are detouched from the grid but remain in the code page, cluttering up the source.
I would vastly appreciate help/suggestion in accomplishing two things,
1. Being able to Programatically specify the names of the columns (e.g. PersonName_col, insted of the default dataGridViewTextBoxColumn1...)
2. if the above is no allowed, a process of cleaning up the recedue (detached from the grid) columns from the forms source.
I'd be obliged to salute anybody who can understand what I'm trying to say, cause I myself am not very sure if have said it meaningfully enough. Nevertheless this is the place where I've seen many wonders take place.
Gratitude in advance to the kind heart(s) that will even attempt to help me out.
(Its oh so hard for me to keep it short)
Galib Anwar
A C# shortimer.
|
|
|
|
|
Hi...
I`ve done a COM DLL (using C#.NET 2.0) to use in my VB6 app. OK. It worked well in my dev computer where i compiled it and let VS2005 register it for COM Interoperation.
But I need to use this COM DLL in another development enviroment (and further put it in a production enviroment) without VS2005. I`ve tried the regasm utility and intellisense works there in VB6, but I get an error when I try to run my project (Automation Error. The system cannot find the file specified").
Any hint?
Thanks
|
|
|
|
|
I think you either need to add a reference to the dll project, or the path to the dll to your development environment's search path.
|
|
|
|
|
You could try REGASM Assembly.DLL /CODEBASE. That way the current location of the assembly is recorded in the registry.
David
|
|
|
|
|
Hi,
I'm using a DataGridView to display data from a Dataset which contains a few tables.
I'm binding the DataGridView to the DataSet by DataGridView.DataSource and DataGridView.DataMember.
All goes well up to a point when I read new data into that DataSet (I read a new xml file into that DataSet using DataSet.ReadXml).
from this point and on the DataGridView remais the same and doesn't update according to the new data in the DataSet.
Even if I set the DataGridView.DataSource to Null and that back to that Dataset it doesn't help.
Any help is appreciated.
tnx
Roy
|
|
|
|
|
Hello everyone,
Is there anyway to fix the column size in a ListView so the user cannot move them around (Increase or Dicrease the column width)?
I am able to set the size using the following line of code:
listView1.Columns.Add("Tables", 150, HorizontalAlignment.Left);
Thank you so much for your time and have a great day.
Khoramdin
|
|
|
|
|
Change the HeaderStyle or ColumnStyle or something like that to NonClickable and I think that disables the resizing.
|
|
|
|
|
Hi
I am trying to install a setup kit using c#. During installation, db folder and output xml folder has to be configured. I have configured as
c:\program files\xy z technologies\DB\ and
c:\program files\xy z technologies\xml\
I am also checking for the existence of that particular folder. If the folder exist, it should automaticlally install otherwise, create the folder and install.
I tried both by giving exact folder name and also without folder name, but in both cases, it is failing and giving an error message as
System.io.filenotfoundexception. file or assembly name or one of its components does not exist.
what could be the problem.
If I had given the folder name without any space (c:\dbfolder, c:\xml) then (without space between folders) i am able to install the kit. if space given in between folder name (say for example "program files"), i am not able to install the kit. what could be the reason
Jtamil
|
|
|
|
|
Try putting the folder name between quotation marks.
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|
|
this is the code that i am using in my installer
base.Install (stateSaver);
assemblypath = this.Context.Parameters["assemblypath"].ToString();
appConfigPath = assemblypath + ".config";
try
{
strDbFolder = this.Context.Parameters["DBFOLDER"];
strGenerateFolder = this.Context.Parameters["GENERATEFOLDER"];
strImageFolder = this.Context.Parameters["IMAGEFOLDER"];
if ((strDbFolder == "")||(strGenerateFolder == "")||(strImageFolder == ""))
{
throw new InstallException("Directory path not specified");
}
if (!Directory.Exists(strDbFolder))
{
throw new InstallException("Directory path for DB Folder <" + strDbFolder + "> is invalid");
}
if (!Directory.Exists(strGenerateFolder))
{
throw new InstallException("Directory path for Generate Folder <" + strGenerateFolder + "> is invalid");
}
if (!Directory.Exists(strImageFolder))
{
throw new InstallException("Directory path for Image Folder <" + strImageFolder + "> is invalid");
}
doc = new XmlDocument();
doc.Load(appConfigPath);
SetValue("//appSettings//add[@key='DBFolder']", strDbFolder);
SetValue("//appSettings//add[@key='GenerateFolder']", strGenerateFolder);
SetValue("//appSettings//add[@key='ImageFolder']", strImageFolder);
doc.Save(appConfigPath);
}
catch (FormatException e)
{
string s = e.Message.ToString();
throw e;
}
catch (Exception ex)
{
throw ex;
}
|
|
|
|
|
Do the path variables (strDbFolder, ..) contain the correct values so the problem lies within the Directory.Exists method or are they already retrieved incorrectly?
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|
|
I have given the correct directory path
|
|
|
|
|
The question is whether they are correctly retrieved at runtime. What do the paths look like that are incorporated into the messages of the InstallExceptions? Are they correct?
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|
|
I ve tried
System.Windows.Forms.MessageBox.Show(strDbFolder) in all the places (right from the begining). but this error message is not displayed at all, but if i am giving a folder name without any space, then the message box is displaying. I am not able to give a message box of the path during installation
|
|
|
|
|
Don't you get the message of the install exception, which is thrown if an directory does not exist, during installation (the paths are incorporated in those messages)?
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|
|
i am getting io exception. The path that i have specified in strdbfolder exists, but still i am getting io exception
|
|
|
|
|
I've tested the Directory.Exists method and it definitely has no problem with space characters within folder names. At least that the case in a windows application, but I doubt the behaviour changes in an installer. Also it is not specified that the method throws any exception; it simply returns a boolean value.
What statement throws the IO exception?
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook www.troschuetz.de
|
|
|
|
|
Hi ! I have to create a new software in C# which will always RUN in the background. I want to show the GUI only when the user click on the icon in the icon tray (resident program). The program must run by itself each time the system (PC) is power up.
How we do it ?
Note: I have checked with my Visual Studio 2005 in the New Project option but I don't see anything that seems to be a SERVICE (or resident program).
How I must create the project ????
Thank you.
Danny Gilbert, engineer
Montreal, Canada
|
|
|
|
|
Create a new Project, and in the Project Types treeview, select "Windows" and then "Windows Service".
You'll probably want to make 2 programs. The service itself, and then a small Windows app to act as an interface for it.
|
|
|
|
|
Hey guys, i have a thread i created that loops in a while loop it also has 3 functions in it:
1 being:
private void PrintRecord()
I set up a delegate in the thread so that when the delegate is called it "should" make the thread do this function. When it does it still "hangs" the main form and it should really do the work behind the scenes without interupting the main form. Can someone point me in the right direction to what i am doing wrong?
Thanks In Advance,
Don't be overcome by evil, but overcome evil with good
|
|
|
|