亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C#中MemoryStream類怎么用

發布時間:2021-08-21 16:30:06 來源:億速云 閱讀:550 作者:小新 欄目:開發技術

這篇文章將為大家詳細講解有關C#中MemoryStream類怎么用,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

MemoryStream位于System.IO命名空間,為系統內存提供流式的讀寫操作。常作為其他流數據交換時的中間對象操作。

  1. MemoryStream類封裝一個字節數組,在構造實例時可以使用一個字節數組作為參數,但是數組的長度無法調整。使用默認無參數構造函數創建實例,可以使用Write方法寫入,隨著字節數據的寫入,數組的大小自動調整。

  2. 在對MemoryStream類中數據流進行讀取時,可以使用seek方法定位讀取器的當前的位置,可以通過指定長度的數組一次性讀取指定長度的數據。ReadByte方法每次讀取一個字節,并將字節返回一個整數值。

  3. UnicodeEncoding類中定義了Unicode中UTF-16編碼的相關功能。通過其中的方法將字符串轉換為字節,也可以將字節轉換為字符串。

MemoryStream 是一個特例,MemoryStream中沒有任何非托管資源,所以它的Dispose不調用也沒關系。托管資源.Net會自動回收

MemoryStream繼承自Stream類。內存流的好處是指針可以晃來晃去,也就是支CanSeek,Position,Seek()。任意讀其中一段。

在內存流中有必要了解一下SeekOrigin枚舉

枚舉成員成員值描述
Begin0指定流的開頭。
Current1指定流內的當前位置。
End2指定流的結尾。

MemoryStream提供的屬性與方法:

一、屬性

CanRead     已重寫。獲取一個值,該值指示當前流是否支持讀取。
CanSeek     已重寫。獲取一個值,該值指示當前流是否支持查找。
CanTimeout    獲取一個值,該值確定當前流是否可以超時。(從 Stream 繼承。)
CanWrite     已重寫。獲取一個值,該值指示當前流是否支持寫入。
Capacity     獲取或設置分配給該流的字節數。 這個是分配的字節數
Length      已重寫。獲取用字節表示的流長度。這個是真正占用的字節數。
Position      已重寫。獲取或設置流中的當前位置。
ReadTimeout   獲取或設置一個值,該值確定流在超時前嘗試讀取多長時間。 (從 Stream 繼承。)
WriteTimeout   獲取或設置一個值,該值確定流在超時前嘗試寫入多長時間。 (從 Stream 繼承。)

二、方法

BeginRead     開始異步讀操作。 (從 Stream 繼承。)
BeginWrite    開始異步寫操作。 (從 Stream 繼承。)
Close        關閉當前流并釋放與之關聯的所有資源(如套接字和文件句柄)。 (從 Stream 繼承。)
CreateObjRef   創建一個對象,該對象包含生成用于與遠程對象進行通信的代理所需的全部相關信息。 (從 MarshalByRefObject 繼承。)
Dispose      已重載。
EndRead     等待掛起的異步讀取完成。 (從 Stream 繼承。)
EndWrite      結束異步寫操作。 (從 Stream 繼承。)
Flush        已重寫。 重寫 Stream.Flush 以便不執行任何操作。
GetBuffer     返回從其創建此流的無符號字節數組。 是會返回所有分配的字節,不管用沒用到。
GetLifetimeService      檢索控制此實例的生存期策略的當前生存期服務對象。 (從 MarshalByRefObject 繼承。)
InitializeLifetimeService   獲取控制此實例的生存期策略的生存期服務對象。 (從 MarshalByRefObject 繼承。)
Read            已重寫。 從當前流中讀取字節塊并將數據寫入 buffer 中。 搞了好久才弄明白Read()方法的含義,第一個參數,是讀取到的內容要輸出到的字節數組,第二個參數是放在第一個參數即要輸出的數組的位置的偏移量,第三個參數是,要讀取的字符數。 用這個方法你可以任意讀取一段需要的內存。注意,Read()方法是從當前流的Position屬性的位置開始讀,這就是為什么很多人測試的時候,剛剛寫入內存的數據,Read()方法無法讀取到內容的原因,因為剛剛寫入內存之后,位置恰好是在最后一位了。Read()方法當然讀不到。此方法強大之處在于,你可以從一個內存流中讀出你想要的一個片段。
ReadByte          已重寫。 從當前流中讀取一個字節。
Seek            已重寫。 將當前流中的位置設置為指定值。
SetLength          已重寫。 將當前流的長度設為指定值。
Synchronized        在指定的 Stream 對象周圍創建線程安全(同步)包裝。 (從 Stream 繼承。)
ToArray          將整個流內容寫入字節數組,而與 Position 屬性無關。
Write            已重寫。 使用從緩沖區讀取的數據將字節塊寫入當前流。 同樣注意下,第二個參數是第一個參數數組的偏移量就可以了。
WriteByte         已重寫。 將一個字節寫入當前流中的當前位置。
WriteTo          將此內存流的整個內容寫入另一個流中。

