web-dev-qa-db-fra.com

Base64 Encode a PDF en C #?

Quelqu'un peut-il nous éclairer sur la façon de procéder? Je peux le faire pour du texte normal ou un tableau d'octets, mais je ne sais pas comment aborder un pdf. puis-je d'abord bourrer le pdf dans un tableau d'octets?

30
Tone

Utilisez File.ReadAllBytes pour charger le fichier PDF, puis codez le tableau d'octets comme d'habitude à l'aide de Convert.ToBase64String(bytes) .

45
Andrew Rollings

Il existe un moyen de le faire en plusieurs parties afin de ne pas avoir à graver une tonne de mémoire à la fois.

.Net comprend un encodeur qui peut faire le découpage, mais c'est en quelque sorte un endroit étrange. Ils l'ont mis dans l'espace de noms System.Security.Cryptography.

J'ai testé l'exemple de code ci-dessous et j'obtiens une sortie identique en utilisant ma méthode ou la méthode d'Andrew ci-dessus.

Voici comment cela fonctionne: vous lancez une classe appelée CryptoStream. C'est une sorte d'adaptateur qui se branche sur un autre flux. Vous branchez une classe appelée CryptoTransform dans le CryptoStream (qui à son tour est attaché à votre fichier/mémoire/flux réseau) et il effectue des transformations de données sur les données pendant leur lecture ou leur écriture dans le flux.

Normalement, la transformation est le chiffrement/déchiffrement, mais .net inclut également les transformations ToBase64 et FromBase64, donc nous ne serons pas en train de chiffrer, juste de l'encoder.

Voici le code. J'ai inclus une implémentation (peut-être mal nommée) de la suggestion d'Andrew afin que vous puissiez comparer la sortie.


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

Je joue également avec l'endroit où j'attache le CryptoStream. Dans la méthode Encode, je l'attache au flux de sortie (écriture), donc lorsque j'instance le CryptoStream, j'utilise sa méthode Write ().

Lorsque je lis, je l'attache au flux d'entrée (lecture), donc j'utilise la méthode de lecture sur le CryptoStream. Peu importe le flux auquel je l'attache. Je dois simplement passer le membre d'énumération de lecture ou d'écriture approprié au constructeur de CryptoStream.

35
JMarsch