Ответ 1
Вы также можете кодировать байты в Base64. Как получить это из потока, см. Здесь: Как преобразовать поток в байт [] в С#?
Или я думаю, что также следует использовать метод .ToString() и кодировать это.
Я знаю, как кодировать/декодировать простую строку в/из base64.
Но как бы это сделать, если данные уже были записаны в объект FileStream. Скажем, у меня есть только доступ к объекту FileStream, а не к ранее сохраненным исходным данным. Как мне закодировать FileStream на base64, прежде чем я очищу FileStream до файла.
Ofc Я мог бы просто открыть свой файл и закодировать/декодировать его после того, как я написал FileStream в файл, но я хотел бы сделать это всего за один шаг, не делая двух файловых операций один за другим. Файл может быть больше, и для загрузки, зашифрования и сохранения его снова потребуется два раза, после того, как он был сохранен за короткое время раньше.
Возможно, кто-то из вас знает лучшее решение? Могу ли я преобразовать FileStream в строку, закодировать строку и затем преобразовать строку обратно в FileStream, например, или что бы я сделал и как выглядел бы такой код?
Вы также можете кодировать байты в Base64. Как получить это из потока, см. Здесь: Как преобразовать поток в байт [] в С#?
Или я думаю, что также следует использовать метод .ToString() и кодировать это.
Легкий как метод расширения
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));
}
}
Вы можете попробовать что-то как, которое:
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 ГБ, вы не хотите загружать файл в память (как Byte[]
), потому что он не только очень медленный, но также может вызвать сбой, как даже в 64- битовые процессы Byte[]
не могут превышать 2 ГБ (или 4 ГБ с gcAllowVeryLargeObjects
).
К счастью, в .NET есть полезный помощник под названием ToBase64Transform
, который обрабатывает поток кусками.
Вы используете его с CryptoStream
примерно так:
using( FileStream inputFile = new FileStream( @"C:\VeryLargeFile.bin", FileMode.Open, FileAccess.Read ) )
using( CryptoStream base64Stream = new CryptoStream( inputFile, new ToBase64Transform(), CryptoStreamMode.Read ) )
using( FileStream outputFile = new FileStream( @"C:\VeryLargeBase64File.txt", FileMode.CreateNew, FileAccess.Write ) )
{
await base64Stream.CopyToAsync( outputFile ).ConfigureAwait(false);
}