C# TextWriter inserting line break every 1024 characters - c#

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

Related

CSV file double-spacing lines

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.

Check for carriage return\line feed in tab delimited text file in C#

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.

Reading a text file from Unity3d

I have a error in a script which reads from a text file outside the program.
The error is
FormatException: Input string was not in the correct format
Its obvious whats wrong, but I just don't understand why it cant read it properly.
My code:
using (FileStream fs = new FileStream(#"D:\Program Files (x86)\Steam\SteamApps\common\blabla...to my file.txt))
{
byte[] b = new byte[1024];
UTF8Encoding temp = new UTF8Encoding(true);
while (fs.Read(b, 0, b.Length) > 0)
{
//Debug.Log(temp.GetString(b));
var converToInt = int.Parse(temp.GetString(b));
externalAmount = converToInt;
}
fs.Close();
}
The text file has 4 lines of values.
Each line represent a object in a game. All I am trying to do is read these values. Unfortunately I get the error which I can't explain.
So how can I read new lines without getting the error?
the text file looks like this
12
5
6
0
4 lines no more, all values on a seperate line.
There's no closing " on your new Filestream(" ...); but I'm gonna assume that's an issue when copy pasting your code to Stackoverflow.
The error you're getting is likely because you're trying to parse spaces to int, which wont work; the input string (" " in this case) was not in the correct format (int).
Split your lines on spaces (Split.(' ')) and parse every item in the created array.
A couple problems:
Problem 1
fs.Read(b, 0, b.Length) may read one byte, or all of them. The normal way to read a text file like this is to use StreamReader instead of FileStream. The Streamreader has a convenience constructor for opening a file that works the same way, but it can read line by line and is much more convenient. Here's the documentation and an excellent example: https://msdn.microsoft.com/en-us/library/f2ke0fzy(v=vs.110).aspx
If you insist on reading directly from a filestream, you will either need to
Parse your string outside the loop so you can be certain you've read the whole file into your byte buffer (b), or
Parse the new content byte by byte until you find a particular separator (for example a space or a newline) and then parse everything in your buffer and reset the buffer.
Problem 2
Most likely your buffer already contains everything in the file. Your file is so small that the filestream object is probably reading the whole thing in a single shot, even though that's not gauranteed.
Since your string buffer contains ALL the characters in the file you are effectively trying to parse "12\n5\n6\n0" as an integer and the parser is choking on the newline characters. Since newlines are non-numeric, it has no idea how to interpret them.

Why does StreamReader.ReadLine() return a value for a one line file with no newline?

I want to append two text files together.
I have one file with a carriage return line feed at the end. Observe file A which is 28 bytes.
this is a line in the file\n
then I have another file which is the same thing without the new line. Observe file B which is 26 bytes.
this is a line in the file
I want to append the same file to itself (file A to A, and file B to B) and compare the byte counts.
However, when using StreamReader.ReadLine() on file A, I get a value returned but MSDN says:
A line is defined as a sequence of characters followed by a line feed ("\n"), a carriage return ("\r") or a carriage return immediately followed by a line feed ("\r\n"). The string that is returned does not contain the terminating carriage return or line feed. The returned value is null if the end of the input stream is reached.
However, there is no crlf in the file.
How can I safely append these files without adding an extra line break at the end? For example, StreamWriter.WriteLine() will put an extra line break on file A when I don't want it to. What would be an ideal approach?
You'll only get null if you call ReadLine at the end of the stream. Otherwise, you'll get all data up until either a CRLF or the end of the stream.
If you're trying to do a byte-for-byte duplication (and comparison), you're better off reading either characters (using StreamReader/StreamWriter as you're using now) or bytes (using just using the Stream class) using the normal Read and Write functions rather than ReadLine and WriteLine.
You could also just read the entire contents of the file using ReadToEnd then write it by calling Write (not WriteLine), though this isn't practical if the file is large.
string data;
using(StreamReader reader = new StreamReader(path))
{
data = reader.ReadToEnd();
}
using(StreamWriter writer = new StreamWriter(path, true))
{
writer.Write(data);
}
StreamReader and StreamWriter (which derive from TextReader and TextWriter) are not suitable for situations requiring an exact form of binary data. They are high level abstractions of a file which consists of bytes, not text or lines. In fact, not only could you wind up with different number of newlines, but depending on the environment you might write out a line terminator other than the expected CR/LF.
You should instead just copy from one stream to another. This is quite easy actually.
var bytes = File.ReadAllBytes(pathIn);
var stream = File.Open(pathOut, FileMode.Append);
stream.Write(bytes, 0, bytes.Length);
stream.Close();
If the size of the file is potentially large, you should open both the input and output file at the same time and use a fixed-sized buffer to copy a block at a time.
using (var streamIn = File.Open(pathIn, FileMode.Read))
using (var streamOut = File.Open(pathOut, FileMode.Append)) {
var bytes = new byte[BLOCK_SIZE];
int count;
while ((count=streamIn.Read(bytes, 0, bytes.Length)) > 0) {
streamOut.Write(bytes, 0, count);
}
}
Also worth noting is that the above code could be replaced by Stream.CopyTo which is new in .NET 4.
You can use StreamWriter.Write instead of WriteLine to avoid the extra crlf.
As to the ReadLine docs, I beleive the problem is a poorly worded explanation. You certainly wouldn't want the last bytes of a file discarded just because there is no formal line ending flag.
Well it really depends on the reasons for your implementation (Why are you reading it by line and writing it back line by line?) You could just use StreamWriter.Write(string) and output all the text you have stored, the WriteLine() methods are named as such because they append a newline.
TextWriter.WriteLine Method (String)
Writes a string followed by a line terminator to the text stream.

StreamWriter is writing carriage returns?

I have a very simple console application that creates a text file. Below is a recap of the code:
StreamWriter writer = File.CreateText("c:\\temp.txt");
foreach (blah...)
{
writer.Write(body.ToString() + "\n");
writer.Flush();
}
writer.Close();
The client is claiming there are carriage returns at the end of each line. Where are these carriage returns coming from?
Update: After opening in VS binary editor and Notepad++, there were no occurrences of 0d 0a. I'm going to go back to the client.
Open the file in the Visual Studio binary editor (File.Open.File, click down-arrow on Open button, choose Open With... and pick Binary Editor), and look for 0D bytes. If none are present, then either:
your client can't tell the the difference between a line feed and a carriage return,
your transmission method is modifying the file en-route. Is there any FTP binary/ascii mismatch going on?
If there are 0D bytes, then they are present in your body variable.
I tested your code.
alt text http://img830.imageshack.us/img830/5443/18414385.png
The code you posted does not have any carriage returns (0D) only new lines (0A). Something else is creating the carriage returns or the client does not know what a carriage return really is.
In your code you put a line feed (\n).
Your customer is talking about a carriage return (\r). Maybe your customer is taking a line feed per a carriage return ?
The "\n" at the end of each write call
EDIT: I know this is a new line, not a carriage return but I bet any money the client is getting confused between the two and it's actually this that is causing the problem
Does the client distinguish between a CR and LF? Is the flush() necessary? Are you overloading the buffer if you don't flush?
Unless you have a massive amount of text you might find more use out of creating a StringBuilder to format the text exactly as you want it with \n, \r, \t or whatever and then pumping that directly into a StreamWriter.
If each body string's first character was '\r', it would explain what you're seeing.
Have you checked whether body is also ending with characters you don't want printed? This is the other potential problem source.

Categories