Why Does Binarywriter Prepend Gibberish to the Start of a Stream? How to Avoid It

Why does BinaryWriter prepend gibberish to the start of a stream? How do you avoid it?

They are not byte-order marks but a length-prefix, according to MSDN:

public virtual void Write(string value);

Writes a length-prefixed string to
[the] stream

And you will need that length-prefix if you ever want to read the string back from that point. See BinaryReader.ReadString().

Additional

Since it seems you actually want a File-Header checker

  1. Is it a problem? You read the length-prefix back so as a type-check on the File it works OK

  2. You can convert the string to a byte[] array, probably using Encoding.ASCII. But hen you have to either use a fixed (implied) length or... prefix it yourself. After reading the byte[] you can convert it to a string again.

  3. If you had a lot of text to write you could even attach a TextWriter to the same stream. But be careful, the Writers want to close their streams. I wouldn't advice this in general, but it is good to know. Here too you will have to mark a Point where the other reader can take over (fixed header works OK).

BinaryWriter puts dirty chars at the begin writing in AppendMode

Try this:

    BinaryWriter w = new BinaryWriter(fsw);

w.Write(UTF8Encoding.Default.GetBytes(report));

C#: 2 unwanted additional characters are being appended during file write

If you're saving a string to a plain text file, use a StreamWriter instead of the BinaryWriter:

public static void saveFile(string path, string data) 
{
using (Stream fileStream = File.Open(path, FileMode.Append, FileAccess.Write, FileShare.None))
{
using (StreamWriter sw = new StreamWriter(fileStream))
{
sw.Write(data);
}
}
}

I cant write data to a binary file in a loop

There are some notes here:

  • the array1 items as you init will all be 14, you have to change it to following, but as i'll say later it is not required to define such array!

    For x = 2 To 91
    array1(x) = array1(x - 1) + 14 'modified to array1(x - 1)
    Next
  • before bw.Write, you have this: studentstream.Position = array1(randomvalue2) which will override the file position! also all items in array1 are equal to 14. this is why you get always a small file size (nothing more nothing less). you don't need to set position this way. Just remove that line from your code to append data one after one.

  • According to documentations, if you use a BinaryWriter to write strings, it will be prefixed by string-length! see this question.

    Dim bw As New BinaryWriter(studentstream, System.Text.Encoding.ASCII)

    bw.Write("A") 'writes: 1 A => where 1 is length of string "A"
    bw.Write("BC") 'writes: 2 B => where 2 is length of string "BC"

    'note that for Unicode Encoding, it will be 2 bytes per char
    Dim bw As New BinaryWriter(studentstream, System.Text.Encoding.Unicode)
    bw.Write("A") '2 A 0 where 2 is length of unicde string [A 0]
    bw.Write("BC") '4 B 0 C 0 where 4 is length of unicde string [B 0 C 0]
  • If you want to write strings without length prefix, you can use System.Text.Encoding.ASCII.GetBytes(str) to convert it to byte array:

    bw.Write(System.Text.Encoding.ASCII.GetBytes(newstudent.studentname))
  • Another option will also be to use StreamWriter instead of BinaryWriter as it seems you don't need it. see this link

  • note that its better to open files with Using block. otherwise, do not forget to call Close method (studentstream.Close()) when you finished. if you don't do this, you may lose last chunk or whole of your data!

    Using studentstream As New FileStream("C:\...\Desktop\A2Filing.dat", FileMode.Create)
  • use FileMode.Create to override the file if it already exists

C# Read and replace binary data in text file

int binaryStart = 100;
int binaryEnd = 150;

//buffer to copy the remaining data to it and insert it after inserting the base64string
byte[] dataTailBuffer = null;

string base64String = null;

//get the binary data and convert it to base64string
using (System.IO.Stream fileStream = new FileStream(@"c:\Test Soap", FileMode.Open, FileAccess.Read))
{
using (System.IO.BinaryReader reader = new BinaryReader(fileStream))
{
reader.BaseStream.Seek(binaryStart, SeekOrigin.Begin);

var buffer = new byte[binaryEnd - binaryStart];

reader.Read(buffer, 0, buffer.Length);

base64String = Convert.ToBase64String(buffer);

if (reader.BaseStream.Position < reader.BaseStream.Length - 1)
{
dataTailBuffer = new byte[reader.BaseStream.Length - reader.BaseStream.Position];

reader.Read(dataTailBuffer, 0, dataTailBuffer.Length);
}
}
}

//write the new base64string at specifid location.
using (System.IO.Stream fileStream = new FileStream(@"C:\test soap", FileMode.Open, FileAccess.Write))
{
using (System.IO.BinaryWriter writer = new BinaryWriter(fileStream))
{
writer.Seek(binaryStart, SeekOrigin.Begin);

writer.Write(base64String);//writer.Write(Convert.FromBase64String(base64String));

if (dataTailBuffer != null)
{
writer.Write(dataTailBuffer, 0, dataTailBuffer.Length);
}
}
}

reading c# binary files in java

As its name implies, BinaryWriter writes in binary format. .Net binary format to be precise, and as java is not a .Net language, it has no way of reading it. You have to use an interoperable format.

You can choose an existing format, like xml or json or any other interop format.

Or you can create your own, providing your data is simple enough to make it this way (it seems to be the case here). Just write a string to your file (using a StreamWriter for instance), provided you know your string's format. Then read your file from java as a string and parse it.

System.IO - Does BinaryReader/Writer read/write exactly what a file contains? (abstract concept)

For your first question: A BinaryReader is not what you want. The name is a bit misleading: it "Reads primitive data types as binary values in a specific encoding." You probably want a FileStream.

Regarding the second question: That will not be easy: please see the "How SDelete Works" section of SDelete for an explanation. Brief extract in case that link breaks in the future:

"Securely deleting a file that has no special attributes is relatively straight-forward: the secure delete program simply overwrites the file with the secure delete pattern. What is more tricky is securely deleting Windows NT/2K compressed, encrypted and sparse files, and securely cleansing disk free spaces.

Compressed, encrypted and sparse are managed by NTFS in 16-cluster blocks. If a program writes to an existing portion of such a file NTFS allocates new space on the disk to store the new data and after the new data has been written, deallocates the clusters previously occupied by the file."



Related Topics



Leave a reply



Submit