2012-07-25 191 views
3

只是爲了澄清事情。我是而不是試圖將字節數組轉換爲單個字符串。我試圖將字節數組轉換爲字符串數組。如何將字節數組轉換爲字符串數組?

我使用GetClipboardData API從剪貼板獲取一些數據,然後我將數據從內存複製爲字節數組。當你複製多個文件(因此爲CF_HDROP剪貼板格式)時,我想將此字節數組轉換爲複製文件的字符串數組。

這是我的代碼到目前爲止。

//Get pointer to clipboard data in the selected format 
var clipboardDataPointer = GetClipboardData(format); 

//Do a bunch of crap necessary to copy the data from the memory 
//the above pointer points at to a place we can access it. 
var length = GlobalSize(clipboardDataPointer); 
var @lock = GlobalLock(clipboardDataPointer); 

//Init a buffer which will contain the clipboard data 
var buffer = new byte[(int)length]; 

//Copy clipboard data to buffer 
Marshal.Copy(@lock, buffer, 0, (int)length); 

GlobalUnlock(clipboardDataPointer); 

snapshot.InsertData(format, buffer); 

現在,這裏是我之後讀取緩衝區數據的代碼。

var formatter = new BinaryFormatter(); 
using (var serializedData = new MemoryStream(buffer)) 
{ 
    paths = (string[]) formatter.Deserialize(serializedData); 
} 

這是行不通的,它會用一個異常說,流不包含二進制頭崩潰。我想這是因爲它不知道要反序列化的類型。

我試過看Marshal類。沒有什麼關係。

+0

你思考['Clipboard.GetFileDropList()'](http://msdn.microsoft.com/en-us/library/system.windows.forms.clipboard。 getfiledroplist.aspx)? – GSerg 2012-07-25 19:11:10

+0

是的,但我想單獨使用Windows API,因爲WPF中的常規剪貼板功能有問題,正如Web上的許多地方所述。 – 2012-07-25 19:12:09

回答

2

如果數據通過Win32 API傳遞,那麼字符串數組將只是一個以null結尾的字符串序列,並在末尾帶有一個雙空終止符。 (注意字符串將是UTF-16,所以兩個字符每個字符字節)。你基本上需要一次將一個字符串拉出到一個數組中。

您在此尋找的方法是Marshal.PtrToStringUni,您應該使用該方法,而不是Marshal.Copy,因爲它適用於IntPtr。它將從您的IntPtr中提取一個字符串,直到第一個空字符,並將其複製到字符串中。

想法是繼續提取單個字符串,然後將IntPtr超過空字節前進到下一個字符串的開頭,直到您用完緩衝區。我已經沒有進行了測試,它也許可以改善(尤其是我覺得有檢測緩衝區的末尾一個更聰明的方式),但基本的想法是:

var myptr = GetClipboardData(format); 
var length = GlobalSize(myptr); 

var result = new List<string>(); 

var pos = 0; 
while (pos < length) 
{ 
    var str = Marshal.PtrToStringUni(myptr); 
    var count = Encoding.Unicode.GetByteCount(str); 

    myptr = IntPtr.Add(myptr, count + 1); 
    pos += count + 1; 

    result.Add(str); 
} 

return result.ToArray(); 

(順便說一句:你的反序列化不起作用的原因是因爲序列化一個string[]不只是將字符寫成字節;而是寫出了一個字符串數組的結構,包括.NET使用的其他內部位,如長度,以及帶有類型信息的二進制頭文件。從剪貼板返回的內容不存在,因此無法反序列化。)

1

如何:

var strings = Encoding.Unicode 
    .GetString(buffer) 
    .Split(new[] { '\0' }, StringSplitOptions.RemoveEmptyEntries); 
相關問題