五月综合缴情婷婷六月,色94色欧美sute亚洲线路二,日韩制服国产精品一区,色噜噜一区二区三区,香港三级午夜理伦三级三

您現(xiàn)在的位置: 365建站網(wǎng) > 365文章 > C#使用MemoryStream類(lèi)讀寫(xiě)內(nèi)存

C#使用MemoryStream類(lèi)讀寫(xiě)內(nèi)存

文章來(lái)源:365jz.com     點(diǎn)擊數(shù):877    更新時(shí)間:2018-06-04 21:02   參與評(píng)論

MemoryStream和BufferedStream都派生自基類(lèi)Stream,因此它們有很多共同的屬性和方法,但是每一個(gè)類(lèi)都有自己獨(dú)特的用法。這兩個(gè)類(lèi)都是實(shí)現(xiàn)對(duì)內(nèi)存進(jìn)行數(shù)據(jù)讀寫(xiě)的功能,而不是對(duì)持久性存儲(chǔ)器進(jìn)行讀寫(xiě)。

讀寫(xiě)內(nèi)存-MemoryStream類(lèi)

MemoryStream類(lèi)用于向內(nèi)存而不是磁盤(pán)讀寫(xiě)數(shù)據(jù)。MemoryStream封裝以無(wú)符號(hào)字節(jié)數(shù)組形式存儲(chǔ)的數(shù)據(jù),該數(shù)組在創(chuàng)建MemoryStream對(duì)象時(shí)被初始化,或者該數(shù)組可創(chuàng)建為空數(shù)組??稍趦?nèi)存中直接訪問(wèn)這些封裝的數(shù)據(jù)。內(nèi)存流可降低應(yīng)用程序中對(duì)臨時(shí)緩沖區(qū)和臨時(shí)文件的需要。

下表列出了MemoryStream類(lèi)的重要方法:

1、Read():讀取MemoryStream流對(duì)象,將值寫(xiě)入緩存區(qū)。

2、ReadByte():從MemoryStream流中讀取一個(gè)字節(jié)。

3、Write():將值從緩存區(qū)寫(xiě)入MemoryStream流對(duì)象。

4、WriteByte():從緩存區(qū)寫(xiě)入MemoytStream流對(duì)象一個(gè)字節(jié)。

Read方法使用的語(yǔ)法如下:

mmstream.Read(byte[] buffer,offset,count)


其中mmstream為MemoryStream類(lèi)的一個(gè)流對(duì)象,3個(gè)參數(shù)中,buffer包含指定的字節(jié)數(shù)組,該數(shù)組中,從offset到(offset +count-1)之間的值由當(dāng)前流中讀取的字符替換。Offset是指Buffer中的字節(jié)偏移量,從此處開(kāi)始讀取。Count是指最多讀取的字節(jié)數(shù)。Write()方法和Read()方法具有相同的參數(shù)類(lèi)型。


MemoryStream類(lèi)的使用實(shí)例:

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.IO;  
  
namespace ConsoleApplication1  
{  
    class Program  
    {  
        static void Main()  
        {   
            int count;   
            byte[] byteArray;   
            char[] charArray;  
            UnicodeEncoding uniEncoding = new UnicodeEncoding();  
            // Create the data to write to the stream.  
            byte[] firstString = uniEncoding.GetBytes("一二三四五");   
            byte[] secondString = uniEncoding.GetBytes("上山打老虎");   
            using (MemoryStream memStream = new MemoryStream(100))  
            {   
                // Write the first string to the stream.  
                memStream.Write(firstString, 0, firstString.Length);   
  
                // Write the second string to the stream, byte by byte.  
                count = 0;  
                while (count < secondString.Length)   
                {  
                    memStream.WriteByte(secondString[count++]);   
                }   
  
                // Write the stream properties to the console.  
                Console.WriteLine("Capacity={0},Length={1},Position={2}\n", memStream.Capacity.ToString(), memStream.Length.ToString(), memStream.Position.ToString());  
  
                // Set the position to the beginning of the stream.  
                memStream.Seek(0, SeekOrigin.Begin);  
  
                // Read the first 20 bytes from the stream.  
                byteArray = new byte[memStream.Length];   
                count = memStream.Read(byteArray, 0, 20);   
  
                // Read the remaining bytes, byte by byte.  
                while (count < memStream.Length)   
                {   
                    byteArray[count++] = Convert.ToByte(memStream.ReadByte());  
                }   
  
                // Decode the byte array into a char array  
                // and write it to the console.  
                charArray = new char[uniEncoding.GetCharCount(byteArray, 0, count)];   
                uniEncoding.GetDecoder().GetChars(byteArray, 0, count, charArray, 0);   
                Console.WriteLine(charArray); Console.ReadKey();  
            }  
        }  
    }  
}



