Base64 在 C# 中编码 PDF?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/475421/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 04:54:01  来源:igfitidea点击:

Base64 Encode a PDF in C#?

c#encodingbase64

提问by Tone

Can someone provide some light on how to do this? I can do this for regular text or byte array, but not sure how to approach for a pdf. do i stuff the pdf into a byte array first?

有人可以提供一些关于如何做到这一点的信息吗?我可以对常规文本或字节数组执行此操作,但不确定如何处理 pdf。我要先把pdf塞进一个字节数组吗?

采纳答案by Andrew Rollings

Use File.ReadAllBytesto load the PDF file, and then encode the byte array as normal using Convert.ToBase64String(bytes).

使用File.ReadAllBytes加载PDF文件,然后编码字节数组作为正常使用Convert.ToBase64String(bytes)

回答by JMarsch

There is a way that you can do this in chunks so that you don't have to burn a ton of memory all at once.

有一种方法可以分块执行此操作,这样您就不必一次消耗大量内存。

.Net includes an encoder that can do the chunking, but it's in kind of a weird place. They put it in the System.Security.Cryptography namespace.

.Net 包含一个可以进行分块的编码器,但它位于一个奇怪的地方。他们把它放在 System.Security.Cryptography 命名空间中。

I have tested the example code below, and I get identical output using either my method or Andrew's method above.

我已经测试了下面的示例代码,并且使用我的方法或上面的 Andrew 方法获得了相同的输出。

Here's how it works: You fire up a class called a CryptoStream. This is kind of an adapter that plugs into another stream. You plug a class called CryptoTransform into the CryptoStream (which in turn is attached to your file/memory/network stream) and it performs data transformations on the data while it's being read from or written to the stream.

它的工作原理如下:您启动一个名为 CryptoStream 的类。这是一种插入另一个流的适配器。您将一个名为 CryptoTransform 的类插入到 CryptoStream(它又附加到您的文件/内存/网络流)中,并在从流中读取或写入数据时对数据执行数据转换。

Normally, the transformation is encryption/decryption, but .net includes ToBase64 and FromBase64 transformations as well, so we won't be encrypting, just encoding.

通常,转换是加密/解密,但 .net 也包括 ToBase64 和 FromBase64 转换,所以我们不会加密,只是编码。

Here's the code. I included a (maybe poorly named) implementation of Andrew's suggestion so that you can compare the output.

这是代码。我包含了 Andrew 建议的一个(可能命名不当)实现,以便您可以比较输出。


    class Base64Encoder
    {
        public void Encode(string inFileName, string outFileName)
        {
            System.Security.Cryptography.ICryptoTransform transform = new System.Security.Cryptography.ToBase64Transform();
            using(System.IO.FileStream inFile = System.IO.File.OpenRead(inFileName),
                                      outFile = System.IO.File.Create(outFileName))
            using (System.Security.Cryptography.CryptoStream cryptStream = new System.Security.Cryptography.CryptoStream(outFile, transform, System.Security.Cryptography.CryptoStreamMode.Write))
            {
                // I'm going to use a 4k buffer, tune this as needed
                byte[] buffer = new byte[4096];
                int bytesRead;

                while ((bytesRead = inFile.Read(buffer, 0, buffer.Length)) > 0)
                    cryptStream.Write(buffer, 0, bytesRead);

                cryptStream.FlushFinalBlock();
            }
        }

        public void Decode(string inFileName, string outFileName)
        {
            System.Security.Cryptography.ICryptoTransform transform = new System.Security.Cryptography.FromBase64Transform();
            using (System.IO.FileStream inFile = System.IO.File.OpenRead(inFileName),
                                      outFile = System.IO.File.Create(outFileName))
            using (System.Security.Cryptography.CryptoStream cryptStream = new System.Security.Cryptography.CryptoStream(inFile, transform, System.Security.Cryptography.CryptoStreamMode.Read))
            {
                byte[] buffer = new byte[4096];
                int bytesRead;

                while ((bytesRead = cryptStream.Read(buffer, 0, buffer.Length)) > 0)
                    outFile.Write(buffer, 0, bytesRead);

                outFile.Flush();
            }
        }

        // this version of Encode pulls everything into memory at once
        // you can compare the output of my Encode method above to the output of this one
        // the output should be identical, but the crytostream version
        // will use way less memory on a large file than this version.
        public void MemoryEncode(string inFileName, string outFileName)
        {
            byte[] bytes = System.IO.File.ReadAllBytes(inFileName);
            System.IO.File.WriteAllText(outFileName, System.Convert.ToBase64String(bytes));
        }
    }

I am also playing around with where I attach the CryptoStream. In the Encode method,I am attaching it to the output (writing) stream, so when I instance the CryptoStream, I use its Write() method.

我也在玩我附加 CryptoStream 的地方。在 Encode 方法中,我将它附加到输出(写入)流,因此当我实例化 CryptoStream 时,我使用它的 Write() 方法。

When I read, I'm attaching it to the input (reading) stream, so I use the read method on the CryptoStream. It doesn't really matter which stream I attach it to. I just have to pass the appropriate Read or Write enumeration member to the CryptoStream's constructor.

当我阅读时,我将它附加到输入(阅读)流,所以我在 CryptoStream 上使用 read 方法。我将它附加到哪个流并不重要。我只需要将适当的 Read 或 Write 枚举成员传递给 CryptoStream 的构造函数。