I am having trouble with OpenOffice Calc opening a CSV file that I create using StreamWriter C#. When it opens it has empty lines between every line that should be there(double-spaced). There seems to be some kind of doubling of the carriage returns. When I open it in Notepad it reads correctly. When I changed the program to write integers instead of strings the problem went away. It seems to be adding a return on the end of each string and then the formating adds another return that I'm not seeing.
Output looks like this...
1...
2...
3...
Output should look like this...
1...
2...
3...
Here is the ForEach loop I use to write the List to file...
using (StreamWriter sw = new StreamWriter(#"c:\andy\Arduino StreamWriter.csv", false, Encoding.UTF8))
{
foreach (string element in SerialPortString)
{
sw.WriteLine(element);
}
}
There is only one field of data per line, so there are no delimiters, just new lines. I tried formatting so that it would write with quotes around each field hoping that would eliminate confusion for the CSV format, but I wasn't able to figure that out either.
Any help would be appreciated.
Thanks.
Change
sw.WriteLine(element);
to
sw.WriteLine(element.Trim());
or maybe
sw.WriteLine(element.TrimEnd());
Trim the element first. That will remove any LineFeeds or other whitespace characters around the 'edges' of the characters. Then the StreamWriter's CRLFs will be the only newlines present.
Related
I have what I believed to be new line feed\carriage return in tab delimited file that I am reading using C# Stream Reader, please see an extract below, the second and third lines is actually a single line that contains what I believed to be carriage return after "NL" on the second line. I have tried using the code below to determine the presence of new line\carriage return, but no luck.
Could someone please help?
Code extract
string line = sr.ReadLine();
if (line.EndsWith(Environment.NewLine))
{
MessageBox.Show("New line detected");
}
File extract
1224 TX68176 FR123 0.2241 2788848 JP31650 B62G7K6 J7618E108 8630
----------
1225 TX68176 NL
----------
128 0.2241 2788848 JP3165000 B62G7K6 J7618E108 8630
Because you are reading the line with ReadLine, you will never get an Environment.NewLine at the end of the line. Your real problem is that you have a line of data, which you are probably expecting to be a single line, split into multiple lines. The exception you are getting does not come from having an newline in the line you read, and you are not going to fix it by trying to detect a newline character.
The problem probably comes from the rest of your code expecting fields in the line that are not there, because this part of the code read a line of text data that was only a partial line of data. The rest of your code chokes on not getting all the fields in that data line. To detect that you have only a partial line of data, you will need to probably detect on line length, since it seems to be a fixed length formatted file, or detect on the number of fields after you split it with tabs.
I am trying to append a line to a text file but by removing the enclosing bracket first.
Below is how my text file data format looks like
{
"1455494402": 8,
"1456272000": 2,
"1456358400": 1}
Now when I append the text file data should look like this
{
"1455494402": 8,
"1456272000": 2,
"1456358400": 1,
"1454716800": 1,
"1454803200": 4,
"1454889600": 7,
"1458345600": 17,
"1458518400": 1 }
There are two options to do this, I think,
By overwriting the whole file with new data (burden right? Performance hit)
Or By just appending the latest data(seems fast but not possible without removing last bracket)
First option is not so smart, I think.
Second option is cool but how do I remove the last bracket before appending the latest data, can't I just replace } with new data ?
So far my research has taught me that writing to the file again is the only better option, do you also think so? can't just append (in the sense remove bracket and append)
EDIT: Please do not consider this as duplicate, i am willing to know if that second option possible or not ? However I know i can do with first option mentioned in the details above
Assuming that:
You know that there will be a curly bracket (or any other character that is encoded as a single byte) at the end of the file,
The file is written as UTF8
then you can overwrite the last character as follows:
string filename = "test.txt";
File.WriteAllText(filename, "{One\nTwo\nThree}"); // Note curly brace at the end.
using (var file = new StreamWriter(File.OpenWrite(filename)))
{
file.BaseStream.Position = file.BaseStream.Length - 1;
file.Write("\nfour}"); // New line at end, previous brace is replaced.
}
This is very fragile, however. If the last character happens to be one that is encoded in more than one byte, then this will not work.
It is likely that it's not worth you taking the chance unless the files are very large and you have made timings that indicate it is worth introducing such brittle code to speed it up.
Note that this code can also be modified to work with ASCII or ANSI files by changing the encoding passed to the StreamWriter() constructor.
I'm doing a little program where the data saved on some users are stored in a text file. I'm using Sytem.IO with the Streamwriter to write new information to my text file.
The text in the file is formatted like so :
name1, 1000, 387
name2, 2500, 144
... and so on. I'm using infos = line.Split(',') to return the different values into an array that is more useful for searching purposes. What I'm doing is using a While loop to search for the correct line (where the name match) and I return the number of points by using infos[1].
I'd like to modify this infos[1] value and set it to something else. I'm trying to find a way to replace a word in C# but I can't find a good way to do it. From what I've read there is no way to replace a single word, you have to rewrite the complete file.
Is there a way to delete a line completely, so that I could rewrite it at the end of the text file and not have to worried about it being duplicated?
I tried using the Replace keyword, but it didn't work. I'm a bit lost by looking at the answers proposed for similar problems, so I would really appreciate if someone could explain me what my options are.
If I understand you correctly, you can use File.ReadLines method and LINQ to accomplish this.First, get the line you want:
var line = File.ReadLines("path")
.FirstOrDefault(x => x.StartsWith("name1 or whatever"));
if(line != null)
{
/* change the line */
}
Then write the new line to your file excluding the old line:
var lines = File.ReadLines("path")
.Where(x => !x.StartsWith("name1 or whatever"));
var newLines = lines.Concat(new [] { line });
File.WriteAllLines("path", newLines);
The concept you are looking for is called 'RandomAccess' for file reading/writing. Most of the easy-to-use I/O methods in C# are 'SequentialAccess', meaning you read a chunk or a line and move forward to the next.
However, what you want to do is possible, but you need to read some tutorials on file streams. Here is a related SO question. .NET C# - Random access in text files - no easy way?
You are probably either reading the whole file, or reading it line-for-line as part of your search. If your fields are fixed length, you can read a fixed number of bytes, keep track of the Stream.Position as you read, know how many characters you are going to read and need to replace, and then open the file for writing, move to that exact position in the stream, and write the new value.
It's a bit complex if you are new to streams. If your file is not huge, copying a file line for line can be done pretty efficiently by the System.IO library if coded correctly, so you might just follow your second suggestion which is read the file line-for-line, write it to a new Stream (memory, temp file, whatever), replace the line in question when you get to that value, and when done, replace the original.
It is most likely you are new to C# and don't realize the strings are immutable (a fancy way of saying you can't change them). You can only get new strings from modifying the old:
String MyString = "abc 123 xyz";
MyString.Replace("123", "999"); // does not work
MyString = MyString.Replace("123", "999"); // works
[Edit:]
If I understand your follow-up question, you could do this:
infos[1] = infos[1].Replace("1000", "1500");
I use a OleDb data reader to read a number of records, and then write them to a CSV. I then read from this CSV using File.ReadAllLines, then split on commas to get my data. The problem is some parts of the CSV include a character I can't display (shows up as a square), which appears to act as a line break - this line break corrupts the CSV, so I need to get rid of it.
I've tried replacing Environment.NewLine with something else (a blank space) when writing the CSV, and ditto with /r and /n but to no avail - the character isn't replaced. What other ways are there to remove these?
I then read from this CSV using File.ReadAllLines, then split on commas to get my data.
Stop rolling your own CSV parser.
Dont write CSV file's this way... as it won't work in every scenario.
Use OLD DB to do it for you.
http://devlicio.us/blogs/sergio_pereira/archive/2008/09/17/tip-export-to-csv-using-ado-net.aspx
Hope that helps.
I'm using the textwriter to write data to a text file but if the line exceeds 1024 characters a line break is inserted and this is a problem for me. Any suggestions on how to work round this or increase the character limit?
textWriter.WriteLine(strOutput);
Many thanks
Use Write, not WriteLine
Well you're using TextWriter.WriteLine(string) which appends \r\n after strOutput. As the docs say:
Writes a string followed by a line terminator to the text stream.
(Emphasis mine.) That has nothing to do with 1024 characters though - my guess is that that's how you're reading it in (e.g. with a buffer of 1024 characters).
To avoid the extra line break, just use
textWriter.Write(strOutput);
EDIT: You say in the comment that you need a line break after "the full line has been written out" - but it sounds like strOutput isn't always the same line.
I suspect the easiest way of accomplishing what you want is to separate the "copying" side out from the "line break" side. Use Write for all the text you want to copy, and then just call
textWriter.WriteLine();
when you want a line break. If this doesn't help, I think we're going to need more context - please provide a code sample of exactly what you're doing.
I wrote a sample app that writes and read a 1025 character string. The size never changes. Although if I opened it with notepad.exe (Windows) I can see the extra character in the second line. These seems like a notepad limitation. Here is my sample code
static void Main(string[] args)
{
using (TextWriter streamWriter = new StreamWriter("lineLimit.txt")) {
String s=String.Empty;
for(int i=0;i<1025;i++){
s+= i.ToString().Substring(0,1);
}
streamWriter.Write(s);
streamWriter.Close();
}
using (TextReader streamReader = new StreamReader("lineLimit.txt"))
{
String s = streamReader.ReadToEnd();
streamReader.Close();
Console.Out.Write(s.Length);
}
}
if you need to add the line breaks at the end of your output just append them.
textWriter.Write(strOutput +"\r\n");