2009-01-24 38 views
26

Ai đó có thể cung cấp một số ánh sáng về cách thực hiện việc này không? Tôi có thể làm điều này cho văn bản hoặc mảng byte thông thường, nhưng không chắc chắn cách tiếp cận cho một pdf. tôi có nhồi nhét pdf vào mảng byte trước không?Base64 Mã hóa một tệp PDF bằng C#?

+2

Tại sao tệp PDF lại khác với mảng byte? –

Trả lời

39

Sử dụng File.ReadAllBytes để tải tệp PDF và sau đó mã hóa mảng byte như bình thường bằng cách sử dụng Convert.ToBase64String(bytes).

+2

Yikes! Điều đó có thể lớn. –

+0

Thật vậy. Nhưng những ngày này máy có rất nhiều bộ nhớ. Và nếu cần thiết, đọc khối đệm từ một tập tin là một kỹ thuật khá tiêu chuẩn :) –

+0

Hoạt động tốt cho những gì tôi cần cho thời điểm này. Cảm ơn vì tiền hỗ trợ! – Tone

34

Có một cách để bạn có thể thực hiện việc này theo từng phần để bạn không phải ghi một tấn bộ nhớ cùng một lúc.

.Net bao gồm bộ mã hóa có thể thực hiện việc chunking, nhưng nó là một nơi kỳ lạ. Họ đặt nó vào không gian tên System.Security.Cryptography.

Tôi đã thử nghiệm mã ví dụ bên dưới và tôi nhận được kết quả giống hệt nhau bằng phương pháp của tôi hoặc phương pháp của Andrew ở trên.

Đây là cách hoạt động: Bạn kích hoạt một lớp được gọi là CryptoStream. Đây là loại bộ điều hợp cắm vào luồng khác. Bạn cắm một lớp được gọi là CryptoTransform vào CryptoStream (lần lượt được gắn vào luồng tệp/bộ nhớ/mạng của bạn) và nó thực hiện các phép biến đổi dữ liệu trên dữ liệu trong khi nó được đọc từ hoặc được ghi vào luồng.

Thông thường, việc chuyển đổi là mã hóa/giải mã, nhưng .net cũng bao gồm các biến đổi ToBase64 và FromBase64, vì vậy chúng tôi sẽ không mã hóa, chỉ cần mã hóa.

Đây là mã. Tôi bao gồm một (có thể kém tên) thực hiện đề xuất của Andrew để bạn có thể so sánh đầu ra.

 

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

Tôi cũng đang chơi xung quanh với nơi tôi đính kèm CryptoStream. Trong phương thức mã hóa, tôi gắn nó vào luồng đầu ra (viết), vì vậy khi tôi dụ CryptoStream, tôi sử dụng phương thức Write() của nó.

Khi đọc, tôi gắn nó vào luồng đầu vào (đọc), vì vậy tôi sử dụng phương thức đọc trên CryptoStream. Nó không thực sự quan trọng mà tôi gắn nó vào. Tôi chỉ cần chuyển thành viên đọc hoặc viết thích hợp vào hàm tạo của CryptoStream.

+0

Tôi chưa chạy và xác minh điều này, nhưng điều này có vẻ hứa hẹn tốt và tuyệt vời. Ý tưởng tuyệt vời! +1 – codingbear

+1

Tôi đã thử nghiệm điều này. Làm việc như một say mê. Thực hiện tốt. – mcNux

+0

@mcNux: Cảm ơn! – JMarsch