在這個(gè)實(shí)例代碼中使用了using關(guān)鍵字。注意:

using 關(guān)鍵字有兩個(gè)主要用途:

1、作為指令,用于為命名空間創(chuàng)建別名或?qū)肫渌臻g中定義的類(lèi)型。

例如:


using System; 

2、作為語(yǔ)句,用于定義一個(gè)范圍,在此范圍的末尾將釋放對(duì)象。


using(Connection conn=new Connection(connStr))  

{  

}  

//使用using關(guān)鍵字可及時(shí)銷(xiāo)毀對(duì)象 

MemoryStream.Capacity 屬性 取得或設(shè)定配置給這個(gè)資料流的位元組數(shù)目。

MemoryStream.Position 屬性 指定當(dāng)前流的位置。

MemoryStream.Length 屬性獲取用字節(jié)表示的流長(zhǎng)度。

SeekOrigin()是一個(gè)枚舉類(lèi),作用設(shè)定流的一個(gè)參數(shù)。

SeekOrigin.Begin我得理解就是文件的最開(kāi)始,“0”是偏移,表示跳過(guò)0個(gè)字節(jié)。寫(xiě)2就是跳過(guò)2個(gè)字節(jié)。

MemoryStream類(lèi)通過(guò)字節(jié)讀寫(xiě)數(shù)據(jù)。本例中定義了寫(xiě)入的字節(jié)數(shù)組,為了更好的說(shuō)明Write和WriteByte的異同,在代碼中聲明了兩個(gè)byte數(shù)組,其中一個(gè)數(shù)組寫(xiě)入時(shí)調(diào)用Write方法,通過(guò)指定該方法的三個(gè)參數(shù)實(shí)現(xiàn)如何寫(xiě)入。

另一個(gè)數(shù)組調(diào)用了WriteByte方法,每次寫(xiě)入一個(gè)字節(jié),所以采用while循環(huán)來(lái)完成全部字節(jié)的寫(xiě)入。寫(xiě)入MemoryStream后,可以檢索該流的容量,實(shí)際長(zhǎng)度,當(dāng)前流的位置,將這些值輸出到控制臺(tái)。通過(guò)觀察結(jié)果,可以確定寫(xiě)入MemoryStream流是否成功。

調(diào)用Read和ReadByte兩種方法讀取MemoryStream流中的數(shù)據(jù),并將其進(jìn)行Unicode編碼后輸出到控制臺(tái)。







讀取內(nèi)存流中的數(shù)據(jù)


在.NET中,使用抽象基類(lèi)System.IO.Stream代表流,它提供Read和Write兩個(gè)方法。由于數(shù)據(jù)流的有序性,因此流對(duì)象還有一個(gè)讀寫(xiě)指針,為此,Stream類(lèi)還有一個(gè)Seek方法用于移動(dòng)讀寫(xiě)指針。  

字符串與字節(jié)數(shù)組間的互相轉(zhuǎn)化:


string str = "內(nèi)存大小";  
byte[] temp = Encoding.UTF8.GetBytes (str);        // 字符串轉(zhuǎn)化為字節(jié)數(shù)組  
string s = Encoding.UTF8.GetString (temp);        // 字節(jié)數(shù)組轉(zhuǎn)化為字符串  
Debug.Log (s);

 