以下給出使用示例代碼:

static void Main(string[] args)
        {
            //屬性測試
            MemoryStream ms = new MemoryStream();
            Console.WriteLine(ms.CanRead);      //True  內存流可讀
            Console.WriteLine(ms.CanSeek);      //True  內存流支持查找,指針移來移去的查找
            Console.WriteLine(ms.CanTimeout);   //False 內存流不支持超時
            Console.WriteLine(ms.CanWrite);     //True  內存流可寫
 
            Console.WriteLine(ms.Capacity);     //0     分配給該流的字節數
            byte[] bytes = Encoding.UTF8.GetBytes("abcdedcba");
            ms.Write(bytes, 0, bytes.Length);   //已將一段文本寫入內存
            Console.WriteLine(ms.Capacity);     //256   再次讀取為文本流分配的字節數已經變成了256,看來內存流是根據需要的多少來分配的
            Console.WriteLine(ms.Length);       //9    這個是流長度,通常與英文的字符數一樣,真正占用的字節數。
 
            Console.WriteLine(ms.Position);     //9    流當前的位置,該屬性可讀可設置
 
            //Console.WriteLine(ms.ReadTimeout);    由于流不支持超時,此屬性如果讀取或者設置的話會報錯
            //Console.WriteLine(ms.WriteTimeout);   由于流不支持超時,此屬性如果讀取或者設置的話會報錯
 
            //方法測試
            byte[] byte1 = ms.GetBuffer();          //返回無符號字節數組 差點被忽悠了,無符號字節數組 其實就是byte(0~255),有符號字節sbyte(-128~127)
            string str1 = Encoding.UTF8.GetString(byte1);
            Console.WriteLine(str1);    //輸出    abcdedcba
 
            ms.Seek(2, SeekOrigin.Current);    //設置當前流正在讀取的位置 為開始位置即從0開始
            //從內存中讀取一個字節
            int i = ms.ReadByte();
            Console.WriteLine(i);                   //輸出99
            byte[] bytes3 = ms.ToArray();
            foreach (byte b in bytes3)
            {
                Console.Write(b + "-");//用于對比   輸出 97-98-99-100-101-100-99-98-97-   可以看到    0,1,2第二位剛好是99
            }
 
            MemoryStream ms2 = new MemoryStream();
            byte[] bytes6 = Encoding.UTF8.GetBytes("abcde");
            ms2.Write(bytes6, 0, bytes6.Length);
            Console.WriteLine(ms2.Position);    //輸出5 寫完之后流的位置就到了最后,因此想用read讀取必須加下面這一行代碼。 
 
            //ms2.Seek(0, SeekOrigin.Begin);    //想要用Read方法讀取完整的流,必須設置當前位置,Read是從Position的位置開始讀。
            ms2.Position = 0;                   //Read是從當前位置開始讀,這行代碼和上面一行意義一樣。
            byte[] byteArray = new byte[5] { 110, 110, 110, 110, 110 }; //99是經過YTF8解碼之后是 n
            ms2.Read(byteArray, 2, 1);   //讀取一個字節,byteArray的第一個元素中,(注意從0開始)
            Console.WriteLine(Encoding.UTF8.GetString(byteArray)); //nnann
            //ms2.Read(byteArray, 2, 2);
            //Console.WriteLine(Encoding.UTF8.GetString(byteArray)); //nnabn    //當超出接收數組總長度的時候,后面的元素會被移開
 
 
            //設置當前流的長度
            Console.WriteLine(ms.Length);   //輸出9   當前流的長度是9
            ms.SetLength(20);
            Console.WriteLine(ms.Length);   //輸出20
            foreach (byte b in ms.ToArray())    //將流的內容也就是內存中的內容轉換字節數組
            {
                Console.Write(b + "-");     //輸出 97-98-99-100-101-100-99-98-97-0-0-0-0-0-0-0-0-0 由于設置了長度,因此空的自動補0
            }
            Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));   //輸出    abcdedcba   雖然長度變長了,但是沒影響讀取數據
 
            MemoryStream ms1 = new MemoryStream();
            byte[] bytes4 = ms1.ToArray();
            Console.WriteLine("此內存流并沒有寫入數據(Write)" + Encoding.UTF8.GetString(bytes4));//輸出    此內存流并沒有寫入數據(Write)  因為內存為空
 
 
            //下面來一個指定位置的寫入
            MemoryStream ms3 = new MemoryStream();
            byte[] bytesArr = Encoding.ASCII.GetBytes("abcdefg");
            ms3.Write(bytesArr, 0, bytesArr.Length);
            ms3.Position = 2;
            ms3.WriteByte(97);  //97代表的是a   這段代碼的意思是,將原先第二個的c替換為a
            string str = Encoding.ASCII.GetString(ms3.ToArray());
            Console.WriteLine(str); //輸出 abacdefg
            
            byte[] byteArr1 = Encoding.ASCII.GetBytes("kk");
            ms3.Position = 4;
            ms3.Write(byteArr1, 0, byteArr1.Length);
            Console.WriteLine(Encoding.UTF8.GetString(ms3.ToArray()));  //abadkkg   //從第4位替換掉了兩個字節為KK
 
            Console.ReadKey();
        }

