Loading a text file from the SharePoint content database should be straightforward, and it is, kind of.
The work I’m doing right now requires me to load XML and XSL files provisioned into the content database. Initially I figured I’d use the GetFileAsString method of SPWeb.
Despite numerous posts extolling the virtues of this method, I couldn’t get it to work, it kept throwing FileNotFoundException‘s.
Not willing to spend any more time on it, I shifted over to a simpler solution which gets hold of the SPFile object, extracts the bytes from it and converts the bytes to a string.
The first method below, simply loads a text file and converts the contents to a string using one of the following encodings;
- ASCII
- UTF-8
- UTF-16 Big Endian
- UTF-16 Little Endian
private static string GetTextFileAsString(string url) { using (var site = new SPSite(url)) { var web = site.OpenWeb(); var file = web.GetFile(url); if (file.CharSetName != null) return Encoding.GetEncoding(file.CharSetName).GetString(file.OpenBinary()); // open binary file contents and work out encoding Encoding encoding; var bytes = file.OpenBinary(); if (bytes[0] == '\x00EF' && bytes[1] == '\x00BB' && bytes[2] == '\x00BF') encoding = Encoding.UTF8; else if (bytes[0] == '\x00FF' && bytes[1] == '\x00FE') encoding = Encoding.Unicode; else if (bytes[0] == '\x00FE' && bytes[1] == '\x00FF') encoding = Encoding.BigEndianUnicode; else encoding = Encoding.ASCII; return encoding.GetString(bytes); } }
If you’re loading an XML/XSL file a better way of determining the encoding is this;
private static string GetTextFileAsString(string url) { using (var site = new SPSite(url)) { var web = site.OpenWeb(); var file = web.GetFile(url); if (file.CharSetName != null) return Encoding.GetEncoding(file.CharSetName).GetString(file.OpenBinary()); // open binary file contents and work out encoding Encoding encoding; var bytes = file.OpenBinary(); using (var stream = new MemoryStream(bytes)) { using (var xmlreader = new XmlTextReader(stream)) { xmlreader.MoveToContent(); encoding = xmlreader.Encoding; } } return encoding.GetString(bytes); } }
However, for my own solution when loading XML/XSL files, I’ve found that the method shown below works well, 100% of the time, regardless of encoding styles;
private static byte[] GetTextFileAsBytes(string url) { using (var site = new SPSite(url)) { var web = site.OpenWeb(); var file = web.GetFile(url); // open binary file contents var bytes = file.OpenBinary(); return bytes; } } private XslCompiledTransform LoadTransformation() { var xslFilePath = GetXslFileUrl(); var xslTransform = new XslCompiledTransform(); var xslBytes = GetTextFileAsBytes(xslFilePath); using (var stream = new MemoryStream()) { stream.Write(xslBytes, 0, xslBytes.Length); stream.Flush(); stream.Seek(0, SeekOrigin.Begin); using (var reader = new XmlTextReader(stream)) { // load the transformation xslTransform.Load(reader); } } return xslTransform; }
One thought on “SharePoint: Load a Text File from the Content Database.”