如何将NSData转换为byte[]?

25
如果我有一个NSData中的图像数据,从图像中提取如下,那么我该如何将此NSData对象转换为字节数组?
NSData data = NSData.FromUrl(NSUrl.FromString(urlString));

问题是:你为什么要这样做?如果你需要从URL获取数据,只需使用.NET的WebClient类。 - Krumelur
我需要这样做的原因是因为在MonoTouch中使用WebClient似乎会导致我的应用程序在启动时崩溃。如果我排除对WebClient的引用,该应用程序就会正常启动。而且WebClient代码甚至不在启动事件中,而是在TouchDown事件处理程序中。所以这就是我在寻找WebClient替代方案的原因。 - BruceHill
3个回答

45
NSData data = NSData.FromUrl(NSUrl.FromString(urlString));

byte[] dataBytes = new byte[data.Length];

System.Runtime.InteropServices.Marshal.Copy(data.Bytes, dataBytes, 0, Convert.ToInt32(data.Length));

谢谢,Timo。我使用了不同的解决方案(请参见我发布的答案),但我也测试了你的解决方案,它很好用。因此,我将把这个答案归功于你,并将其标记为已接受的解决方案。谢谢。 - BruceHill
2
对于base64编码图像,这非常重要。我们最终得到了损坏的图像,因为我们使用了data.ToArray()。 - kwcto

28

我从Dimitris Tavlikos的回复中得到了对这个问题的答案:

如何在MonoTouch中将本地图像的内容读入base64字符串

从那个答案中,我了解到如果你包含一个System.Linq引用,那么NSData对象将有一个ToArray()方法,该方法将返回一个字节数组。因此,在引用这个命名空间后,您可以执行以下操作:

bytes[] dataBytes = data.ToArray();

希望这些信息能对其他人有所帮助。


4
对于较大的图片,我发现这种方法比Timo的解决方案要慢得多。 - Dan Abramov
1
@给那个点踩的人:如果你认为答案太糟糕需要点踩,至少要勇敢地留下评论说清楚为什么你点踩它。 - BruceHill
嘿,很抱歉我没有承认我的投票。几天前我重新访问了这个问题,并使用了你的方法,因为它得到了最多的投票,只是发现我已经来过这里(我忘了!)并且已经发现这种方法比Timo的慢得多。你说得对,答案不错,更重要的是,它不符合“没有用”的标准。对我来说没有用,但对于任何寻找合理性能单行代码的人来说肯定有用。我的投票是情绪化和错误的,所以我改正了。 - Dan Abramov
嗨,丹。感谢您承认了这个踩票,解释了引起它的情况并撤销了这个踩票。我很感激。也感谢您提供有关两种解决方案性能差异的信息。我的应用程序使用小图像,因此我从未需要对解决方案进行性能测试,但我相信这些信息将帮助其他需要考虑性能问题的人。不过,我很好奇为什么 ToArray 方法的性能不佳。也许这是 Monotouch 的某个人可以研究和纠正的问题。感谢您的评论。 - BruceHill
1
除了性能差异之外,我们在通过HTTP POST UIImages作为Base64编码的PNG时遇到了数据一致性问题。从.ToArray()迁移到System.Runtime.InteropServices.Marshal.Copy方法消除了最终出现在服务器上的损坏的PNG文件。 - kwcto
感谢bayfrontconsulting分享你遇到的问题。 - BruceHill

7

Timo的回答作为扩展方法:

    public static byte[] ToByteArray (this NSData data) {
        var dataBytes = new byte[data.Length];
        System.Runtime.InteropServices.Marshal.Copy(data.Bytes, dataBytes, 0, Convert.ToInt32(data.Length));
        return dataBytes;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接