是否有用于.NET的Base64Stream?

是否有用于.NET的Base64Stream?,base64,.net,Base64,.net,如果我想生成Base64编码的输出,我将如何在.NET中实现这一点 我知道自从.NET2.0以来,就有了接口和 以及该接口的实现 但是这些类嵌入到System.Security命名空间中,需要使用TransformBlock、TransformFinalBlock等 有没有一种更简单的方法可以在.NET中对数据流进行base64编码?加密流没有RFC2045行结尾。因此,这对我不起作用。 ToBase64String是不可接受的,因为它不是流式方法。我不想一次保存内存中的所有数据 因此,我需要其

如果我想生成Base64编码的输出,我将如何在.NET中实现这一点

我知道自从.NET2.0以来,就有了接口和 以及该接口的实现

但是这些类嵌入到System.Security命名空间中,需要使用TransformBlock、TransformFinalBlock等


有没有一种更简单的方法可以在.NET中对数据流进行base64编码?

加密流没有RFC2045行结尾。因此,这对我不起作用。
ToBase64String是不可接受的,因为它不是流式方法。我不想一次保存内存中的所有数据

因此,我需要其他选择

Richard Grimes在这里发布了一条:

由于许可和功能需求,我没有使用它,而是编写了一个独立的实现,可在此处获得:

它是根据法律许可的

要使用此选项压缩然后对文件进行base64编码,请执行以下操作:

byte[] working= new byte[1024];
int n;
using (Stream input = File.OpenRead(fileToCompress))
{
    using (Stream output = new FileStream("file.deflated.b64"))
    {
        using (var b64 = new Base64Stream(output, Base64Stream.Mode.Encode))
        {
            b64.Rfc2045Compliant = true; // OutputLineLength = 76;

            using (var compressor = new DeflateStream(b64, CompressionMode.Compress, true))
            {
                while ((n = input.Read(working, 0, working.Length)) != 0)
                {
                    compressor.Write(working, 0, n);
                }
            }
        }
    }
}

Convert提供了这一点,下面是一个可能有帮助的代码示例

private string EncodeBase64(string toEncode)
{
  byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(toEncode);
  string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
  return returnValue;
}

如果需要转换为Base64的流,可以将
ToBase64转换
放入:

如果您只想将单字节数组转换为Base64,只需调用


在这两种情况下,您都可以将单词
替换为
From

这应该满足您的需要:


看起来有一个
Base64Stream
类。也许这会对未来的读者有所帮助


用SLaks的简单答案,我写了一个简单的解决方案:

/// <summary>
///     Encodes the specified input stream into the specified output stream.
/// </summary>
/// <param name="inputStream">
///     The input stream.
/// </param>
/// <param name="outputStream">
///     The output stream.
/// </param>
/// <param name="lineLength">
///     The length of lines.
/// </param>
/// <param name="dispose">
///     true to release all resources used by the input and output <see cref="Stream"/>;
///     otherwise, false.
/// </param>
/// <exception cref="ArgumentNullException">
///     inputStream or outputStream is null.
/// </exception>
/// <exception cref="ArgumentException">
///     inputStream or outputStream is invalid.
/// </exception>
/// <exception cref="NotSupportedException">
///     inputStream is not readable -or- outputStream is not writable.
/// </exception>
/// <exception cref="IOException">
///     An I/O error occured, such as the specified file cannot be found.
/// </exception>
/// <exception cref="ObjectDisposedException">
///     Methods were called after the inputStream or outputStream was closed.
/// </exception>
public static void EncodeStream(Stream inputStream, Stream outputStream, int lineLength = 0, bool dispose = false)
{
    if (inputStream == null)
        throw new ArgumentNullException(nameof(inputStream));
    if (outputStream == null)
        throw new ArgumentNullException(nameof(outputStream));
    var si = inputStream;
    var so = outputStream;
    try
    {
        int i;
        var cs = new CryptoStream(si, new ToBase64Transform(), CryptoStreamMode.Read);
        var ba = new byte[lineLength < 1 ? 4096 : lineLength];
        var sep = new byte[] { 0xd, 0xa };
        while ((i = cs.Read(ba, 0, ba.Length)) > 0)
        {
            so.Write(ba, 0, i);
            if (lineLength < 1 || i < ba.Length)
                continue;
            so.Write(sep, 0, sep.Length);
        }
    }
    finally
    {
        if (dispose)
        {
            si.Dispose();
            so.Dispose();
        }
    }
}

