File ReadAllLines and Unicode Encoding - c#

I have a file which has unicode of a byte array which is a serialized object.
I tried reading that file using the code below.
string unicodeString = File.ReadAllText(filename);
This works fine, when i tried to get that Byte array back, for deserialization.
What I am looking for is, read only the particular lines of a file and try to convert that unicode string to bytes. For that I tried.
string unicodeString = string.join("", File.ReadAllLines(filename).Take(4).ToArray());
Here I used 4 because, the file has 4 lines of unicode string
byte[] _bytes = System.Text.Encoding.Unicode.GetBytes(unicodeString );
var bformatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
using (var ms = new MemoryStream(_bytes))
{
myobject data = (myobject)bformatter.Deserialize(ms);
}
I can able to get the string but unable to deserialize. My objective is to I will many such objects in the file and I'll retrieve only those lines and deserialize that to object.
It throws the following exception.
{"Binary stream '0' does not contain a valid BinaryHeader. Possible causes are invalid stream or object version change between serialization and deserialization."}

Related

String value system.byte[] while coverting Base64 value to string in c#

I have two LDIF files from where I am reading values and using it for comparsion using c#
One of the attribute: value in LDIF is a base64 value, need to convert it in UTF-8 format
displayName:: Rmlyc3ROYW1lTGFzdE5hbWU=
So I thought of using string -> byte[], but I am not able to use the above displayName value as string
byte[] newbytes = Convert.FromBase64String(displayname);
string displaynamereadable = Encoding.UTF8.GetString(newbytes);
In my C# code, I am doing this to retrieve the values from the ldif file
for(Entry entry ldif.ReadEntry() ) //reads value from ldif for particular user's
{
foreach(Attr attr in entry) //here attr gives attributes of a particular user
{
if(attr.Name.Equals("displayName"))
{
string attVal = attr.Value[0].ToString(); //here the value of String attVal is system.Byte[], so not able to use it in the next line
byte[] newbytes = Convert.FromBase64String(attVal); //here it throws an error mentioned below
string displaynamereadable = Encoding.UTF8.GetString(attVal);
}
}
}
Error:
The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.
I am trying to user attVal as String so that I can get the encoded UTf-8 value but its throwing an error.
I tried to use BinaryFormatter and MemoryStream as well, it worked but it inserted so many new chars with the original value.
Snapshot of BinaryFormatter:
object obj = attr.Value[0];
byte[] bytes = null;
BinaryFormatter bf = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
bf.Serialize(ms, obj);
bytes = (ms.ToArray());
}
string d = Encoding.UTF8.GetString(bytes);
So the result after encoding should be: "FirstNameLastName"
But it gives "\u0002 \u004 \u004 ...................FirstNameLastName\v"
Thanks,
Base64 was designed to send binary data through transfer channels that only support plain text, and as a result, Base64 is always ASCII text. So if attr.Value[0] is a byte array, just interpret those bytes as string using ASCII encoding:
String attVal = Encoding.ASCII.GetString(attr.Value[0] as Byte[]);
Byte[] newbytes = Convert.FromBase64String(attVal);
String displaynamereadable = Encoding.UTF8.GetString(newbytes);
Also note, your code above was feeding attVal into that final line rather than newbytes.

Image to binary returning System.byte[] instead of binary format in asp.net

I'm trying to convert image to binary and then store in database. I have a code to do this and after several Google searches, most answers are like the code I have written. The error I have is that instead of seeing a binary format in my database I'm getting System.byte[] as output. I also debugged and got the same thing.
Here's part of the code
if (Upload.HasFile)
{
HttpPostedFile postedFile = Upload.PostedFile;
string filename = Path.GetFileName(postedFile.FileName);
string fileExtension = Path.GetExtension(filename);
int filesize = postedFile.ContentLength;
if (fileExtension.ToLower() == ".jpg")
{
Stream stream = postedFile.InputStream;
BinaryReader binaryreader = new BinaryReader(stream);
byte[] bytes = binaryreader.ReadBytes((int)stream.Length);
Debug.WriteLine(bytes);
}
}
The result of my debug gives System.byte[] as output.
You can convert a byte array to string for DB storage
var storedString = Convert.ToBase64String(bytes);
and get the byte array from the stored string
bytes = Convert.FromBase64String(storedString);
If you really want to use the Binary format, you can look into the SoapHexBinary class, particularly the Parse() method and Value property

