I am able to do data transfer between PC and android via bluetooth. But now i want to send image files of size around 80KB. When i send the image, only a part of it gets transfered but not
completely. Does anyone know how to achieve that? I am using TCP and working in C# platform.
string fileName = "send.png";
string filePath = #"C:\Users\Asus 53s\Desktop\"; //path
byte[] fileNameByte = Encoding.ASCII.GetBytes(fileName);
byte[] fileData = File.ReadAllBytes(filePath + fileName);
byte[] clientData = new byte[4 + fileNameByte.Length + fileData.Length];
byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length);
fileNameLen.CopyTo(clientData,0);
fileNameByte.CopyTo(clientData,4);
fileData.CopyTo(clientData,4+fileNameByte.Length);
sendMessage(clientData);
}
public Boolean sendMessage(byte[] msg)
{
{
if (!msg.Equals(""))
{
UTF8Encoding encoder = new UTF8Encoding();
NetworkStream stream = me.GetStream();
stream.Write(encoder.GetBytes(msg + "\n"), 0, (msg).Length);
stream.Flush();
}
}
Converting a binary object first to a string and then converting it to UTF-8 is not a good idea... Lots of bad things may happen in the conversions. (And there's also a bug in sendMessage.)
Why not just do:
public Boolean sendMessage(byte[] msg)
{
stream.Write(msg, 0, msg.Length);
stream.Flush();
}
If you really need that final "\n", then add before the Flush:
stream.WriteByte((byte)'\n');
Whilst we're on the subject of UTF-8, why are you presuming that the filename will only contain ASCII characters?? Change that code to:
byte[] fileNameByte = Encoding.UTF8.GetBytes(fileName);
Related
I have the problem that i can't send an image to the browser. After reading endless comments i decided to ask by myself. I send the Content-type and a bmp as byte[] but it is never showing an image in the browser.
Thanks for your help :D
I tried to use ASCII encoding to send the image but nope.
private const string headerImage = "HTTP/1.1 200 OK\r\nContent-Type:
image/jpeg\r\nContent-Length: %bytes%\r\n\r\n";
...
g.CopyFromScreen(Cursor.Position.X - 100, Cursor.Position.Y - 100, 0, 0, bmp.Size);
stream = new MemoryStream();
bmp.Save(stream, bmp.RawFormat);
byte[] img = stream.ToArray();
POST(headerImage.Replace("%bytes%", img.Length + "") + img, nwStream);
...
private void POST(String msg, NetworkStream nwStream)
{
UTF8Encoding uft8 = new UTF8Encoding();
byte[] send = uft8.GetBytes(msg);
nwStream.Write(send, 0, send.Length);
}
Just the console "TypeError: image is null"
I have a android mobile application that has functionality to set a profile picture.
I send a variable containing the path of the image to a method that does the following:
string imagePath = _ProfilePicture.GetTag (Resource.String.profile_picture_path).ToString ();
byte[] imageBytes = System.IO.File.ReadAllBytes(imagePath);
Stream imageStream = new MemoryStream(imageBytes);
After this block of code I send the imageStream variable to UploadUserProfilePicture(imageStream); which is located on the WCF Service
Currently it only sends the stream, but because we cannot send another parameter containing the extension. We save all images as png. I have however found a library that requires the stream to be parsed to bytes and then based on the bytes the file type can retrieved.
However when I then try to use the same stream to Write the file to the location on the server, the position is at the end so the file created is always 0 bytes.
I have tried:
Doing the conversion to Bytes in another method and only returning the fileType, however the originals position was still at the end.
The CopyTo function gave me the same results.
I tried using the Seek function and setting it's position back to zero however the I get a NotSupportedException.
I tried this as well:
string content;
var reader = new StreamReader(image);
content = reader.ReadToEnd();
image.Dispose();
image = new MemoryStream(Encoding.UTF8.GetBytes(content));
^ this seems to corrupt the stream as I cannot get the FileType nor write it to the above location.
I have also had a look at: How to read a Stream and reset its position to zero even if stream.CanSeek == false
This is the method on the WCF Service:
public Result UploadUserProfilePicture(Stream image)
{
try
{
FileType fileType = CommonMethods.ReadToEnd(image).GetFileType();
Guid guid = Guid.NewGuid();
string imageName = guid.ToString() + "." + fileType.Extension;
var buf = new byte[1024];
var path = Path.Combine(#"C:\" + imageName);
int len = 0;
using (var fs = File.Create(path))
{
while ((len = image.Read(buf, 0, buf.Length)) > 0)
{
fs.Write(buf, 0, len);
}
}
return new Result
{
Success = true,
Message = imageName
};
}
catch(Exception ex)
{
return new Result
{
Success = false,
Message = ex.ToString()
};
}
Link to Library Used: https://github.com/Muraad/Mime-Detective
The CommonMethods.ReadToEnd(image) method can be found here: How to convert an Stream into a byte[] in C#? as the questions answer
I hope this is enough information on my problem.
On the server side, you receive a stream from WCF that does not support seek operations. You can, however, read the stream to memory as the GetFileType method requires an array of bytes as input parameter. Instead of accessing the original stream again, you can write the bytes of the array to disk in a very easy way using the File.WriteAllBytes method:
public Result UploadUserProfilePicture(Stream image)
{
try
{
// Store bytes in a variable
var bytes = CommonMethods.ReadToEnd(image);
FileType fileType = bytes.GetFileType();
Guid guid = Guid.NewGuid();
string imageName = guid.ToString() + "." + fileType.Extension;
var path = Path.Combine(#"C:\" + imageName);
File.WriteAllBytes(path, bytes);
return new Result
{
Success = true,
Message = imageName
};
}
catch(Exception ex)
{
return new Result
{
Success = false,
Message = ex.ToString()
};
}
}
Please note that this means that you store a possibly large amount of bytes in memory, in the same way you already did before. It would be better if you could use the stream without reading all bytes into memory, so looking for an alternative for the GetFileType method that can handle a stream is well worth the time. You could then first save the image to a temporary file and then open a new FileStream to discover the correct file type so that you can rename the file.
We are using Flash to send an image to the servers and upload an image. The way we're trying to do this is by sending the bytes to the server through a parameter and then converting the bytes to an image.
http://i.gyazo.com/fb8225af80ef465b0262d97f63bd54b2.png
In the image the object is sending a few different bits of information. I'm not sure if I am supposed to just receive one bit of information instead of the entire object.
So far I have the post request
string byteArray = Request["bytes"];
Then I am trying to convert it to an image
string file_name = Guid.NewGuid().ToString();
//byte[] imageBytes = Convert.FromBase64String(byteArray);
Derio.App.Model.Helper.ByteArrayToFile(file_name, Derio.App.Model.Helper.GetBytes(byteArray));
My helper method looks like -
public static class Helper
{
public static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
public static string ByteArrayToFile(string _FileName, byte[] _ByteArray)
{
try
{
// Open file for reading
System.IO.FileStream _FileStream =
new System.IO.FileStream(_FileName, System.IO.FileMode.Create,
System.IO.FileAccess.Write);
// Writes a block of bytes to this stream using data from
// a byte array.
_FileStream.Write(_ByteArray, 0, _ByteArray.Length);
// close file stream
_FileStream.Close();
return "true";
}
catch (Exception _Exception)
{
// Error
return "Exception caught in process:" + _Exception.ToString();
}
}
}
We've multiple different methods such as trying to convert it from Base64String to an image.
I can't for the life of me though figure out what I am doing wrong.
What happens when you try this:
string file_name = Guid.NewGuid().ToString();
string byteArray = Request["bytes"];
byte[] imageBytes = Convert.FromBase64String(byteArray);
IO.File.WriteAllBytes(file_name, imageBytes);
I working on sending an image from Android to a WCF server. I tried sending the FileBOdy in a multi-part body, but that didn't get the job done. Finally I tried sending a ByteArrayBody in a multi-part body. It did work, but I got a corrupted image in server. I googled a lot, but couldn't get an acceptable solution to my problem. Can any one spot a mistake in my Android or WCF code?
Android code
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.JPEG, 75, bos);
byte[] data = bos.toByteArray();
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
String URL1 = "http://rohit-pc:8078/service1.svc/UploadImage";
HttpPost httpPost = new HttpPost(URL1);
ContentBody bin = null;
MultipartEntity reqEntity = new MultipartEntity(
HttpMultipartMode.BROWSER_COMPATIBLE);
ByteArrayBody bab = new ByteArrayBody(data, "forest.jpg");
reqEntity.addPart("image", bab);
reqEntity.addPart("photoCaption", new StringBody("sfsdfsdf"));
httpPost.setEntity(reqEntity);
HttpResponse response = httpClient.execute(httpPost);
BufferedReader reader = new BufferedReader(new InputStreamReader(
response.getEntity().getContent(), "UTF-8"));
String sResponse;
s = new StringBuilder();
while ((sResponse = reader.readLine()) != null) {
s = s.append(sResponse);
}
System.out.println("Response: " + s);
} catch (Exception e) {
Log.e(e.getClass().getName(), e.getMessage());
}
WCF code
public string GetStream(Stream str,string filename) {
Guid guid = Guid.NewGuid();
string Path = System.Web.Hosting.HostingEnvironment.MapPath("~/Images");
FileStream file = new FileStream(Path + "/" +filename, FileMode.Create);
byte[] bytearray = new byte[100000000];
int bytesRead, totalBytesRead = 0;
do {
bytesRead = str.Read(bytearray, 0, bytearray.Length);
totalBytesRead += bytesRead;
} while (bytesRead > 0);
file.Write(bytearray, 0, bytearray.Length);
file.Close();
file.Dispose();
return "Success";
}
I would say use Base64 format to send the image encoded in base64 format as string.
Sorry to answer an old question. But I had spent over 5 hours to figure out the issue. So would like to share the solution I found. My issue was a corrupted image saved in the server.
Actually, WCF does not have an effective way of parsing the multipart form data. Thats why the suggestion from MS is to use the raw stream to transmit images to wcf services.
So after a few hours of struggling to get rid of MultipartEntity(replaced with ByteArrayEntity), I finally got it working by using the below code. Hope this should help some one.
Android
Bitmap bm = BitmapFactory.decodeFile(params[0]);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bm.compress(CompressFormat.JPEG, 75, bos);
byte[] data = bos.toByteArray();
// the below is the important one, notice no multipart here just the raw image data
request.setEntity(new ByteArrayEntity(data));
then the rest of the actual http client continues.
Wcf Interface
<OperationContract()>
<WebInvoke(Method:="POST",
ResponseFormat:=WebMessageFormat.Json,
BodyStyle:=WebMessageBodyStyle.Bare,
UriTemplate:="/UploadPhoto?UsedCarID={UsedCarID}&FileName={FileName}")>
Sub UploadPhoto(UsedCarID As Integer, FileName As String, FileContents As Stream)
This is my first post at Stack Overflow thank you so much.
I have a asp.net webservice. some functionality of this webservice is to decompress clients request first. for this i have wrote 2 methods one uses MemoryStream and other uses FileStream.
When using MemoryStream sometiomes it get OutofMemoryException. so i have planned to use FileStream instead of MemoryStream for this reason.
before using this i just need a clarification that i am doing the right
thing for the right job.
N:B: Sometiome my clients will send 10MB+ data to the webservice which i need to decompress in webservice side. i have more then 200 clients running. and where the webservice is hosted there are more then 30 web application and webservice also hosted though my webservice is under different app pool.
I did see : GZIP decompression C# OutOfMemory
i get some knowledge from there but for webservice which one should better i have quite confusion based on my situation. and i need a clear understanding about this.
Decompress method (uses MemoryStream) is below:
public static string Decompress(string compressedText)
{
try
{
byte[] gzBuffer = Convert.FromBase64String(compressedText);
using (MemoryStream ms = new MemoryStream())
{
int msgLength = BitConverter.ToInt32(gzBuffer, 0);
ms.Write(gzBuffer, 4, gzBuffer.Length - 4);
byte[] buffer = new byte[msgLength];
ms.Position = 0;
using (GZipStream zip = new GZipStream(ms, CompressionMode.Decompress))
{
zip.Read(buffer, 0, buffer.Length);
}
return Encoding.UTF8.GetString(buffer);
}
}
catch (Exception ex)
{
DataSyncLog.Debug(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType + "::" + System.Reflection.MethodBase.GetCurrentMethod().ToString() + ":" + ex.ToString()+" : "+ex.StackTrace);
}
return string.Empty;
}
Decompress method (uses FileStream) is below:
public static string Decompress(string compressedText)
{
string SourceDirectory = System.Guid.NewGuid().ToString();
string DestinationDirectory = System.Guid.NewGuid().ToString();
try
{
File.WriteAllBytes(SourceDirectory, Convert.FromBase64String(compressedText));
using (FileStream fd = File.Create(DestinationDirectory))
{
using (FileStream fs = File.OpenRead(SourceDirectory))
{
fs.Seek(4, 0);
using (Stream csStream = new GZipStream(fs, CompressionMode.Decompress))
{
byte[] buffer = new byte[1024];
int nRead;
while ((nRead = csStream.Read(buffer, 0, buffer.Length)) > 0)
{
fd.Write(buffer, 0, nRead);
}
}
}
}
return Encoding.UTF8.GetString(File.ReadAllBytes(DestinationDirectory));
}
catch (Exception ex)
{
DataSyncLog.Debug(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType + "::" + System.Reflection.MethodBase.GetCurrentMethod().ToString() + ":" + ex.ToString() + " : " + ex.StackTrace);
return string.Empty;
}
finally
{
ClearFiles(SourceDirectory);
ClearFiles(DestinationDirectory);
}
}
Someone could you please show me the right direction that which one
should i use or any modification needed to the method that uses
MemoryStream that can overcome this error. i will be grateful to you
if you give me a clear understanding about this or any code change
suggestion.
Working with stream looks more efficient memory-wise in the second case: with memory stream you hold entire stream in memory, with file stream you have only buffer of limited size.
Both of your methods can have problems with memory just because of their signature: when client sends 10MB this amount of memory will be allocated for compressedText argument and for return value.
You can look into changing interface of your service, so data is transfered in chunks (here you can find example of similar approach -http://www.codeproject.com/Articles/43272/Uploading-Large-Files-Through-Web-Service)
Or, if you can consider switching to WCF, it supports streaming transfer mode - http://msdn.microsoft.com/en-us/library/ms751463.aspx