How to read the contents of a local image into a b

2019-04-16 05:53发布

问题:

I am trying to read the contents of an image stored in the Documents folder for my application into a string, using base64 encoding. I have the image location as a url; so, for example, I could have the following url for the image:

file://localhost/var/mobile/Applications/40A88352-7F78-4085-856B-9621541774ED/Documents/tmp/photo_017.jpg

This is what I tried:

byte[] imgData = new WebClient().DownloadData(url);
string base64Encoded = System.Convert.ToBase64String(imgData);

As far as I know this code should be correct. However, this causes my monotouch application to crash at startup, and in the debugger I see the following exception thrown:

Mono.Debugger.Soft.VMDisconnectedException: Exception of type 'Mono.Debugger.Soft.VMDisconnectedException' was thrown.
at Mono.Debugger.Soft.Connection.SendReceive (CommandSet command_set, Int32 command, Mono.Debugger.Soft.PacketWriter packet) [0x00000] in <filename unknown>:0 
at Mono.Debugger.Soft.Connection.VM_GetVersion () [0x00000] in <filename unknown>:0 
at Mono.Debugger.Soft.Connection.Connect () [0x00000] in <filename unknown>:0 
at Mono.Debugger.Soft.VirtualMachine.connect () [0x00000] in <filename unknown>:0 
at Mono.Debugger.Soft.VirtualMachineManager.ListenInternal (System.Net.Sockets.Socket dbg_sock, System.Net.Sockets.Socket con_sock) [0x00000] in <filename unknown>:0 

If I comment out the two lines of code that I gave above, then the application starts correctly, so it seems to me that the new WebClient() line of code is causing this exception.

So, basically, I need to know, either if there is a workaround to this problem that I am experiencing with WebClient or if there is another way for me to read the contents of the image into a string such that I do not need to use WebClient.

回答1:

If you are getting VMDisconnectedException at startup, it probably means that the FinishedLaunching method does not return in time and iOS kills your app.

If you need to load that file at startup, wrap your code in an async method or thread that will allow FinishedLaunching to return in time:

byte[] imgData;
string base64Encoded;
ThreadPool.QueueUserWorkItem(delegate {
    imgData = new WebClient().DownloadData(url);
    base64Encoded = System.Convert.ToBase64String(imgData);
});

I tried your code and it works, however I would suggest using wrappers to native objects as much as possible.

byte[] imgData;
string base64Encoded;
ThreadPool.QueueUserWorkItem(delegate {
   NSUrl imageUrl = NSUrl.FromFilename("path/file");
   NSData data = NSData.FromUrl(imageUrl);
   imgData = data.ToArray();
   base64Encoding = Convert.ToBase64String(bufferData);
});