Encoding detection for a string-data in a byte[] succeed and after that all string comparisons failed

How it is all setup:
I receive a byte[] which contains CSV data
I don't know the encoding (should be unicode / utf8)
I need to detect the encoding or fallback to a default (the text may contain umlauts, so the encoding is important)
I need to read the header line and compare it with defined strings
After a short search I how to get a string out of the byte[] I found How to convert byte[] to string? which stated to use something like
string result = System.Text.Encoding.UTF8.GetString(byteArray);
I (know) use this helper to detect the encoding and afterwards the Encoding.GetString method to read the string like so:
string csvFile = TextFileEncodingDetector.DetectTextByteArrayEncoding(data).GetString(data);
But when I now try to compare values from this result string with static strings in my code all comparisons fails!
// header is the first line from the string that I receive from EncodingHelper.ReadData(data)
for (int i = 0; i < headers.Count; i++) {
switch (headers[i].Trim().ToLower()) {
case "number":
// do
break;
default:
throw new Exception();
}
}
// where (headers[i].Trim().ToLower()) => "number"
While this seems to be a problem with the encoding of both strings my question is:
How can I detect the encoding of a string from a byte[] and convert it into the default encoding so that I am able to work with that string data?
Edit
The code supplied above was working as long the string data came from a file that was saved this way:
string tempFile = Path.GetTempFileName();
StreamReader reader = new StreamReader(inputStream);
string line = null;
TextWriter tw = new StreamWriter(tempFile);
fileCount++;
while ((line = reader.ReadLine()) != null)
{
if (line.Length > 1)
{
tw.WriteLine(line);
}
}
tw.Close();
and afterwards read out with
File.ReadAllText()
This
A. Forces the file to be unicode (ANSI format kills all umlauts)
B. requires the written file be accessible
Now I only got the inputStream and tried what I posted above. And as I mentioned this worked before and the strings look identical. But they are not.
Note: If I use ANSI encoded file, which uses Encoding.Default all works fine.
Edit 2
While ANSI encoded data work the UTF8 Encoded (notepadd++ only show UTF-8 not w/o BOM) start with char [0]: 65279
So where is my error because I guess System.Text.Encoding.UTF8.GetString(byteArray) is working the right way.
Yes, Encoding.GetString doesn't strip the BOM (see https://stackoverflow.com/a/11701560/613130). You could:
string result;
using (var memoryStream = new MemoryStream(byteArray))
{
result = new StreamReader(memoryStream).ReadToEnd();
}
The StreamReader will autodetect the encoding (your encoding detector is a copy of the StreamReader.DetectEncoding())

xml issue incorporating byte array

