2013-10-02 13 views
12

Wiem, jak kodować/dekodować prosty ciąg do/z base64.Zakoduj FileStream do base64 za pomocą C#

Ale jak to zrobić, jeśli dane zostały już zapisane do obiektu FileStream. Załóżmy, że mam tylko dostęp do obiektu FileStream, a nie do wcześniej zapisanych w nim oryginalnych danych. W jaki sposób mogę kodować FileStream do base64, zanim opróżnię plik FileStream do pliku.

Ofc Mogę po prostu otworzyć mój plik i zakodować/odkodować go po napisaniu FileStream do pliku, ale chciałbym zrobić to wszystko w jednym kroku bez wykonywania dwóch operacji na plikach jeden po drugim. Plik może być większy, a jego załadowanie, zakodowanie i zapisanie zajęłoby podwójnie dużo czasu, po tym, jak został właśnie zapisany na krótko.

Może ktoś z was zna lepsze rozwiązanie? Czy mogę przekonwertować obiekt FileStream na ciąg znaków, zakodować ciąg znaków, a następnie przekonwertować ciąg z powrotem na obiekt FileStream lub na przykład, co powinienem zrobić i jak będzie wyglądał taki kod?

+1

nie jestem pewien, że całkowicie rozumiem pytanie, ale jest to możliwe, aby korzystać z wbudowanych -in klas, aby zapewnić strumień, który przekształci dane binarne na dane z bazy 64 lub z nich. Następnie możesz wstawić taki strumień między twoimi zapisami i strumieniem wyjściowym pliku (tak jak zwykle robi się to przy kompresji strumieni i szyfrowaniu strumieni). Przykład znajduje się tutaj: http://netpl.blogspot.co.uk/2011/05/builtin-base64-streaming.html –

+0

Możliwy duplikat [Jak przekształcić strumień w bajt \ [\] w C#?] (http://stackoverflow.com/questions/1080442/how-to-convert-an-stream-into-a-byte-in-c) – Liam

+0

Możliwy duplikat [Czy istnieje Base64Stream dla .NET? gdzie?] (http://stackoverflow.com/questions/2525533/is-there-a-base64stream-for-net-where) – xmedeko

Odpowiedz

2

Ponieważ plik będzie większy, nie masz dużego wyboru, jak to zrobić. Nie możesz przetworzyć pliku, ponieważ spowoduje to zniszczenie informacji, których potrzebujesz. Masz dwie opcje, które mogę zobaczyć:

  1. Odczytaj w całym pliku, kodowanie base64, przepisz ponownie zakodowane dane.
  2. Odczytaj plik w mniejszych fragmentach, koduj zgodnie z przebiegiem. Koduje do pliku tymczasowego w tym samym katalogu. Po zakończeniu usuń oryginalny plik i zmień nazwę pliku tymczasowego.

Oczywiście, celem strumieni jest uniknięcie tego rodzaju scenariusza. Zamiast tworzyć zawartość i wpychać ją do strumienia plików, wstaw ją do strumienia pamięci. Następnie zakoduj to i dopiero potem zapisz na dysku.

10

Można spróbować czegoś jak że:

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

Skąd się bierze 1.34? – DanDan

+2

Bajt zawiera 8 bitów. Base64 nie używa bajtów ale znaków. Nie żadnych znaków, ale konkretnych znaków, które można przekonwertować na 6 bitów.Więc tablica jest mniejsza niż nasza tablica o czynnik 6/8. 8 podzielone przez 6 to 1,33333, więc jeśli weźmiesz 1,34, out-array będzie zawsze wystarczająco duży. – user1884155

+1

Musisz pobrać nowy rozmiar z 'Convert.ToBase64CharArray', a następnie wykonaj' Array.Resize (ref base64Chars, newSize); '. W przeciwnym razie masz dodatkowe bajty w końcowym wyjściu. – toddmo

5

łatwa jako metodę rozszerzenia

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)); 
    } 
}