從流建立字節數組

從輸入流建立字節數組的首選方法是什麼? html

這是我目前使用.NET 3.5的解決方案。 數組

Stream s;
byte[] b;

using (BinaryReader br = new BinaryReader(s))
{
    b = br.ReadBytes((int)s.Length);
}

讀取和寫入流的塊是否仍然是一個更好的主意? 網絡


#1樓

您甚至能夠經過擴展程序使其變得更加漂亮: ide

namespace Foo
{
    public static class Extensions
    {
        public static byte[] ToByteArray(this Stream stream)
        {
            using (stream)
            {
                using (MemoryStream memStream = new MemoryStream())
                {
                     stream.CopyTo(memStream);
                     return memStream.ToArray();
                }
            }
        }
    }
}

而後將其稱爲常規方法: 優化

byte[] arr = someStream.ToByteArray()

#2樓

上面的那個是好的...可是當您經過SMTP發送內容時(若是須要),您將遇到數據損壞。 我已經改成其餘有助於正確發送字節的東西:' this

using System;
using System.IO;

        private static byte[] ReadFully(string input)
        {
            FileStream sourceFile = new FileStream(input, FileMode.Open); //Open streamer
            BinaryReader binReader = new BinaryReader(sourceFile);
            byte[] output = new byte[sourceFile.Length]; //create byte array of size file
            for (long i = 0; i < sourceFile.Length; i++)
                output[i] = binReader.ReadByte(); //read until done
            sourceFile.Close(); //dispose streamer
            binReader.Close(); //dispose reader
            return output;
        }'

#3樓

只是個人幾分錢...我常常使用的作法是將這樣的方法組織成一個自定義助手 spa

public static class StreamHelpers
{
    public static byte[] ReadFully(this Stream input)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            input.CopyTo(ms);
            return ms.ToArray();
        }
    }
}

將命名空間添加到配置文件並在任何地方使用它 code


#4樓

這真的取決於你是否能夠信任s.Length 。 對於許多流,您只是不知道將有多少數據。 在這種狀況下 - 在.NET 4以前 - 我會使用這樣的代碼: htm

public static byte[] ReadFully(Stream input)
{
    byte[] buffer = new byte[16*1024];
    using (MemoryStream ms = new MemoryStream())
    {
        int read;
        while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
        {
            ms.Write(buffer, 0, read);
        }
        return ms.ToArray();
    }
}

使用.NET 4及更高版本,我將使用Stream.CopyTo ,它基本上等同於個人代碼中的循環 - 建立MemoryStream ,調用stream.CopyTo(ms)而後返回ms.ToArray() 。 任務完成。 get

我或許應該解釋爲何個人回答比其餘人長。 Stream.Read並不保證它會讀取它所要求的全部內容。 例如,若是您正在從網絡流中讀取數據,它可能會讀取一個數據包的值,而後返回,即便很快會有更多數據。 BinaryReader.Read將繼續運行直到流的末尾或您指定的大小,但您仍然必須知道要開始的大小。

上面的方法將繼續讀取(並複製到MemoryStream ),直到它用完數據。 而後它要求MemoryStream返回數組中的數據副本。 若是您知道要開始的大小 - 或者認爲您知道大小,而不肯定 - 您能夠將MemoryStream構造爲該大小。 一樣,您能夠在結尾處進行檢查,若是流的長度與緩衝區的大小相同(由MemoryStream.GetBuffer返回),那麼您只需返回緩衝區便可。 因此上面的代碼並無獲得很好的優化,但至少是正確的。 關閉流不承擔任何責任 - 調用者應該這樣作。

有關更多信息(以及替代實現),請參閱此文章


#5樓

只是想指出,若是你有一個MemoryStream你已經有了memorystream.ToArray()

此外,若是您正在處理未知或不一樣子類型的流而且您能夠接收MemoryStream ,則能夠針對這些狀況繼續使用所述方法,並仍然使用其餘人接受的答案,以下所示:

public static byte[] StreamToByteArray(Stream stream)
{
    if (stream is MemoryStream)
    {
        return ((MemoryStream)stream).ToArray();                
    }
    else
    {
        // Jon Skeet's accepted answer 
        return ReadFully(stream);
    }
}
相關文章
相關標籤/搜索