store byte[] into file C# - c#

I have this function reading website names one at a time and creating an object array for each url where the website name and bytes received from the webpage is saved into the array. This array is then saved into a txt file called "saveData.txt"
string[] readText = File.ReadAllLines("new.txt");
foreach (string s in readText)
{
object[] url = new object[2];
url[0] = s;
url[1] = displayByteCode(s);
using (StreamWriter writer = new StreamWriter("saveData.txt",true))
{
writer.WriteLine(url[0]+" "+ url[1]);
}
}
The displayByteCode is a function that is as follows:
public byte[] displayByteCode(string getURLCode)
{
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(getURLCode);
myRequest.Method = "GET";
WebResponse myResponse = myRequest.GetResponse();
MemoryStream ms = new MemoryStream();
myResponse.GetResponseStream().CopyTo(ms);
byte[] data = ms.ToArray();
return data;
}
it is to return the bytes received from the website. While the url is saved properly. the byte is saved as "System.Byte[]" how do i save the actually byte instead of this? Thank you for your help!

when you call + operator on a string and an object, it calls toStirng method on that object (this is why it writes System.Byte[] on file)
you can't write both string and bytes in c#, for storing bytes, you can use :
File.WriteAllBytes("saveData.txt", (byte[])url[1]);
or you can convert it to string and store it :
writer.WriteLine(url[0]+" "+ Convert.ToBase64String((byte[])url[1]));

Related

Web service File Stream to Byte[] to FileStream to pdf failing C#

I am trying to create a web service that returns a pdf file as a byte[] and then the app that consumes it grabs the byte[] and saves it as a pdf file and then opens it. The file fails to open at the end.
Here is the Web Service that returns a byte[]
[WebMethod]
public byte[] XXXX(int fileID)
{
try
{
using (EntitiesModel dbContext = new EntitiesModel())
{
string fileFullPath = .....
.......
if (fileFullNamePath != null)
{
FileStream fileStream = new FileStream(fileFullNamePath, FileMode.Open, System.IO.FileAccess.Read);
int len = fileStream.Length.ToInt();
Byte[] documentContents = new byte[len];
fileStream.Read(documentContents, 0, len);
fileStream.Close();
return documentContents;
Then it is called from an app with the following code
string soap = "<?xml version=\"1.0\" encoding=\"utf - 8\"?>" +
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
"<soap:Body>" +
"<XXXX xmlns=\"http://tempuri.org/\">" +
"<fileID>XXXXX</fileID>" +
"</XXXX>" +
"</soap:Body>" +
"</soap:Envelope>";
string localhostContext = #"http://localhost:3381/";
string webserviceAddress = #"XXXX/XXXX/XXXXX.asmx";
string url = localhostContext + webserviceAddress ;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.ContentType = "text/xml";
request.ContentLength = soap.Length;
request.Timeout = 20000;
request.Method = "POST";
using (Stream stream = request.GetRequestStream())
{
using (StreamWriter streamWriter = new StreamWriter(stream))
{
streamWriter.Write(soap); }
}
}
byte[] bytes;
try
{
WebResponse response = request.GetResponse();
bytes = ReadFully(response.GetResponseStream());
}
catch (Exception exception)
{
throw;
}
private byte[] ReadFully(Stream input)
{
byte[] buffer = new byte[16*1024];
using (MemoryStream memoryStream = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
memoryStream.Position = 0;
memoryStream.Write(buffer, 0, read);
}
return memoryStream.ToArray();
}
}
FileStream objfilestream =
new FileStream(fileName, FileMode.Create,FileAccess.ReadWrite);
objfilestream.Write(bytes, 0, bytes.Length);
objfilestream.Close();
var process = Process.Start(fileName);
The code runs fine and creates a pdf and then tries to open that pdf. But the file can not be opened. Adobe Acrobat gives the error
Adobe Acrobat Reader could not open XXX.pdf because it is either not a
supported file type or because the file has been damaged (for example, it
was sent as an email attachment and wasn't correctly decoded).
Because I am not getting an error in the code I am at a loss to know where the error is that is not creating the proper file.
There was an issue with the Stream variable called input was not giving length so I used Jon Skeet's suggestion here Stackoverflow:Creating a byte array from a stream
new byte[16*1024];
rather than
new byte[input.length]
There were three things wrong.
memoryStream.Position = 0;
in the while loop was problematic so I removed it.
Secondly when reading the stream. What it returned was the SOAP XMl message with the encoded base64 string in the the XXXXResult XML tag. So I had to extract that.
Finally I had to use
byte[] fileResultBytes = Convert.FromBase64String(resultString);
to get the byte[] from the resultString extracted from the SOAP message. In the test SOAP message, that can be generated locally, it tells you the type of this result string. I missed that initially.
Thanks to VC.One and CodeCaster for their correct suggestions.

Why is FtpWebRequest corrupting text that's appended to a file?

I'm trying to use FTP to add lines of text to a .txt file stored on a web server. It's connecting and appending the text, but for some reason it's corrupted and displays as random characters (symbols, Chinese etc). Here is my code:
byte[] data = md5Encryptor.ComputeHash(Encoding.ASCII.GetBytes(dataString));
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpAddress + "file.txt");
request.Method = WebRequestMethods.Ftp.AppendFile;
request.ContentLength = data.Length;
request.Credentials = ftpCredentials;
Stream requestStream = request.GetRequestStream();
requestStream.Write(data, 0, data.Length);
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
response.Close();
To try to debug, I converted 'data' from a byte[] back into a string using this code:
public static string BytesToString(byte[] data)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
sb.Append(data[i].ToString("X2"));
}
return sb.ToString();
}
Here's what the above method returned, an md5 hash string as expected:
E904B52B435BF0E1DA8D4CE6EC47E45A
This is what the same 'data' var, appended to my file via FTP, ended up as:
ө⮵孃跚䟬嫤
I've even tried this, just in case there was an encoding issue:
string dataString = BytesToString(data);
bytes[] newBytes = Encoding.ASCII.GetBytes(dataString);
Didn't work. Anyone know what I'm doing wrong here?
Turns out the .txt was encoded as Unicode not ASCII. Wikipedia said ASCII was the default, but if you open the 'Save As' menu you can check. As soon as I saved with Encoding.Unicode it worked fine.

