File Attachment in InfoPath
根据InfoPath team blog里介绍的File Attachment Control的内容,写了两个类来处理文件的编码与解码。
public class InfoPathAttachmentEncoder
...{
private string base64EncodedFile = string.Empty;
private string fullyQualifiedFileName;
![]()
/**//// <summary>
/// Creates a encoder to create an InfoPath attachement string
/// </summary>
/// <param name="fullyQualifiedFileName"></param>
public InfoPathAttachmentEncoder(string fullyQualifiedFileName)
...{
if (fullyQualifiedFileName == string.Empty)
throw new ArgumentException("Must specify file name", "fullyQualifiedFileName");
![]()
if (!File.Exists(fullyQualifiedFileName))
throw new FileNotFoundException("File does not exist: " + fullyQualifiedFileName, fullyQualifiedFileName);
![]()
this.fullyQualifiedFileName = fullyQualifiedFileName;
}
![]()
/**//// <summary>
/// Returns a Base64 encoded string
/// </summary>
/// <returns>String</returns>
public string ToBase64String()
...{
if (base64EncodedFile != string.Empty)
return base64EncodedFile;
![]()
// This memory stream will hold the InfoPath file attachment buffer before Base64 encoding
MemoryStream ms = new MemoryStream();
![]()
// get the file information
using (BinaryReader br = new BinaryReader(File.Open(fullyQualifiedFileName, FileMode.Open, FileAccess.Read, FileShare.Read)))
...{
string fileName = Path.GetFileName(fullyQualifiedFileName);
![]()
uint fileNameLength = (uint)fileName.Length + 1;
![]()
byte[] fileNameBytes = Encoding.Unicode.GetBytes(fileName);
![]()
using (BinaryWriter bw = new BinaryWriter(ms))
...{
// Write InfoPath attachment signature
bw.Write(new byte[] ...{ 0xC7, 0x49, 0x46, 0x41 });
![]()
// Write the default header information
bw.Write((uint)0x14); // size
bw.Write((uint)0x01); // version
bw.Write((uint)0x00); // reserved
![]()
// Write the file size
bw.Write((uint)br.BaseStream.Length);
![]()
// Write the size of the file name
bw.Write((uint)fileNameLength);
![]()
// Write the file name (Unicode encoded)
bw.Write(fileNameBytes);
![]()
// Write the file name terminator (which is two nulls in Unicode)
bw.Write(new byte[] ...{0,0});
![]()
// Iterate through the file reading data and writing it to the outbuffer
byte[] data = new byte[64*1024];
int bytesRead = 1;
![]()
while (bytesRead > 0)
...{
bytesRead = br.Read(data, 0, data.Length);
bw.Write(data, 0, bytesRead);
}
}
}
![]()
![]()
// This memorystream will hold the Base64 encoded InfoPath attachment
MemoryStream msOut = new MemoryStream();
![]()
using (BinaryReader br = new BinaryReader(new MemoryStream(ms.ToArray())))
...{
// Create a Base64 transform to do the encoding
ToBase64Transform tf = new ToBase64Transform();
![]()
byte[] data = new byte[tf.InputBlockSize];
byte[] outData = new byte[tf.OutputBlockSize];
![]()
int bytesRead = 1;
![]()
while (bytesRead > 0)
...{
bytesRead = br.Read(data, 0, data.Length);
![]()
if (bytesRead == data.Length)
tf.TransformBlock(data, 0, bytesRead, outData, 0);
else
outData = tf.TransformFinalBlock(data, 0, bytesRead);
![]()
msOut.Write(outData, 0, outData.Length);
}
}
![]()
msOut.Close();
![]()
return base64EncodedFile = Encoding.ASCII.GetString(msOut.ToArray());
}
}
public class InfoPathAttachmentDecoder
...{
private const int SP1Header_Size = 20;
private const int FIXED_HEADER = 16;
![]()
private int fileSize;
private int attachmentNameLength;
private string attachmentName;
private byte[] decodedAttachment;
![]()
/**//// <summary>
/// Accepts the Base64 encoded string
/// that is the attachment
/// </summary>
public InfoPathAttachmentDecoder(string theBase64EncodedString)
...{
byte [] theData = Convert.FromBase64String(theBase64EncodedString);
using(MemoryStream ms = new MemoryStream(theData))
...{
BinaryReader theReader = new BinaryReader(ms);
DecodeAttachment(theReader);
}
}
![]()
private void DecodeAttachment(BinaryReader theReader)
...{
//position the reader to get the filesize
byte[] headerData = new byte[FIXED_HEADER];
headerData = theReader.ReadBytes(headerData.Length);
![]()
fileSize = (int)theReader.ReadUInt32();
attachmentNameLength = (int)theReader.ReadUInt32() * 2;
![]()
byte[] fileNameBytes = theReader.ReadBytes(attachmentNameLength);
//InfoPath defaults to UTF8 encoding.
Encoding enc = Encoding.Unicode;
attachmentName = enc.GetString(fileNameBytes, 0, attachmentNameLength - 2);
decodedAttachment = theReader.ReadBytes(fileSize);
}
![]()
public void SaveAttachment(string saveLocation)
...{
string fullFileName = saveLocation;
if(!fullFileName.EndsWith(Path.DirectorySeparatorChar.ToString()))
...{
fullFileName += Path.DirectorySeparatorChar;
}
![]()
fullFileName += attachmentName;
![]()
if(File.Exists(fullFileName))
File.Delete(fullFileName);
![]()
FileStream fs = new FileStream(fullFileName, FileMode.CreateNew);
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(decodedAttachment);
![]()
bw.Close();
fs.Close();
}
![]()
public string Filename
...{
get...{ return attachmentName; }
}
![]()
public byte[] DecodedAttachment
...{
get...{ return decodedAttachment; }
}
}
这样,我们就能根据需要对File Attachment Control来做进一步的控制了。
posted on 2005-07-04 13:07:00 by sam1111 评论(3) 阅读(4438)



}