2013-10-02 44 views
12

我知道如何編碼/解碼一個簡單的字符串到/從base64用c編碼一個FileStream到base64#

但是,如果數據已被寫入FileStream對象,我該怎麼辦。比方說,我只能訪問FileStream對象而不能訪問之前存儲的原始數據。在將FileStream刷新到文件之前,如何將FileStream編碼爲base64

Ofc我可以在將文件流寫入文件後打開我的文件並對其進行編碼/解碼,但我希望一步完成所有操作,而無需一個接一個地執行兩個文件操作。該文件可能會更大,並且需要兩倍的時間才能加載,編碼並在之前很短時間保存之後再次保存。

也許你有人知道更好的解決方案?我可以將FileStream轉換爲字符串,對字符串進行編碼,然後將字符串轉換回FileStream爲例,或者我會做什麼以及這樣的代碼是怎麼樣的?

+1

我不知道我完全理解你的問題,但它可以使用內置在類中提供一個將二進制數據轉換爲基本數據或從基本數據轉換爲二進制數據的流。然後,您可以在寫入和文件輸出流之間插入一個這樣的流(例如通常用於壓縮流和加密流)。一個例子是在這裏:http://netpl.blogspot.co.uk/2011/05/builtin-base64-streaming.html –

+0

[如何將流轉換爲C#中的字節\ [\]?]( http://stackoverflow.com/questions/1080442/how-to-convert-an-stream-into-a-byte-in-c) – Liam

+0

可能的重複[是否有Base64Stream for .NET?在哪裏?](http://stackoverflow.com/questions/2525533/is-there-a-base64stream-for-net-where) – xmedeko

回答

2

由於文件會更大,因此在如何執行此操作時沒有太多選擇。您無法就地處理文件,因爲這會破壞您需要使用的信息。你有兩個選項,我可以看到:

  1. 在整個文件中讀取base64編碼,重新編寫編碼數據。
  2. 以較小的塊閱讀文件,隨着編碼進行編碼。編碼到同一目錄中的臨時文件。完成後,刪除原始文件並重命名臨時文件。

當然,流的整點是爲了避免這種情況。不是創建內容並將其填充到文件流中,而是將其填充到內存流中。然後編碼並只保存到磁盤。

10

你可以嘗試一些說:

public Stream ConvertToBase64(Stream stream) 
    { 
     Byte[] inArray = new Byte[(int)stream.Length]; 
     Char[] outArray = new Char[(int)(stream.Length * 1.34)]; 
     stream.Read(inArray, 0, (int)stream.Length); 
     Convert.ToBase64CharArray(inArray, 0, inArray.Length, outArray, 0); 
     return new MemoryStream(Encoding.UTF8.GetBytes(outArray)); 
    } 
+4

1.34從哪裏來? – DanDan

+2

一個字節保存8位。 base64不使用字節,而是字符。不是任何字符,但可以轉換爲6位的特定字符。所以數組內的數組比我們的數組小6/8。 8除以6就是1,33333,所以如果你取1.34,out數組總是會足夠大。 – user1884155

+1

您需要從'Convert.ToBase64CharArray'獲取新大小,然後執行'Array.Resize (ref base64Chars,newSize);'。否則,您在最終輸出中會有額外的字節。 – toddmo

5

一個容易的擴展方法

public static class Extensions 
{ 
    public static Stream ConvertToBase64(this Stream stream) 
    { 
     byte[] bytes; 
     using (var memoryStream = new MemoryStream()) 
     { 
      stream.CopyTo(memoryStream); 
      bytes = memoryStream.ToArray(); 
     } 

     string base64 = Convert.ToBase64String(bytes); 
     return new MemoryStream(Encoding.UTF8.GetBytes(base64)); 
    } 
}