有人能解释一下如何做到这一点吗?我可以对普通文本或字节数组这样做,但不确定如何处理PDF。我需要先将PDF嵌入字节数组中吗?
File.ReadAllBytes
方法加载PDF文件,然后使用Convert.ToBase64String(bytes)
将字节数组编码为普通字符串。 Byte[] fileBytes = File.ReadAllBytes(@"TestData\example.pdf");
var content = Convert.ToBase64String(fileBytes);
有一种方法可以分块处理,这样您就不必一次性占用大量内存。
.Net包括一个可以进行分块的编码器,但它位于一个有点奇怪的位置。它们将其放在System.Security.Cryptography命名空间中。
我测试了下面的示例代码,并且使用我的方法或上面Andrew的方法获得相同的输出。
这是它的工作原理:您启动一个称为CryptoStream的类。这是一种适配器,可插入另一个流中。您将称为CryptoTransform的类插入CryptoStream(反过来附加到文件/内存/网络流),并在从流中读取或写入数据时对数据执行数据转换。
通常,转换是加密/解密,但是.NET还包括ToBase64和FromBase64变换,因此我们不会加密,只是编码。
这里是代码。我包括Andrew建议的(可能命名不当)实现,以便您可以比较输出。
class Base64Encoder
{
// 编码方法:将输入文件转换为Base64编码格式,并输出到指定的输出文件中
public void Encode(string inFileName, string outFileName)
{
// 创建一个ToBase64Transform对象进行加密操作
System.Security.Cryptography.ICryptoTransform transform = new System.Security.Cryptography.ToBase64Transform();
// 使用using块自动释放资源
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))
{
// 创建一个4k大小的缓冲区
byte[] buffer = new byte[4096];
int bytesRead;
// 从输入文件中读取数据并加密后写入输出文件中
while ((bytesRead = inFile.Read(buffer, 0, buffer.Length)) > 0)
cryptStream.Write(buffer, 0, bytesRead);
cryptStream.FlushFinalBlock(); // 写入最后的块
}
}
// 解码方法:将Base64编码格式的输入文件解码成二进制形式,并输出到指定的输出文件中
public void Decode(string inFileName, string outFileName)
{
// 创建一个FromBase64Transform对象进行解密操作
System.Security.Cryptography.ICryptoTransform transform = new System.Security.Cryptography.FromBase64Transform();
// 使用using块自动释放资源
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(); // 清空缓存区并将数据写入磁盘
}
}
// 内存编码方法:将输入文件的所有数据一次性读入内存,
// 然后将其转换为Base64编码格式,并输出到指定的输出文件中
public void MemoryEncode(string inFileName, string outFileName)
{
byte[] bytes = System.IO.File.ReadAllBytes(inFileName); // 将输入文件读取到内存中
System.IO.File.WriteAllText(outFileName, System.Convert.ToBase64String(bytes)); // 将读取的数据进行Base64编码后写入输出文件中
}
}
我也在尝试着调整加密流的附加位置。在Encode方法中,我将它附加到输出(写入)流上,因此在实例化CryptoStream时,我使用它的Write()方法。
当我读取时,我将其附加到输入(读取)流上,因此我在CryptoStream上使用read方法。无论附加到哪个流上都没有太大关系。我只需要将适当的Read或Write枚举成员传递给CryptoStream的构造函数即可。