base64との間で単純な文字列をエンコード/デコードする方法を知っています。
しかし、データがすでにFileStreamオブジェクトに書き込まれている場合、どうすればよいでしょうか。 FileStreamオブジェクトにのみアクセスでき、以前に保存された元のデータにはアクセスできないとします。 FileStreamをファイルにフラッシュする前に、FileStream to base64をどのようにエンコードしますか?.
Ofcファイルストリームをファイルに書き込んだ後、ファイルを開いてエンコード/デコードすることができますが、次の2つのファイル操作を行うことなく、すべてを1つのステップで実行したいと思います。ファイルは大きくなる可能性があり、少し前に保存した後、再度読み込み、エンコード、保存するのに2倍の時間がかかります。
たぶんあなたの誰かがより良い解決策を知っていますか? FileStreamを文字列に変換し、文字列をエンコードしてから、たとえば、文字列をFileStreamに変換して戻すことはできますか?また、そのようなコードはどのようになりますか?
バイトをBase64にエンコードすることもできます。ストリームからこれを取得する方法は、こちらを参照してください: C#でストリームをbyte []に変換する方法
または、.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));
}
}
何か試してみてくださいlike that:
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));
}
ファイルが大きくなるため、これを行う方法についてはあまり選択肢がありません。使用する必要がある情報が破壊されるため、ファイルを所定の場所で処理できません。次の2つのオプションがあります。
もちろん、ストリームのポイントはこの種のシナリオを避けることです。コンテンツを作成してファイルストリームに詰め込む代わりに、メモリストリームに詰めます。次に、それをエンコードしてからディスクに保存します。
サイズが4GBを超えるファイルのような大きなストリームを扱う場合、ファイルをメモリに(Byte[]
として)ロードしたくないのは、それが非常に遅いだけでなく、 64ビットプロセスは、Byte[]
が2GB(またはgcAllowVeryLargeObjects
で4GB)を超えることはできません。
幸いなことに、.NETには、ストリームをチャンクで処理するToBase64Transform
と呼ばれるきちんとしたヘルパーがあります。そのようです:
using System.Security.Cryptography;
public static Stream EncodeStreamUsingBase64( Stream input )
{
if( input == null ) throw new ArgumentNullException( nameof(input) );
ICryptoTransform xf = new ToBase64Transform();
return new CryptoStream( input, xf, CryptoStreamMode.Write, leaveOpen: false );
}
したがって、次のように使用できます。
using( FileStream inputFile = new FileStream( @"C:\VeryLargeFile.bin", FileMode.Open, FileAccess.Read ) )
using( Stream base64Stream = EncodeStreamUsingBase64( fs ) )
using( FileStream outputFile = new FileStream( @"C:\VeryLargeBase64File.txt", FileMode.CreateNew, FileAccess.Write ) )
{
await base64Stream.CopyToAsync( outputFile );
}