/// <summary>
///     Decodes the specified input stream into the specified output stream.
/// </summary>
/// <param name="inputStream">
///     The input stream.
/// </param>
/// <param name="outputStream">
///     The output stream.
/// </param>
/// <param name="dispose">
///     true to release all resources used by the input and output <see cref="Stream"/>;
///     otherwise, false.
/// </param>
/// <exception cref="ArgumentNullException">
///     inputStream or outputStream is null.
/// </exception>
/// <exception cref="ArgumentException">
///     inputStream or outputStream is invalid.
/// </exception>
/// <exception cref="NotSupportedException">
///     inputStream is not readable -or- outputStream is not writable.
/// </exception>
/// <exception cref="IOException">
///     An I/O error occured, such as the specified file cannot be found.
/// </exception>
/// <exception cref="ObjectDisposedException">
///     Methods were called after the inputStream or outputStream was closed.
/// </exception>
public static void DecodeStream(Stream inputStream, Stream outputStream, bool dispose = false)
{
    if (inputStream == null)
        throw new ArgumentNullException(nameof(inputStream));
    if (outputStream == null)
        throw new ArgumentNullException(nameof(outputStream));
    var si = inputStream;
    var so = outputStream;
    try
    {
        var bai = new byte[4096];
        var bao = new byte[bai.Length];
        using (var fbt = new FromBase64Transform())
        {
            int i;
            while ((i = si.Read(bai, 0, bai.Length)) > 0)
            {
                i = fbt.TransformBlock(bai, 0, i, bao, 0);
                so.Write(bao, 0, i);
            }
        }
    }
    finally
    {
        if (dispose)
        {
            si.Dispose();
            so.Dispose();
        }
    }
}

您不需要自定义流类;您只需使用
加密流
。看到我的答案了。是的,但我不知道如何使用内置类实现RFC2045兼容的行长度。所以,据我所知,我确实需要一个自定义类。您只需通过压缩器运行内容。但是压缩由压缩产生的base64字符串似乎是错误的想法。对原始内容进行压缩,然后对其进行base64编码。压缩输出的结果将消除base64编码的优点。此外,它可能不会有任何好的结果,因为内容已经被压缩,因此所述内容的base64编码大部分将是不可压缩的。@Cheeso,我有兴趣查看一下您的base64流,但winisp.net链接似乎已失效。你还有别的地方吗?死链接。请不要发布链接,发布代码。看起来很简单。您可以在该流上设置RFC 2045行长度吗?您可以调用
Convert.ToBase64String(bytes,base64格式化选项.InsertLineBreaks)
但是,
ToBase64Transform
不公开该选项。好吧,这很奇怪。因此,如果我想创建一个用于MIME附加目的的base64文档(la RFC 2045),那么我不能使用它,但是如果我从base64文档转换,它会工作吗?很有用,但在我的例子中,我不想使用ToBase64字符串。它不是一个流,可能无法很好地处理大数据。这并不能完全回答最初的问题:该类被标记为internal,您不能复制源代码,因为它仅供参考。您是对的,我认为您不能复制源代码。您应该在Nuget包中发布它。:-)
/// <summary>
///     Encodes the specified input stream into the specified output stream.
/// </summary>
/// <param name="inputStream">
///     The input stream.
/// </param>
/// <param name="outputStream">
///     The output stream.
/// </param>
/// <param name="lineLength">
///     The length of lines.
/// </param>
/// <param name="dispose">
///     true to release all resources used by the input and output <see cref="Stream"/>;
///     otherwise, false.
/// </param>
/// <exception cref="ArgumentNullException">
///     inputStream or outputStream is null.
/// </exception>
/// <exception cref="ArgumentException">
///     inputStream or outputStream is invalid.
/// </exception>
/// <exception cref="NotSupportedException">
///     inputStream is not readable -or- outputStream is not writable.
/// </exception>
/// <exception cref="IOException">
///     An I/O error occured, such as the specified file cannot be found.
/// </exception>
/// <exception cref="ObjectDisposedException">
///     Methods were called after the inputStream or outputStream was closed.
/// </exception>
public static void EncodeStream(Stream inputStream, Stream outputStream, int lineLength = 0, bool dispose = false)
{
    if (inputStream == null)
        throw new ArgumentNullException(nameof(inputStream));
    if (outputStream == null)
        throw new ArgumentNullException(nameof(outputStream));
    var si = inputStream;
    var so = outputStream;
    try
    {
        int i;
        var cs = new CryptoStream(si, new ToBase64Transform(), CryptoStreamMode.Read);
        var ba = new byte[lineLength < 1 ? 4096 : lineLength];
        var sep = new byte[] { 0xd, 0xa };
        while ((i = cs.Read(ba, 0, ba.Length)) > 0)
        {
            so.Write(ba, 0, i);
            if (lineLength < 1 || i < ba.Length)
                continue;
            so.Write(sep, 0, sep.Length);
        }
    }
    finally
    {
        if (dispose)
        {
            si.Dispose();
            so.Dispose();
        }
    }
}

