I want to send a binary file to .net c# component in the following xml format
<BinaryFileString fileType='pdf'>
<!--binary file data string here-->
</BinaryFileString>
In the called component I will use the above xml string and convert the binary string received within the BinaryFileString tag, into a file as specified by the filetype='' attribute. The file type could be doc/pdf/xls/rtf
I have the code in the calling application to get out the bytes from the file to be sent. How do I prepare it to be sent with xml tags wrapped around it? I want the application to send out a string to the component and not a byte stream. This is because there is no way I can decipher the file type [pdf/doc/xls] just by looking at the byte stream. Hence the xml string with the filetype attribute. Any ideas on this?
method for extracting Bytes below
FileStream fs = new FileStream(_filePath, FileMode.Open, FileAccess.Read);
using (Stream input = fs)
{
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
{}
}
return buffer;
Thanks.
Edit:
Just to clarify why I am using an xml string rather than setting properties on my component. Actually my calling app is trying to simulate how Siebel will call my component.
http://download.oracle.com/docs/cd/E05553_01/books/eScript/eScript_JSReference244.html#wp1014380
Im not sure if Siebel can set my components properties as I need it to. So Im working on the angle of it sending the data in xml.
Base64 representation is universaly used to represent binary data.
public void EncodeWithString() {
System.IO.FileStream inFile;
byte[] binaryData;
try {
inFile = new System.IO.FileStream(inputFileName,
System.IO.FileMode.Open,
System.IO.FileAccess.Read);
binaryData = new Byte[inFile.Length];
long bytesRead = inFile.Read(binaryData, 0,
(int)inFile.Length);
inFile.Close();
}
catch (System.Exception exp) {
// Error creating stream or reading from it.
System.Console.WriteLine("{0}", exp.Message);
return;
}
// Convert the binary input into Base64 UUEncoded output.
string base64String;
try {
base64String =
System.Convert.ToBase64String(binaryData,
0,
binaryData.Length);
}
catch (System.ArgumentNullException) {
System.Console.WriteLine("Binary data array is null.");
return;
}
// Write the UUEncoded version to the XML file.
System.IO.StreamWriter outFile;
try {
outFile = new System.IO.StreamWriter(outputFileName,
false,
System.Text.Encoding.ASCII);
outFile.Write("<BinaryFileString fileType='pdf'>");
outFile.Write(base64String);
outFile.Write("</BinaryFileString>");
outFile.Close();
}
catch (System.Exception exp) {
// Error creating stream or writing to it.
System.Console.WriteLine("{0}", exp.Message);
}
}
At the receiving end you can reverse this and get back original file content as mentioned below.
// Convert the Base64 UUEncoded input into binary output.
byte[] binaryData;
try {
binaryData =
System.Convert.FromBase64String(base64String);
}
catch (System.ArgumentNullException) {
System.Console.WriteLine("Base 64 string is null.");
return;
}
catch (System.FormatException) {
System.Console.WriteLine("Base 64 string length is not " +
"4 or is not an even multiple of 4." );
return;
}
Can you BASE64 your bytes? MSDN ref: Convert.ToBase64, Convert.FromBase64String
expanding on @russau's answer it will work like this:
var s = "Hello World";
var b = Encoding.Default.GetBytes(s);
var bstr = Convert.ToBase64String(b);
Console.WriteLine("Original String:" + s);
Console.WriteLine("Base64 String:" + bstr);
var fromBStr = Convert.FromBase64String(bstr);
var st = Encoding.Default.GetString(fromBStr);
Console.WriteLine("Converted string: " + st);
you wont need first two lines:
var s = "Hello World";
var b = Encoding.Default.GetBytes(s);
as you already have a byte array. I've used string to show that you get exactly the same value you started with in the end when you convert byte array from Convert.FromBase64String
You mention that you are calling a C# component. I'm not sure I understand why using this component means you need to create an XML string.
Is it possible to define classes to hold your data instead of using an XML string? e.g.
public enum FileType
{
Word,
Excel,
RichText,
PDF
}
public class FileData
{
public FileType TypeOfFile
{
get;
set;
}
public byte[] Data
{
get;
set;
}
}
Then the caller of the component just sets the FileType and the byte[]. The component's interface would then be more explicitly defined (FileData class as opposed to the more generic string or XmlDocument).