Sending Image in Base64 String and receiving in webservice via kSoap

i am sending an image in byte[] and 3 strings to a webservice usingksoap but its not working for me , i am not sure where i am wrong, in sending image from Android and at receiving end, i am putting the code here kindly check it
Here is how i am converting image to byte[] at client (Android) side
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
myBitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream .toByteArray();
String encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);
and here is the code where i am sending it to webservice via Ksoap
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("Name", name);
request.addProperty("Email", email);
request.addProperty("Picture", encoded );
request.addProperty("Date", date);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport. call(SOAP_ACTION, envelope);
SoapPrimitive result = (SoapPrimitive) envelope.getResponse();
String str = result.toString();
and here is the webMethod where i am receiving this soap envelop
[WebMethod]
public String PutFile(String Name, String Email, String Picture, String Date)
{
String PictureByteString = Picture;
Image imgFromString = SaveByteArrayAsImage(PictureByteString);
DateTime.Now.ToShortDateString() + ".jpg"));
string serverpath = Server.MapPath("~/" + Email + "-" + DateTime.Now.ToShortDateString());
imgFromString.Save(serverpath, System.Drawing.Imaging.ImageFormat.Jpeg);
String Path = serverpath + ".Jpeg";
return Name;
}
private Image SaveByteArrayAsImage(string base64String)
{
byte[] bytes = Convert.FromBase64String(base64String);
image;
using (MemoryStream ms = new MemoryStream(bytes))
{
image = Image.FromStream(ms);
}
return image;
}
when i send data to webservice android LogCat shows me
java.io.IOException: HTTP request failed, HTTP status: 500
i think so which means that the data i am sending to webservice is not of correct type, so i tried to make String Picture to byte[] Picture in webmethod but result was same. I am not being able to figure out where i am wrong ...
Update:
now sending image in a Base64 string and java exception is gone but the webmethod is still not converting that Base64 string into image...
This is how i did it.
parameter passed to function is Base64 string
public string SendImage(string data)
{
byte[] myarray = Convert.FromBase64String(data);
MemoryStream memStream = new MemoryStream(myarray);
Image myimage = Image.FromStream(memStream);
myimage.Save("G:\\image.png", ImageFormat.Png);
return "succeeded";
}
This is working perfectly for me, Hope it helps.

Decode Base64 and Inflate Zlib compressed XML