Encoding用法比較簡(jiǎn)單,如果只是字節(jié)和字符的互相轉(zhuǎn)換,GetBytes()和GetChars()這兩個(gè)方法及它們的重載基本上會(huì)滿(mǎn)足你所有要求。

GetByteCount()及其重載是得到一個(gè)字符串轉(zhuǎn)換成字節(jié)時(shí)實(shí)際的字節(jié)個(gè)數(shù)。

GetCharCount()及其重載是得到一個(gè)字節(jié)數(shù)組轉(zhuǎn)換成字符串的大小。

Decoder.GetChars 方法

Decoder.GetChars (Byte[], Int32, Int32, Char[], Int32)

在派生類(lèi)中重寫(xiě)時(shí),將指定字節(jié)數(shù)組的字節(jié)序列和內(nèi)部緩沖區(qū)中的任何字節(jié)解碼到指定的字符數(shù)組。

在派生類(lèi)中重寫(xiě)時(shí),將一個(gè)字節(jié)序列解碼為一組字符。


Java里一個(gè)byte取值范圍是-128~127, 而C#里一個(gè)byte是0~255.

首位不同. 但是底層I/O存儲(chǔ)的數(shù)據(jù)是一樣的


FileStream對(duì)象的數(shù)據(jù)來(lái)自文件,而MemoryStream對(duì)象的數(shù)據(jù)來(lái)自?xún)?nèi)存緩沖區(qū)。這兩個(gè)類(lèi)都繼承自Stream類(lèi)。 

MemoryStream的數(shù)據(jù)來(lái)自?xún)?nèi)存中的一塊連續(xù)區(qū)域,這塊區(qū)域稱(chēng)為“緩沖區(qū)(Buffer)”。可以把緩沖區(qū)看成一個(gè)數(shù)組,每個(gè)數(shù)組元素可以存放一個(gè)字節(jié)的數(shù)據(jù)。

在創(chuàng)建MemoryStream對(duì)象時(shí),可以指定緩沖區(qū)的大小,并且可以在需要的時(shí)候更改。  

//字節(jié)數(shù)組  
         byte[] buffer = new byte[600];  
 //填充字節(jié)數(shù)組  
         private void CreateExampleData()  
         {  
             for(int i=0; i<600; i++)  
             {  
                 //byte類(lèi)型的數(shù)最大不能超過(guò)255,用256取模實(shí)現(xiàn)  
                  buffer[i] = (byte)(i%256);  
              }              
          }