接下來實現數據類的轉換:

using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
 
public class DataSwitch
{
 
    /// <summary>
    /// 數據類對象轉成字節流
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    ///   //MemoryStream: 創建其支持存儲區為內存的流。
        //IFormatter : 提供將序列化對象格式化的功能。
    public static byte[] ObjectToBytes(object obj)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            // //以二進制格式將對象或整個連接對象圖形序列化和反序列化。
            IFormatter formatter = new BinaryFormatter();
            //把字符串以二進制放進memStream中
            formatter.Serialize(ms, obj);
            //返回從其創建此流的無符號字節數組。 是會返回所有分配的字節,不管用沒用到。
            返回無符號字節數組 ,無符號字節數組 其實就是byte(0~255),有符號字節sbyte(-128~127)
            return ms.GetBuffer();
        }
    }
 
    /// <summary>
    /// 字節流轉成數據類對象
    /// </summary>
    /// <param name="bytes"></param>
    /// <returns></returns>
    public static object BytesToObject(byte[] bytes)
    {
        using (MemoryStream ms = new MemoryStream(bytes))
        { 
            // //以二進制格式將對象或整個連接對象圖形序列化和反序列化。
            IFormatter formatter = new BinaryFormatter();
            //把字符串以二進制放進memStream中
            return formatter.Deserialize(ms);
        }
    }
}

關于“C#中MemoryStream類怎么用”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

泸溪县| 鄢陵县| 福鼎市| 高雄市| 酉阳| 南丹县| 香格里拉县| 岐山县| 隆子县| 雷山县| 滨州市| 界首市| 昌平区| 剑阁县| 休宁县| 扎囊县| 太湖县| 丽江市| 泰来县| 高要市| 隆德县| 曲阳县| 凤城市| 石城县| 荥经县| 德阳市| 广河县| 墨脱县| 理塘县| 清远市| 株洲市| 正阳县| 吉安县| 深泽县| 晋宁县| 高陵县| 太湖县| 彰化市| 贵州省| 怀仁县| 禄丰县|