I'm trying out to use the XML - Mind converter https://www.xmlmind.com/foconverter/ to convert some xsl-fo to an rtf and this works well . Just to be clear this is nothing specific to the conveter or its functionality but just a clarification I would like to get which is why I am asking this on stack overflow .
So I have the following code (that was obtained from some documentation)
string foFilePath = #"D:\Temp\test.fo";
string ourPutFilePath = #"D:\Temp\test.rtf";
Converter converter = new Converter();
converter.OutputFormat = OutputFormat.Rtf;
converter.OutputEncoding = "windows-1252";
converter.ImageResolution = 120;
converter.SetInput(foFilePath);
converter.SetOutput(ourPutFilePath);
converter.Convert();
What happens here is quite simple Reads a file from the input path and stores the converted file in the specified output . The question I would like to clarify here is , wheather it would be possible to store this content that is being saved in the file out put path within a variable as well to may be do some processing during the application runtime ?
Maybe I can use the MemoryStream for it ? I'm just not sure how to do it and would really appreciate some help here.
I understand that I can always read it back from the file output path but I am looking for something better than that as saving the file to a certain location may not always be possible in my case
EDIT :- The converter.SetOutput() method allows 3 overloads in the parameters
String fileName
Stream stream
TextWriter writer
Sine you need the output as a string you could try doing something like this
string content;
using (var stream = new MemoryStream())
{
using (var writer = new StreamWriter(stream))
{
Converter converter = new Converter();
converter.OutputFormat = OutputFormat.Rtf;
converter.OutputEncoding = "windows-1252";
converter.ImageResolution = 120;
converter.SetInput(foFilePath);
converter.SetOutput(writer);
converter.Convert();
stream.Position = 0;
content = Encoding.UTF8.GetString(stream.ToArray());
}
}
I'm not sure about the Encoding though, and if the Convert() uses a different encoding this might not work
Related
I'm trying to convert thousands of .lbl files to text to extract just the data I need to populate a database for a much cheaper, easier method of printing labels. However, I've tried many different approaches to convert the .lbl file to a text file:
see this question
and this question
But I just have had zero luck. Here's the code:
using (BinaryReader b = new BinaryReader(File.Open(#"stupid.lbl", FileMode.Open)))
{
int length = (int)b.BaseStream.Length;
byte[] allData = b.ReadBytes(length);
using (BinaryWriter w = new BinaryWriter(File.Open(#"test.txt", FileMode.Create)))
{
Encoding encEncoder = Encoding.ASCII;
string str = encEncoder.GetString(allData);
w.Write(str);
}
}
I do have the proper file paths and whatnot to be able to actually read/write and everything opens, but it's all gibberish...I just need to get the real, useful, human readable text out of it to push into an access db...Any ideas out there?
I just started a new project on WCF and to be honest I'm very new at this with limited knowledge.
So what I'm trying to do is open a file that is stored in my computer (e.g. word, pdf, etc.) and display the contents in the webpage in JSon format. I converted the file in a byte array and tried to display the Stream. When I did that it asked me to open the file or save it. I don't want that - I just want the contents of the file to be displayed on my local host when i call the method.
Here's what I have:
public string GetRawFile()
{
string file = #"C:\.....\TestFile.pdf";
byte[] rawFile = File.ReadAllBytes(file);
//Stream stream = new MemoryStream(rawFile);
//DataContractJsonSerializer obj = newDataContractJsonSerializer(typeof(string));
//string result = obj.ReadObject(stream).ToString();
//Deserializing
MemoryStream stream = new MemoryStream();
BinaryFormatter binForm = new BinaryFormatter();
stream.Write(rawFile, 0, rawFile.Length);
stream.Seek(0, SeekOrigin.Begin);
Object obj = (Object) binForm.Deserialize(stream);
System.Web.Script.Serialization.JavaScriptSerializer xyz = new System.Web.Script.Serialization.JavaScriptSerializer();
string ejson = xyz.Serialize(obj);
WebOperationContext.Current.OutgoingRequest.ContentType = "text/json";
return ejson;
}
I'm trying to return a string and it's not working, but when I return just the stream it's popping up the "openwith" message.
Also should I use the GET or POST on my datacontract. I'm using REST in C#.
I'm assuming that your file actually contains json. If that is the case just do this;
string file = File.ReadAllText("C:\path\to\file.extension");
You're making the problem a lot more complicated than it needs to be. Just read the file and return it's data as a string. I think you want to use GET for the http method. Generally speaking, you all use post if you're adding new content. If for example the users request would cause the application to write some data to a file or data base then you would typically use POST for the http method. If they're just requesting data, you almost always use GET.
Here is my code:
public static TextWriter twLog = null;
private int fileNo = 1;
private string line = null;
TextReader tr = new StreamReader("file_no.txt");
TextWriter tw = new StreamWriter("file_no.txt");
line = tr.ReadLine();
if(line != null){
fileNo = int.Parse(line);
twLog = new StreamWriter("log_" + line + ".txt");
}else{
twLog = new StreamWriter("log_" + fileNo.toString() + ".txt");
}
System.IO.File.WriteAllText("file_no.txt",string.Empty);
tw.WriteLine((fileNo++).ToString());
tr.Close();
tw.Close();
twLog.Close();
It throws this error:
IOException: Sharing violation on path C:\Users\Water Simulation\file_no.txt
What i'm trying to do is just open a file with log_x.txt name and take the "x" from file_no.txt file.If file_no.txt file is empty make log file's name log_1.txt and write "fileNo + 1" to file_no.txt.After a new program starts the new log file name must be log_2.txt.But i'm getting this error and i couldn't understand what am i doing wrong.Thanks for help.
Well, you're trying to open the file file_no.txt for reading and for writing using separate streams. This may not work as the file will be locked by the reading stream, so the writing stream can't be created and you get the exception.
One solution would be to read the file first, close the stream and then write the file after increasing the fileNo. That way the file is only opened once at a time.
Another way would be to create a file stream for both read and write access like that:
FileStream fileStream = new FileStream(#"file_no.txt",
FileMode.OpenOrCreate,
FileAccess.ReadWrite,
FileShare.None);
The accepted answer to this question seems to have a good solution also, even though I assume you do not want to allow shared reads.
Possible alternate solution
I understand you want to create unique log files when your program starts. Another way to do so would be this:
int logFileNo = 1;
string fileName = String.Format("log_{0}.txt", logFileNo);
while (File.Exists(fileName))
{
logFileNo++;
fileName = String.Format("log_{0}.txt", logFileNo);
}
This increases the number until it finds a file number where the log file doesn't exist. Drawback: If you have log_1.txt and log_5.txt, the next file won't be log_6.txt but log_2.txt.
To overcome this, you could enumerate all the files in your directory with mask log_*.txt and find the greatest number by performing some string manipulation.
The possibilities are endless :-D
Well this may be old but the accepted answer didn't work for me. This is caused when you try to Read or Write a file you just created from a separate stream. Solving this is very simple, just dispose the filestream you used in creating it and then you can access the file freely.
if (!File.Exists(myfile))
{
var fs = new FileStream(fav, FileMode.Create);
fs.Dispose();
string text = File.ReadAllText(myfile);
}
enter image description here
var stream = new System.IO.FileStream(filePath, System.IO.FileMode.Create);
resizedBitmap.Compress(Bitmap.CompressFormat.Png, 200, stream); //problem here
stream.Close();
return resizedBitmap;
In the Compress method, I was passing the value of the quality parameter as 200, which sadly doesn't allows values outside the range 0-100.
I changed back the value of quality to 100 and the issue got fixed.
None of the proposed options helped me. But I found a solution:
In my case, the problem was with Anti-Virus, with intensive writing to a file, Anti-Virus started scanning the file and at that moment there was a problem with writing to the file.
this is the code in question:
using (var file = MemoryMappedFile.OpenExisting("AIDA64_SensorValues"))
{
using (var readerz = file.CreateViewAccessor(0, 0))
{
var bytes = new byte[567];
var encoding = Encoding.ASCII;
readerz.ReadArray<byte>(0, bytes, 0, bytes.Length);
File.WriteAllText("C:\\myFile.txt", encoding.GetString(bytes));
var readerSettings = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment };
using (var reader = XmlReader.Create("C:\\myFile.txt", readerSettings))
{
This is what myfile.txt looks like:
<sys><id>SCPUCLK</id><label>CPU Clock</label><value>1598</value></sys><sys><id>SCPUFSB</id><label>CPU FSB</label><value>266</value></sys><sys><id>SMEMSPEED</id><label>Memory Speed</label><value>DDR2-667</value></sys><sys><id>SFREEMEM</id><label>Free Memory</label><value>415</value></sys><sys><id>SGPU1CLK</id><label>GPU Clock</label><value>562</value></sys><sys><id>SFREELVMEM</id><label>Free Local Video Memory</label><value>229</value></sys><temp><id>TCPU</id><label>CPU</label><value>42</value></temp><temp><id>TGPU1</id><label>GPU</label><value>58</value></temp>
if i write the data to a txt file on the hard drive with:
File.WriteAllText("C:\\myFile.txt", encoding.GetString(bytes));
then read that same text file with the fragment XmlReader:
XmlReader.Create("C:\\myFile.txt");
it reads it just fine, the program runs and completes like it supposed to, but then if i directly read with the fragment XmlReader like:
XmlReader.Create(encoding.GetString(bytes));
I get exception when run " illegal characters in path" on the XmlReader.Create line.
ive tried writing it to a separate string first and reading that with xmlreader, and it wouldn't help to try to print it to CMD to see what it looks like because CMD wouldnt show the invalid characters im dealing with right?
but oh well i did Console.WriteLine(encoding.GetString(bytes)); and it precisely matched the txt file.
so somehow writing it to the text file is removing some "illegal characters"? what do you guys think?
XmlReader.Create(encoding.GetString(bytes));
XmlReader.Create() interprets your string as the URI where it should read a file from. Instead encapsulate your bytes in a StringReader:
StringReader sr = new StringReader(encoding.GetString(bytes));
XmlReader.Create(sr);
Here:
XmlReader.Create(encoding.GetString(bytes));
you are simply invoking the following method which takes a string representing a filename. However you are passing the actual XML string to it which obviously is an invalid filename.
If you want to load the reader from a buffer you could use a stream:
byte[] bytes = ... represents the XML bytes
using (var stream = new MemoryStream(bytes))
using (var reader = XmlReader.Create(stream))
{
...
}
The method XmlReader.Create() with a single string as argument needs a URI passed and not the XML document as string, please refer to the MSDN. It tries to open a file named "<..." which is an invalid URI. You can pass a Stream instead.
You are passing the xml content in the place where it is expecting a path, as evidenced by the error - illegal characters in path
Use an appropriate overload, and pass a stream - http://msdn.microsoft.com/en-us/library/system.xml.xmlreader.create.aspx
I have a stream of bytes which actually (if put right) will form a valid Word file, I need to convert this stream into a Word file without writing it to disk, I take the original stream from SQL Server database table:
ID Name FileData
----------------------------------------
1 Word1 292jf2jf2ofm29fj29fj29fj29f2jf29efj29fj2f9 (actual file data)
the FileData field carries the data.
Microsoft.Office.Interop.Word.Application word = new Microsoft.Office.Interop.Word.Application();
Microsoft.Office.Interop.Word.Document doc = new Microsoft.Office.Interop.Word.Document();
doc = word.Documents.Open(#"C:\SampleText.doc");
doc.Activate();
The above code opens and fill a Word file from File System, I don't want that, I want to define a new Microsoft.Office.Interop.Word.Document, but I want to fill its content manually from byte stream.
After getting the in-memory Word document, I want to do some parsing of keywords.
Any ideas?
Create an in memmory file system, there are drivers for that.
Give word a path to an ftp server path (or something else) which you then use to push the data.
One important thing to note: storing files in a database is generally not good design.
You could look at how Sharepoint solves this. They have created a web interface for documents stored in their database.
Its not that hard to create or embed a webserver in your application that can serve pages to Word. You don't even have to use the standard ports.
There probably isn't any straight-forward way of doing this. I found a couple of solutions searching for it:
Use the OpenOffice SDK to manipulate the document instead of Word
Interop
Write the data to the clipboard, and then from the Clipboard to Word
I don't know if this does it for you, but apparently the API doesn't provide what you're after (unfortunately).
There are really only 2 ways to open a Word document programmatically - as a physical file or as a stream. There's a "package", but that's not really applicable.
The stream method is covered here: https://learn.microsoft.com/en-us/office/open-xml/how-to-open-a-word-processing-document-from-a-stream
But even it relies on there being a physical file in order to form the stream:
string strDoc = #"C:\Users\Public\Public Documents\Word13.docx";
Stream stream = File.Open(strDoc, FileMode.Open);
The best solution I can offer would be to write the file out to a temp location where the service account for the application has permission to write:
string newDocument = #"C:\temp\test.docx";
WriteFile(byteArray, newDocument);
If it didn't have permissions on the "temp" folder in my example, you would simply just add the service account of your application (application pool, if it's a website) to have Full Control of the folder.
You'd use this WriteFile() function:
/// <summary>
/// Write a byte[] to a new file at the location where you choose
/// </summary>
/// <param name="byteArray">byte[] that consists of file data</param>
/// <param name="newDocument">Path to where the new document will be written</param>
public static void WriteFile(byte[] byteArray, string newDocument)
{
using (MemoryStream stream = new MemoryStream())
{
stream.Write(byteArray, 0, (int)byteArray.Length);
// Save the file with the new name
File.WriteAllBytes(newDocument, stream.ToArray());
}
}
From there, you can open it with OpenXML and edit the file. There's no way to open a Word document in byte[] form directly into an instance of Word - Interop, OpenXML, or otherwise - because you need a documentPath, or the stream method mentioned earlier that relies on there being a physical file. You can edit the bytes you would get by reading the bytes into a string, and XML afterwards, or just edit the string, directly:
string docText = null;
byte[] byteArray = null;
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(documentPath, true))
{
using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
{
docText = sr.ReadToEnd(); // <-- converts byte[] stream to string
}
// Play with the XML
XmlDocument xml = new XmlDocument();
xml.LoadXml(docText); // the string contains the XML of the Word document
XmlNodeList nodes = xml.GetElementsByTagName("w:body");
XmlNode chiefBodyNode = nodes[0];
// add paragraphs with AppendChild...
// remove a node by getting a ChildNode and removing it, like this...
XmlNode firstParagraph = chiefBodyNode.ChildNodes[2];
chiefBodyNode.RemoveChild(firstParagraph);
// Or play with the string form
docText = docText.Replace("John","Joe");
// If you manipulated the XML, write it back to the string
//docText = xml.OuterXml; // comment out the line above if XML edits are all you want to do, and uncomment out this line
// Save the file - yes, back to the file system - required
using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
{
sw.Write(docText);
}
}
// Read it back in as bytes
byteArray = File.ReadAllBytes(documentPath); // new bytes, ready for DB saving
Reference:
https://learn.microsoft.com/en-us/office/open-xml/how-to-search-and-replace-text-in-a-document-part
I know it's not ideal, but I have searched and not found a way to edit the byte[] directly without a conversion that involves writing out the file, opening it in Word for the edits, then essentially re-uploading it to recover the new bytes. Doing byte[] byteArray = Encoding.UTF8.GetBytes(docText); prior to re-reading the file will corrupt them, as would any other Encoding I tried (UTF7,Default,Unicode, ASCII), as I found when I tried to write them back out using my WriteFile() function, above, in that last line. When not encoded and simply collected using File.ReadAllBytes(), and then writing the bytes back out using WriteFile(), it worked fine.
Update:
It might be possible to manipulate the bytes like this:
//byte[] byteArray = File.ReadAllBytes("Test.docx"); // you might be able to assign your bytes here, instead of from a file?
byte[] byteArray = GetByteArrayFromDatabase(fileId); // function you have for getting the document from the database
using (MemoryStream mem = new MemoryStream())
{
mem.Write(byteArray, 0, (int)byteArray.Length);
using (WordprocessingDocument wordDoc =
WordprocessingDocument.Open(mem, true))
{
// do your updates -- see string or XML edits, above
// Once done, you may need to save the changes....
//wordDoc.MainDocumentPart.Document.Save();
}
// But you will still need to save it to the file system here....
// You would update "documentPath" to a new name first...
string documentPath = #"C:\temp\newDoc.docx";
using (FileStream fileStream = new FileStream(documentPath,
System.IO.FileMode.CreateNew))
{
mem.WriteTo(fileStream);
}
}
// And then read the bytes back in, to save it to the database
byteArray = File.ReadAllBytes(documentPath); // new bytes, ready for DB saving
Reference:
https://learn.microsoft.com/en-us/previous-versions/office/office-12//ee945362(v=office.12)
But note that even this method will require saving the document, then reading it back in, in order to save it to bytes for the database. It will also fail if the document is in .doc format instead of .docx on that line where the document is being opened.
Instead of that last section for saving the file to the file system, you could just take the memory stream and save that back into bytes once you are outside of the WordprocessingDocument.Open() block, but still inside the using (MemoryStream mem = new MemoryStream() { ... } statement:
// Convert
byteArray = mem.ToArray();
This will have your Word document byte[].