內(nèi)存流的基本使用方法:  

 private void OnTestMemory()  
         {  
             //創(chuàng)建測(cè)試數(shù)據(jù)  
              CreateExampleData();  
               
             //創(chuàng)建內(nèi)存流對(duì)象,初始分配50字節(jié)的緩沖區(qū)  
              MemoryStream mem = new MemoryStream(50);  
  
             //向內(nèi)存流中寫(xiě)入字節(jié)數(shù)組的所有數(shù)據(jù)  
              mem.Write(buffer,0,buffer.GetLength(0));  
   
              MessageBox.Show("寫(xiě)入數(shù)據(jù)后的內(nèi)存流長(zhǎng)度:" + mem.Length.ToString());  
              MessageBox.Show("分配給內(nèi)存流的緩沖區(qū)大?。?quot; + mem.Capacity.ToString());  
   
              mem.SetLength(550);  
   
              MessageBox.Show("調(diào)用SetLength方法后的內(nèi)存流長(zhǎng)度:" + mem.Length.ToString());  
   
              mem.Capacity = 620;//此值不能小于Length屬性  
              MessageBox.Show("調(diào)用Capacity方法后緩沖區(qū)大?。?quot; + mem.Capacity.ToString());  
   
             //將讀寫(xiě)指針移到距流開(kāi)頭10個(gè)字節(jié)的位置  
              mem.Seek(10,SeekOrigin.Begin);  
              MessageBox.Show(mem.ReadByte().ToString());  
              mem.Close();  
          }

內(nèi)存流的Length屬性代表了其中存放的數(shù)據(jù)的真實(shí)長(zhǎng)度,而Capacity屬性則代表了分配給內(nèi)存流的內(nèi)存空間大小。  

可以使用字節(jié)數(shù)組創(chuàng)建一個(gè)固定大小的MemoryStream,  

 MemoryStream mem = new MemoryStream(buffer);  

這時(shí),無(wú)法再設(shè)置Capacity屬性的大小。  

還可以創(chuàng)建只讀的內(nèi)存流對(duì)象。  

 MemoryStream mem = new MemoryStream(buffer,false);  

  

FlieStream用于存取文件。  

創(chuàng)建文件并寫(xiě)入內(nèi)容:  

 //創(chuàng)建一個(gè)新文件  
              FileStream fsForWrite = new FileStream("test.data",FileMode.Create);  
             try  
             {      
                 //寫(xiě)入一個(gè)字節(jié)  
                  fsForWrite.WriteByte(100);  
                  CreateExampleData();  
                 //將字節(jié)數(shù)組寫(xiě)入文件  
                  fsForWrite.Write(buffer,0,buffer.GetLength(0));  
              }  
             catch(Exception ex)  
             {      
                  MessageBox.Show(ex.Message);  
              }  
             finally  
             {  
                 //關(guān)閉文件  
                  fsForWrite.Close();  
              }

打開(kāi)文件并讀取內(nèi)容:  

 private void ReadFromFile()  
         {  
              FileStream fsForRead = new FileStream("test.data",FileMode.Open);  
             try  
             {  
                 //讀入一個(gè)字節(jié)  
                  MessageBox.Show("文件的第一個(gè)字節(jié)為:"+fsForRead.ReadByte().ToString());  
                 //讀寫(xiě)指針移到距開(kāi)頭10個(gè)字節(jié)處  
                  fsForRead.Seek(10,SeekOrigin.Begin);  
                 byte[] bs = new byte[10];  
                 //從文件中讀取10個(gè)字節(jié)放到數(shù)組bs中  
                  fsForRead.Read(bs,0,10);  
              }  
             catch(Exception ex)  
             {      
                  MessageBox.Show(ex.Message);  
              }  
             finally  
             {  
                  fsForRead.Close();         }  
          }

如果一個(gè)程序退出了,但它打開(kāi)的文件沒(méi)有被關(guān)閉,將導(dǎo)致其他程序無(wú)法修改或刪除此文件。   



FileStream與MemoryStream間的相互作用:

-----解決方案--------------------

 FileStream fs = new FileStream(path, FileMode.Open); 
  byte[] data = new byte[fs.Length]; 
  fs.Read(data, 0, data.Length); 
  fs.Close();
  MemoryStream ms = new MemoryStream(data);


------解決方案--------------------

 ///定義并實(shí)例化一個(gè)內(nèi)存流,以存放圖片的字節(jié)數(shù)組。 
 MemoryStream m = new MemoryStream(); 
 ///獲得當(dāng)前路徑 
 string strAppPath = AppDomain.CurrentDomain.BaseDirectory; //獲得可執(zhí)行文件的路徑。 
 ///獲得圖片路徑  
 string strPath = strAppPath + "img\\default.jpg";  
 ///圖片讀入FileStream  
 FileStream f = new FileStream(strPath, FileMode.open);  
 ///把FileStream寫(xiě)入MemoryStream  
 m.SetLength(f.Length);  
 f.Read(m.GetBuffer(), 0, (int)f.Length);  
 m.Flush();  
 f.Close();



------解決方案--------------------
          FileStream fs = new FileStream(fileName, FileMode.Open);
           byte[] MyData = new byte[fs.Length];
           fs.Read(MyData, 0, (int)fs.Length);
           fs.Close();
           MemoryStream ms = new MemoryStream(MyData);
------解決方案--------------------
MemoryStream ms = new MemoryStream(File.ReadAllBytes("c:\\1.jpg"));


另外在做BCP項(xiàng)目的時(shí)候,沒(méi)有遇到數(shù)據(jù)庫(kù),全部是從內(nèi)存取的數(shù)據(jù)

現(xiàn)提供從內(nèi)存取數(shù)據(jù)的方法:,這個(gè)是我從網(wǎng)上copy的

因?yàn)槿毡镜哪莻€(gè)項(xiàng)目,我們用的是c++程序讀寫(xiě)共有內(nèi)存,有一個(gè)c++寫(xiě)的dll文件

我們調(diào)用那個(gè)文件即可.


using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace CrazyCoder.ShareMemLib
{
public class ShareMem
{
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, IntPtr lParam);

[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr CreateFileMapping(int hFile, IntPtr lpAttributes, uint flProtect, uint dwMaxSizeHi, uint dwMaxSizeLow, string lpName);

[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr OpenFileMapping(int dwDesiredAccess,[MarshalAs(UnmanagedType.Bool)] bool bInheritHandle,string lpName);

[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr MapViewOfFile(IntPtr hFileMapping,uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow,uint dwNumberOfBytesToMap);

[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool UnmapViewOfFile(IntPtr pvBaseAddress);

[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);

[DllImport("kernel32", EntryPoint="GetLastError")]
public static extern int GetLastError ();

const int ERROR_ALREADY_EXISTS = 183;

const int FILE_MAP_COPY = 0x0001;
const int FILE_MAP_WRITE = 0x0002;
const int FILE_MAP_READ = 0x0004;
const int FILE_MAP_ALL_ACCESS = 0x0002 | 0x0004;

const int PAGE_READONLY = 0x02;
const int PAGE_READWRITE = 0x04;
const int PAGE_WRITECOPY = 0x08;
const int PAGE_EXECUTE = 0x10;
const int PAGE_EXECUTE_READ = 0x20;
const int PAGE_EXECUTE_READWRITE = 0x40;

const int SEC_COMMIT = 0x8000000;
const int SEC_IMAGE = 0x1000000;
const int SEC_NOCACHE = 0x10000000;
const int SEC_RESERVE = 0x4000000;

const int INVALID_HANDLE_VALUE = -1;

IntPtr m_hSharedMemoryFile = IntPtr.Zero;
IntPtr m_pwData = IntPtr.Zero;
bool m_bAlreadyExist = false;
bool m_bInit = false;
long m_MemSize=0;

public ShareMem()
{
}
~ShareMem()
{
Close();
}

/// 
/// 初始化共享內(nèi)存
/// 
/// 共享內(nèi)存名稱(chēng)
/// 共享內(nèi)存大小
/// 
public int Init(string strName, long lngSize)
{
if (lngSize <= 0 || lngSize > 0x00800000) lngSize = 0x00800000;
m_MemSize = lngSize;
if (strName.Length > 0)
{
//創(chuàng)建內(nèi)存共享體(INVALID_HANDLE_VALUE)
m_hSharedMemoryFile = CreateFileMapping(INVALID_HANDLE_VALUE, IntPtr.Zero, (uint)PAGE_READWRITE, 0, (uint)lngSize, strName);
if (m_hSharedMemoryFile == IntPtr.Zero)
{
m_bAlreadyExist = false;
m_bInit = false;
return 2; //創(chuàng)建共享體失敗
}
else
{
if (GetLastError() == ERROR_ALREADY_EXISTS) //已經(jīng)創(chuàng)建
{
m_bAlreadyExist = true;
}
else //新創(chuàng)建
{
m_bAlreadyExist = false;
}
}
//---------------------------------------
//創(chuàng)建內(nèi)存映射
m_pwData = MapViewOfFile(m_hSharedMemoryFile, FILE_MAP_WRITE, 0, 0, (uint)lngSize);
if (m_pwData == IntPtr.Zero)
{
m_bInit = false;
CloseHandle(m_hSharedMemoryFile);
return 3; //創(chuàng)建內(nèi)存映射失敗
}
else
{
m_bInit = true;
if (m_bAlreadyExist == false)
{
//初始化
}
}
//----------------------------------------
}
else
{
return 1; //參數(shù)錯(cuò)誤 
}

return 0; //創(chuàng)建成功
}
/// 
/// 關(guān)閉共享內(nèi)存
/// 
public void Close()
{
if (m_bInit)
{
UnmapViewOfFile(m_pwData);
CloseHandle(m_hSharedMemoryFile);
}
}

/// 
/// 讀數(shù)據(jù)
/// 
/// 數(shù)據(jù)
/// 起始地址
/// 個(gè)數(shù)
/// 
public int Read(ref byte[] bytData, int lngAddr, int lngSize)
{
if (lngAddr + lngSize > m_MemSize) return 2; //超出數(shù)據(jù)區(qū)
if (m_bInit)
{ 
Marshal.Copy(m_pwData, bytData, lngAddr, lngSize);
}
else
{
return 1; //共享內(nèi)存未初始化
}
return 0; //讀成功
}

/// 
/// 寫(xiě)數(shù)據(jù)
/// 
/// 數(shù)據(jù)
/// 起始地址
/// 個(gè)數(shù)
/// 
public int Write(byte[] bytData, int lngAddr, int lngSize)
{
if (lngAddr + lngSize > m_MemSize) return 2; //超出數(shù)據(jù)區(qū)
if (m_bInit)
{
Marshal.Copy(bytData, lngAddr, m_pwData, lngSize);
}
else
{
return 1; //共享內(nèi)存未初始化
}
return 0; //寫(xiě)成功
}
}
}

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using ShareMemLib;

namespace YFShareMem
{
public partial class frmShareMem : Form
{
ShareMem MemDB=new ShareMem();
public frmShareMem()
{
InitializeComponent();
}

private void btnOpen_Click(object sender, EventArgs e)
{
if (MemDB.Init("YFMemTest", 10240) != 0)
{
//初始化失敗
MessageBox.Show("初始化失敗");
}
else
{
btnOpen.Enabled = false;
chkWrite.Enabled = true;
tmrTime.Enabled = true;
}
}

private void tmrTime_Tick(object sender, EventArgs e)
{
byte[] bytData = new byte[16];
int intRet = MemDB.Read(ref bytData, 0, 16);
lstData.Items.Clear(); 
if (intRet == 0)
{
for (int i = 0; i < 16; i++)
{
lstData.Items.Add(bytData[i].ToString());
}

if (chkWrite.Checked)
{
bytData[0]++;
bytData[1] += 2;
if (bytData[0] > 200) bytData[0] = 0;
if (bytData[1] > 200) bytData[1] = 0;
MemDB.Write(bytData, 0, 16);
}
} 
}

}
}


如對(duì)本文有疑問(wèn),請(qǐng)?zhí)峤坏浇涣髡搲?,廣大熱心網(wǎng)友會(huì)為你解答?。?點(diǎn)擊進(jìn)入論壇

發(fā)表評(píng)論 (877人查看0條評(píng)論)
請(qǐng)自覺(jué)遵守互聯(lián)網(wǎng)相關(guān)的政策法規(guī),嚴(yán)禁發(fā)布色情、暴力、反動(dòng)的言論。
昵稱(chēng):
最新評(píng)論
------分隔線----------------------------

其它欄目

· 建站教程
· 365學(xué)習(xí)

業(yè)務(wù)咨詢(xún)

· 技術(shù)支持
· 服務(wù)時(shí)間:9:00-18:00
365建站網(wǎng)二維碼

Powered by 365建站網(wǎng) RSS地圖 HTML地圖

copyright © 2013-2024 版權(quán)所有 鄂ICP備17013400號(hào)