/// <summary>
///     Decodes the specified input stream into the specified output stream.
/// </summary>
/// <param name="inputStream">
///     The input stream.
/// </param>
/// <param name="outputStream">
///     The output stream.
/// </param>
/// <param name="dispose">
///     true to release all resources used by the input and output <see cref="Stream"/>;
///     otherwise, false.
/// </param>
/// <exception cref="ArgumentNullException">
///     inputStream or outputStream is null.
/// </exception>
/// <exception cref="ArgumentException">
///     inputStream or outputStream is invalid.
/// </exception>
/// <exception cref="NotSupportedException">
///     inputStream is not readable -or- outputStream is not writable.
/// </exception>
/// <exception cref="IOException">
///     An I/O error occured, such as the specified file cannot be found.
/// </exception>
/// <exception cref="ObjectDisposedException">
///     Methods were called after the inputStream or outputStream was closed.
/// </exception>
public static void DecodeStream(Stream inputStream, Stream outputStream, bool dispose = false)
{
    if (inputStream == null)
        throw new ArgumentNullException(nameof(inputStream));
    if (outputStream == null)
        throw new ArgumentNullException(nameof(outputStream));
    var si = inputStream;
    var so = outputStream;
    try
    {
        var bai = new byte[4096];
        var bao = new byte[bai.Length];
        using (var fbt = new FromBase64Transform())
        {
            int i;
            while ((i = si.Read(bai, 0, bai.Length)) > 0)
            {
                i = fbt.TransformBlock(bai, 0, i, bao, 0);
                so.Write(bao, 0, i);
            }
        }
    }
    finally
    {
        if (dispose)
        {
            si.Dispose();
            so.Dispose();
        }
    }
}
const int lineLength = 76;
const string sourcePath = @"C:\test\file-to-encode.example";
const string encodedPath = @"C:\test\encoded-example.base64";
const string decodedPath = @"C:\test\decoded-base64.example";

// encoding
using(var fsi = new FileStream(sourcePath, FileMode.Open))
    using (var fso = new FileStream(encodedPath, FileMode.Create))
        EncodeStream(fsi, fso, lineLength);

// decoding
using(var fsi = new FileStream(encodedPath, FileMode.Open))
    using (var fso = new FileStream(decodedPath, FileMode.Create))
        DecodeStream(fsi, fso);