hello i use a form of message parsing in which i write fields into a buffered stream, and then extract a byte array repesantaition of that stream
MyMessage _message = new MyMessage("me","you",MessageType.peer_message,4252422) ;
// in the constructor String sender,String receiver,MessageType(enumaraition) m_type,Int32 id
byte [] buffer = myEncoder.encode(message) ;
now when i pass this to myDecoder it decodes it in the same metter and it works great !
how i do that is not the issue
my issue is that in some cases of misscommunicaition i need to store the byte[] array (buffer) for farther use , and i'm trying to do that in an xmlDocumant under a tag
HERE IN THE INNER TEXT IS WHERE I WOULD LIKE TO SAVE THAT ARRAY OF BYTES
ive tryed -->
utf8Encoding.Ascii.getString(buffer) which save some kind of repsantaition
but it changes values of field wich are not strings... when i take it out by using
utf8Encoding.Ascii.getBytes(packet_node.innerText) ;
1)THE QUESTION IS HOW WOULD U GO ABOUT SAVING THAT BYTE ARRAY TO A XMLNODE
2)i've also tried just writing the fields one by one in each tag
<Packet>
<sender>me</sender>
<receiver>him</receiver>
<MessageType> ..?? how would i represent a byte as a string ? </MessageType>
<Id> 4252353523 </Id> here i have no problem but i still would have to always prase the value back and forth in other uses from int to string ..
</Packet>
3) so my conclusion is to serialize the byte array to an xmldocument .. just that i don't want it to be a document but just one node in an existing document
Encode it as a base-64 string. Just remember to decode it when you read it back.
byte[] bytes = ...;
string encoded = Convert.ToBase64String(bytes);
byte[] decoded = Convert.FromBase64String(encoded);

Invalid length for a Base-64 char array

I'm getting a "Invalid length for a Base-64 char array." inside of the IF(){...} are variations i have tried to get it to work. it fails in the first line without calling decrypt(...) proving it's not that functions problem. i get the same error inside with the first decrypt(...) call. the last one using the encoding.ascii... will get me inside the function, but then it fails inside the function. I'm getting the proper encrypted info from the database to string SSnum. it's value is: 4+mFeTp3tPF
try
{
string SSnum = dr.GetString(dr.GetOrdinal("Social Security"));
if (isEncrypted)
{
byte[] temp = Convert.FromBase64String(SSnum);
//SSnum = decrypt(Convert.FromBase64String(SSnum), Key, IV);
//SSnum = decrypt(Encoding.ASCII.GetBytes(SSnum), Key, IV);
}
txt_Social_Security.Text = SSnum;
}
catch { txt_Social_Security.Text = ""; }
I've been told to use the Convert.FromBase64String() and not the ASCII method...so why is it failing, how can i fix it?
Base64 data length should be multiple of 4 and with padding char '='
You can change your data as valid base64 data.
string dummyData = imgData.Trim().Replace(" ", "+");
if (dummyData.Length % 4 > 0)
dummyData = dummyData.PadRight(dummyData.Length + 4 - dummyData.Length % 4, '=');
byte[] byteArray = Convert.FromBase64String(dummyData);
https://stackoverflow.com/a/9301545/2024022
This will help you , try once.
Thanks
suribabu.
it's value is: 4+mFeTp3tPF
You are receiving this error because that value, 4+mFeTp3tPF, is in fact not valid Base64.
Is it possible you are simply missing the required padding character, as so 4+mFeTp3tPF=?
Are you certain that you have a Base64 string? Base64 is a means of encoding binary data into a string while only using standard 7-bit ASCII characters. It's not a string encoding like ASCII and has some control bytes present. You have a Base64 string if you're using Convert.ToBase64String to obtain the value (which, if you're trying to store binary data as a string, is your best bet)
Judging by your error (and your example data), I'm assuming that you do not have a Base64 string. If you need to store binary data in the database, you can either create a column using a binary type or encode the string into Base64 by using Convert.ToBase64String.
byte[] inputData = ...;
string base64String = Convert.ToBase64String(inputData);
byte[] outputData = Convert.FromBase64String(base64String);
Here, outputData should contain the same data as inputData.
If what you have is just an ASCII-encoded string, then your original practice of using System.Text.Encoding.ASCII.GetBytes() is correct, but you should change this to use a Base64 string if you can.
Are you sure that string 4+mFeTp3tPF is well-formed Base64 string?
I've tried some online services - no one could convert it.
replace
byte[] temp = Convert.FromBase64String(SSnum);
to this
var temp = UTF8Encoding.UTF8.GetBytes(SSnum);

Categories