Sorry for the long post, will try to make this as short as possible.
I'm consuming a json API (which has zero documentation of course) which returns something like this:
{
uncompressedlength: 743637,
compressedlength: 234532,
compresseddata: "lkhfdsbjhfgdsfgjhsgfjgsdkjhfgj"
}
The data (xml in this case) is compressed and then base64 encoded data which I am attempting to extract. All I have is their demo code written in perl to decode it:
use Compress::Zlib qw(uncompress);
use MIME::Base64 qw(decode_base64);
my $uncompresseddata = uncompress(decode_base64($compresseddata));
Seems simple enough.
I've tried a number of methods to decode the base64:
private string DecodeFromBase64(string encodedData)
{
byte[] encodedDataAsBytes = System.Convert.FromBase64String(encodedData);
string returnValue = System.Text.Encoding.Unicode.GetString(encodedDataAsBytes);
return returnValue;
}
public string base64Decode(string data)
{
try
{
System.Text.UTF8Encoding encoder = new System.Text.UTF8Encoding();
System.Text.Decoder utf8Decode = encoder.GetDecoder();
byte[] todecode_byte = Convert.FromBase64String(data);
int charCount = utf8Decode.GetCharCount(todecode_byte, 0, todecode_byte.Length);
char[] decoded_char = new char[charCount];
utf8Decode.GetChars(todecode_byte, 0, todecode_byte.Length, decoded_char, 0);
string result = new String(decoded_char);
return result;
}
catch (Exception e)
{
throw new Exception("Error in base64Decode" + e.Message);
}
}
And I have tried using Ionic.Zip.dll (DotNetZip?) and zlib.net to inflate the Zlib compression. But everything errors out. I am trying to track down where the problem is coming from. Is it the base64 decode or the Inflate?
I always get an error when inflating using zlib: I get a bad Magic Number error using zlib.net and I get "Bad state (invalid stored block lengths)" when using DotNetZip:
string decoded = DecodeFromBase64(compresseddata);
string decompressed = UnZipStr(GetBytes(decoded));
public static string UnZipStr(byte[] input)
{
using (MemoryStream inputStream = new MemoryStream(input))
{
using (Ionic.Zlib.DeflateStream zip =
new Ionic.Zlib.DeflateStream(inputStream, Ionic.Zlib.CompressionMode.Decompress))
{
using (StreamReader reader =
new StreamReader(zip, System.Text.Encoding.UTF8))
{
return reader.ReadToEnd();
}
}
}
}
After reading this:
http://george.chiramattel.com/blog/2007/09/deflatestream-block-length-does-not-match.html
And listening to one of the comments. I changed the code to this:
MemoryStream memStream = new MemoryStream(Convert.FromBase64String(compresseddata));
memStream.ReadByte();
memStream.ReadByte();
DeflateStream deflate = new DeflateStream(memStream, CompressionMode.Decompress);
string doc = new StreamReader(deflate, System.Text.Encoding.UTF8).ReadToEnd();
And it's working fine.
This was the culprit:
http://george.chiramattel.com/blog/2007/09/deflatestream-block-length-does-not-match.html
With skipping the first two bytes I was able to simplify it to:
MemoryStream memStream = new MemoryStream(Convert.FromBase64String(compresseddata));
memStream.ReadByte();
memStream.ReadByte();
DeflateStream deflate = new DeflateStream(memStream, CompressionMode.Decompress);
string doc = new StreamReader(deflate, System.Text.Encoding.UTF8).ReadToEnd();
First, use System.IO.Compression.DeflateStream to re-inflate the data. You should be able to use a MemoryStream as the input stream. You can create a MemoryStream using the byte[] result of Convert.FromBase64String.
You are likely causing all kinds of trouble trying to convert the base64 result to a given encoding; use the raw data directly to Deflate.

C#/Why does Get html returns random junk characters?

I have this for ex:
Link
This code:
const String nick = "Alex";
const String log = "http://demonscity.combats.com/zayavka.pl?logs=";
foreach (DateTime cd in dateRange)
{
string str = log + String.Format("{0:MM_dd_yy}", cd.Date) + "&filter=" + nick;
String htmlCode = wc.DownloadString(str);
}
returns something...."‹\b\0\0\0\0\0\0я•XYsЫЦ~зЇёѕ™d)bг.тBҐ$ЪRЖ’<2УN&сh#р ’„\f\0J–—_Фџђ§¤нt¦г6ќѕУЄђ0’IQtТґcµо№X(jі-Щ/Ђі|g?`yҐ¶ц"
Other links works fine.
I think the problem is with codepage, how can i fix it? Or it's server problem?
The issue is that the response is GZip-compressed (response has a Content-Encoding: gzip header). You need to first decompress it, then you'll be able to read it:
public class StackOverflow_6660689
{
public static void Test()
{
WebClient wc = new WebClient();
Encoding encoding = Encoding.GetEncoding("windows-1251");
byte[] data = wc.DownloadData("http://demonscity.combats.com/zayavka.pl?logs=08_07_11&filter=Alex");
GZipStream gzip = new GZipStream(new MemoryStream(data), CompressionMode.Decompress);
MemoryStream decompressed = new MemoryStream();
gzip.CopyTo(decompressed);
string str = encoding.GetString(decompressed.GetBuffer(), 0, (int)decompressed.Length);
Console.WriteLine(str);
}
}
I think it is returning result in gzip format which it should not unless client explicitly accepts the format.

Categories