Can someone please help.
I want to do some binary writing to files either using sdtout or by
passing a filename and I am unsure how to do either in C# - I would
like it to be as fast as possible.
I have done it in awk, just to see what I mean since the code should
be understandable by a C# whiz.
Thanks for all constructive help given.
Hal
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### this is in awk, run using 'awk -f thisfile.awk' > somefile
BEGIN {
m=50
for (x=0; x<m; x++)
for(y=0; y<m; y++)
for(z=0; z<m; z++)
printf("%c%c%c",x,y,z)
}
As I understand is all writing binary, but C# and .net uses different
sorts of unicode encoding, eg UTF-7,8,16,32
Aha, still don understand but writing the first 3 bits binary.. but
the example writes chars... trying binary...
using System;
class Test
{
static void Main(){
int m = 50;
for (int x=0; x<m; x++)
for(int y=0; y<m; y++)
for(int z=0; z<m; z++)
for(int a=0;a<7;a++)
Console.Write("{0}{1}{2},",
((x & a) == 0 ? '0' : '1'),
((y & a) == 0 ? '0' : '1'),
((z & a) == 0 ? '0' : '1'));
string zz = Console.ReadLine();
}
}
this is totally useless, but binary write eludes me, is there a analog
write in awk?
//CY
or...
More like C
using System;
class Test
{
static void Main(){
int m = 50;
for (int x=0; x<m; x++)
for(int y=0; y<m; y++)
for(int z=0; z<m; z++)
Console.Write("{0}{1}
{2}",Convert.ToChar(x),Convert.ToChar(y),Convert.ToChar(z));
}
}
int m = 50;
MemoryStream ms = new MemoryStream();
BinaryWriter bw = new BinaryWriter(ms);
for (int x = 0; x < m; ++x)
{
for (int y = 0; y < m; ++y)
{
for (int z = 0; z < m; ++z)
{
bw.Write(x); bw.Write(y); bw.Write(z);
}
}
}
File.WriteAllBytes(
@"c:\Software Development\Output.bin",
ms.ToArray());
System.IO.BinaryWriter
Arne
In .NET, the console (i.e. stdout) is inherently *text*-based. There
may be a way of reliably writing binary data to a redirected file, but
I don't know it offhand.
For a normal file, just use FileStream - the utility methods in the
File class are also handy.
--
Jon Skeet - <sk...@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Hal
#include <stdio.h>
int main(void)
{
FILE *output;
const char binfile[]="binfile.tmp";
const int m=50;
int x,y,z;
if( (output = fopen( binfile, "wb" )) == NULL )
{
fprintf(stderr,
"\nThe file '%s' could not be opened.\n\n", binfile );
return 9;
}
for (x=0; x<m; x++)
for (y=0; y<m; y++)
for (z=0; z<m; z++)
{
fputc(x,output);
fputc(y,output);
fputc(z,output);
}
fprintf(stderr, "The output should be in '%s'\n", binfile );
if( fclose(output))
fprintf(stderr, "The output file '%s' was not closed\n",
binfile );
return 0;
}
> Thanks for the replies.
> Which of the above would be closest to the C code that follows?
Define "closest". None of the examples are exactly like your most recent
sample. However, "Family Tree Mike"'s suggestion seems closest from a
functional point of view in that he opens a stream explicitly. His sample
uses a MemoryStream, but you can use any Stream in place of that. His
sample may or may not actually write the bytes to the output Stream that
you expect though.
You still have the problem that none of your samples really seem to make
sense. You seem to be mixing and matching binary output with character
output. Until you resolve that and figure out exactly what kind of output
you really want, it will be impossible to provide a single example that
does exactly what you want.
Pete
Id, have to start reding
http://groups.google.se/group/comp.unix.shell/browse_thread/thread/5e43944f4db26814/465217fcd0552107?hl=sv#465217fcd0552107
just to figure out what you are askng...
//CY
Thanks.
Is there any real difference between 'Convert.ToChar(y)' and '(char)
c'?
Hal.
You can cross the street without looking if there is a car coming
too... it works, but it might be a bad habit..
all casting is strange... will it work the same way in 10 yrs in I256
processors and c# 2017 by Microogelahoo? I cant say.. so cast
away... ;)
> [...]
> Is there any real difference between 'Convert.ToChar(y)' and '(char)
> c'?
As far as I know, no.
I'm still bewildered as to how you feel you can just ignore the character
encoding issues, but if you're happy with the results, fine by me. I'll
take that to mean that you never really did want binary output in the
first place. :)
Pete
I always wanted binary and all of the examples I have given were
intended to generate binary - essentially a string of bytes (hex) 00
00 00 00 00 01 00 00 02...
I would welcome advice on how to avoid any potential encoding issues.
Perhaps using 'byte' instead of 'char' is what I should have been
doing in order to generate the hex bytes just mentioned.
I had got the impression that casting was disliked in general, but it
still isn't clear to me why that is. Unicode aside, doesn't C# define
all the data types clearly, meaning an 'int' will be 4 bytes for
example and given that they are defined clearly, shouldn't casting
between them also be clearly defined?
Also if casting is 'bad' in any sense, given that C# is a relatively
new language, why was it put into the language at all?
Hal.
> I always wanted binary and all of the examples I have given were
> intended to generate binary - essentially a string of bytes (hex) 00
> 00 00 00 00 01 00 00 02...
Many of your examples used standard output, or failed to do anything
special to specify an encoding. That implies you are willing to leave
character encoding up to the framework or the OS, which isn't what one
does when they want a specific binary output.
After all, _everything_ is technically "binary". That's all the computer
knows. The word "binary" would typically imply that you have some
specific representation for the data you want followed, but nothing you've
posted (including the code that you said is the solution) does that.
> I would welcome advice on how to avoid any potential encoding issues.
> Perhaps using 'byte' instead of 'char' is what I should have been
> doing in order to generate the hex bytes just mentioned.
The first question is: are you trying to generate a specific byte output?
Or a specific character output?
Depending on the answer to that question, one of two follow-up questions
need to be answered: if the former, why do you want to use characters at
all? If the latter, what character encoding do you want?
And of course finally in either case it's important to understand exactly
what the output you desire is. We have a sense of that from your
examples, I think, but a true explanation would be given in the context of
the previous questions I mentioned and since we don't have those answers
yet, I don't think we have a _complete_ view of the overall question.
> I had got the impression that casting was disliked in general, but it
> still isn't clear to me why that is. Unicode aside, doesn't C# define
> all the data types clearly, meaning an 'int' will be 4 bytes for
> example and given that they are defined clearly, shouldn't casting
> between them also be clearly defined?
I don't know why you have the impression that casting is disliked in
general. It's perfectly fine when used appropriately. For example, if
you have an int that you know contains the exact UTF-16 Unicode value you
want, why not cast it to char?
Casting is frowned upon when the data requires some actual conversion,
because casting doesn't perform any conversion. But other than that, I
see no reason to dislike it.
> Also if casting is 'bad' in any sense, given that C# is a relatively
> new language, why was it put into the language at all?
Because casting isn't "bad" in all senses.
There are lots of things that are "bad" in _some_ sense, but not "bad" in
other senses. We would be severely restricted if we removed everything
that could be considered "bad" in some sense but not all senses.
Pete
Without going over old ground again, surely 'a string of hex bytes'
with the first few given is about as complete as it gets isn't it? Or
do you want a complete hex dump?
What the hell, here's a hex dump of the start and finish of it....
00 00 00 00 00 01 00 00 02 00 00 03 00 00 04 00
00 05 00 00 06 00 00 07 00 00 08 00 00 09 00 00
0a 00 00 0b 00 00 0c 00 00 0d 00 00 0e 00 00 0f
00 00 10 00 00 11 00 00 12 00 00 13 00 00 14 00
00 15 00 00 16 00 00 17 00 00 18 00 00 19 00 00
1a 00 00 1b 00 00 1c 00 00 1d 00 00 1e 00 00 1f
....
31 31 12 31 31 13 31 31 14 31 31 15 31 31 16 31
31 17 31 31 18 31 31 19 31 31 1a 31 31 1b 31 31
1c 31 31 1d 31 31 1e 31 31 1f 31 31 20 31 31 21
31 31 22 31 31 23 31 31 24 31 31 25 31 31 26 31
31 27 31 31 28 31 31 29 31 31 2a 31 31 2b 31 31
2c 31 31 2d 31 31 2e 31 31 2f 31 31 30 31 31 31
so, use byte rather than char in the last example I gave and we're
done?
Hal
While I think I know what you mean by "hex byte", it's really not a good
description of what you want.
"Hex" implies a base-16 number system, but bytes are base-2... and
"string" can mean several different things in the current context.
You do mean "a series of bytes represented in hexadecimal notation",
don't you?
Todd (just adding a bit of fuel to the fire <grin>)
> Without going over old ground again, surely 'a string of hex bytes'
> with the first few given is about as complete as it gets isn't it? Or
> do you want a complete hex dump?
What does "a string of hex bytes" mean? Do you want a character string,
formatted in hex, describing the bytes? Or do you want a series of
contiguous bytes? If the latter, you should avoid words like "string" and
"hex", because those are specific to character-based output.
Now, typically someone would use the phrase "hex dump" to describe a
character representation of a series of contiguous bytes. Using that
interpretation of your follow-up message, I take it to mean that you
really just want a series of contiguous bytes, and your follow-up message
is providing a character representation of what that series should look
like.
With that assumption, I'm now bewildered as to why you want to use
character data at all, or why you want to write once per iteration of the
loop. Why not just create an appropriate sized byte[], fill it with the
necessary data, and then write the entire array to a FileStream as-is in a
single operation?
For example:
byte bMax = 31;
int cbMax = bMax ^ 3, ibCur = 0;
byte[] rgb = new byte[cbMax];
for (byte bX = 0; bX < bMax; bX++)
{
for (byte bY = 0; bY < bMax; bY++)
{
for (byte bZ = 0; bZ < bMax; bZ++)
{
rgb[ibCur++] = bX;
rgb[ibCur++] = bY;
rgb[ibCur++] = bZ;
}
}
}
File.WriteAllBytes(strFilename, rgb);
All that other stuff seems superfluous, if what you really want is a
specific sequence of bytes.
If you want something more than that, then you still have yet to describe
your goal is a clear, unambiguous way.
Pete
On Sat, 17 May 2008 15:14:39 -0700, Peter Duniho
<NpOeS...@nnowslpianmk.com> wrote:
> [...]
> For example:
>
> byte bMax = 31;
Should be:
byte bMax = 32;
And since I would up not using "cbMax", I suppose you could eliminate that
variable and just put the calcuation in the byte[] allocation itself. :)
Anyway, hopefully you get the idea.
Pete
> Can someone please help.
>
> I want to do some binary writing to files either using sdtout or by
> passing a filename and I am unsure how to do either in C# - I would
> like it to be as fast as possible.
The way I present it isn't as necessarily as fast as possible; you'd
probably want to not reallocate the array every time around the loop, in
that case. However, it should give you a start.
---8<---
using System;
using System.IO;
class App
{
static void Main()
{
int m = 50;
using (Stream o = Console.OpenStandardOutput())
{
for (int x = 0; x < m; ++x)
for (int y = 0; y < m; ++y)
for (int z = 0; z < m; ++z)
o.Write(new byte[] {
(byte) x, (byte) y, (byte) z }, 0, 3);
}
}
}
--->8---
-- Barry
> OK, using variations on the above, I have this which does the job.
> ...
> for (int x = 0; x < m; ++x)
> {
> for (int y = 0; y < m; ++y)
> {
> for (int z = 0; z < m; ++z)
> {
> bw.Write(Convert.ToChar(x)); bw.Write(Convert.ToChar(y));
> bw.Write(Convert.ToChar(z));
You need to be clear whether you are using 'char' to mean 'byte' (like
it does in C) or 2-byte character, like it does in C#.
If you are trying to write characters to a binary file, then you need to
use an encoding, because characters aren't bytes.
> Is there any real difference between 'Convert.ToChar(y)' and '(char)
> c'?
Neither does the same thing as a cast to char in C.
> I always wanted binary
Then don't use C#'s char. It's a text character. It has multiple
possible encodings using bytes, depending on which encoding you use.
> I had got the impression that casting was disliked in general, but it
> still isn't clear to me why that is.
Casting a 'char' to a 'byte' is a lossy operation; also, C#'s 'char'
isn't meant to hold numeric values.
For example, writing characters ('char') to a BinaryWriter will cause
those characters to be encoded using the Encoding passed to the
BinaryWriter's constructor, which defaults to Encoding.Default, which in
turn is the ANSI code page (= GetACP() in WinAPI) of the running
program.
This will cause characters, whose number representation is greater than
the range of ASCII (0x7F), to be written as possibly different bytes to
the output. If you intend binary fidelity in your output, this will
probably not be what you want.
In short, 'char' is for holding characters. The .NET IO libraries try to
preserve character fidelity, not number fidelity, when working with
values of type 'char'; thus, they may change their numeric value,
including expanding to possibly more than one byte, depending on the
encoding used.
To make it concrete: what would you expect to be written for the
character expression "(char) 0x80"?
If you expected 0x80 to be written as to the output stream, you'd be
mistaken. 0xC2 0x80 is written instead, on my system:
---8<---
using System;
using System.IO;
class App
{
static void Main()
{
byte[] buf = new byte[3];
MemoryStream ms = new MemoryStream(buf);
BinaryWriter bw = new BinaryWriter(ms);
bw.Write((char) 0x79); // this is ok
bw.Write((char) 0x80); // this isn't ok
bw.Flush();
for (int i = 0; i < buf.Length; ++i)
Console.Write("{0:X2} ", buf[i]);
Console.WriteLine();
}
}
--->8---
Writes:
79 C2 80
> What the hell, here's a hex dump of the start and finish of it....
The program I posted in reply to the root of this thread will, when
redirected to a file, and opened in a hex editor, result in a view which
resembles what you quote here:
> 00 00 00 00 00 01 00 00 02 00 00 03 00 00 04 00
> 2c 31 31 2d 31 31 2e 31 31 2f 31 31 30 31 31 31
>
> so, use byte rather than char in the last example I gave and we're
> done?
You are dealing with raw bytes, not text, so don't use char. Use byte.
Yes, but everything looks like that in a hex editor. That's the whole
point of a hex editor. :)
I get your joke, but of course my intent was to disambiguate between
writing a program which outputted a hex dump, versus writing a program
which outputted binary data that, when viewed as a hex dump, looked like
the example...
If I wanted to iterate through 0 to 255 using a byte variable,
then this first attempt would not work, as it gives an infinite loop.
for(byte i=0;i<=255;i++)
Console.Write(i + " ");
This next attempt does work but its would be nicer to have the exit
condition test within the for statement:
for(byte i=0;;i++)
{
Console.Write(i + " ");
if(i==255)break;
}
Is it possible to make the first loop work by tweaking the parameters
a little?
Ignore the fact that this might be an ideal candidate for a cast!
Hal
for(byte i=0;i<=255;i++)
Console.Write(i + " ");
This next attempt does work but its would be nicer to have the test
within the for statement:
for(byte i=0;;i++)
{
Console.Write(i + " ");
if(i==255)break;
}
Is it possible to make the first loop work by tweaking the parameters
a little?
Ignore the fact that this might be an ideal candidate for a cast!
best I have managed so far:
for(byte i=0, abort=0 ; abort!=255 ;abort=i, i++)
{
Console.Write(i + " ");
}
<snip>
> Is it possible to make the first loop work by tweaking the parameters
> a little?
Not without more state, no.
Proof:
1) There are 256 states during which we want to enter the body of the
loop. If we need to capture the idea that the loop has finished,
that's another state - a total of 257.
2) A byte can only capture 256 distinct states.
You could do it with an extra variable, or even some weird tweaks and
a Nullable<byte>, but not just with byte.
> Ignore the fact that this might be an ideal candidate for a cast!
A cast is a good way of capturing the extra state for the test and
then reducing it to the "interesting" subset of the state within the
loop.
Jon