Может ли кто-нибудь осведомиться о том, как это сделать? Я могу сделать это для обычного текстового или байтового массива, но не уверен, как подойти для pdf. сначала вставляем PDF в массив байтов?
Base64 Кодировать PDF в С#?
Ответ 1
Используйте File.ReadAllBytes
, чтобы загрузить файл PDF, а затем закодировать массив байтов как обычно, используя Convert.ToBase64String(bytes)
.
Ответ 2
Есть способ, которым вы можете сделать это в кусках, чтобы вам не приходилось одновременно сжигать тонну памяти.
.Net включает кодировщик, который может выполнять блокирование, но это своего рода странное место. Они помещают его в пространство имен System.Security.Cryptography.
Я проверил приведенный ниже пример кода, и получаю идентичный вывод, используя либо мой метод, либо метод Andrew выше.
Вот как это работает: вы запускаете класс под названием CryptoStream. Это своего рода адаптер, который подключается к другому потоку. Вы подключаете класс CryptoTransform к CryptoStream (который, в свою очередь, привязан к файлу/памяти/сетевому потоку), и он выполняет преобразования данных по данным во время чтения или записи в поток.
Обычно преобразование - это шифрование/дешифрование, но .net также включает преобразования ToBase64 и FromBase64, поэтому мы не будем шифровать, просто кодировать.
Вот код. Я включил (возможно, плохо названную) реализацию предложения 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));
}
}
Я также играю с тем, где я прикрепляю CryptoStream. В методе Encode я прикрепляю его к потоку вывода (записи), поэтому, когда я экземпляр CryptoStream, я использую его метод Write().
Когда я читаю, я привязываю его к потоку ввода (чтения), поэтому я использую метод чтения в CryptoStream. На самом деле не имеет значения, к какому потоку я прикрепляю его. Мне просто нужно передать соответствующий элемент перечисления Read или Write в конструктор CryptoStream.