473,326 Members | 2,081 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,326 software developers and data experts.

I/O-Redirection:Console.In terminates unexpectedly

Hi All !

Problem:Reading/duplicating "Console.In" fails for unknown reason.

I wrote a little console helper tool, named TEE, which just duplicates
the StdIn to the StdOut AND an additional stream. Looks working
basically and the part that does this is like the following:

private static void CopyStream(TextWriter outStream, bool dup)
{
char temp;
while(Console.In.Peek() != -1)
{
temp = Convert.ToChar(Console.In.Read());
outStream.Write(temp);
if(dup) Console.Out.Write(temp);
}
}

I use it like this:

dir /s /b /a:-d d:\Develop | Tee d:\Develop.log

But unexpectedly, the resuling textfile does not contain all text send
by the dir command. And, for each time, the resulting textfile has other
content. This lokks like, the loop, shown above, terminates for unknown
reason at a random point.

I do not know, what is wrong with my code.
Any idea why this happens is really very welcome!

Thanks so far and
best regards,
Manfred
Jul 23 '06 #1
7 2272
mabra <mabra@homewrote:
I wrote a little console helper tool, named TEE, which just duplicates
the StdIn to the StdOut AND an additional stream. Looks working
basically and the part that does this is like the following:
But unexpectedly, the resuling textfile does not contain all text send
by the dir command. And, for each time, the resulting textfile has other
content. This lokks like, the loop, shown above, terminates for unknown
reason at a random point.

I do not know, what is wrong with my code.
StreamWriter (usually wrapped around a FileStream) buffers characters
before calling FileStream.Write(). What probably happened is that you
didn't dispose or flush the StreamWriter. Ideally you should put the
StreamWriter inside a using block. This program seems to work well for
me:

---8<---
using System;
using System.IO;

class Program
{
static void Main(string[] args)
{
using (TextWriter writer = File.CreateText(args[0]))
while (Console.In.Peek() != -1)
{
char ch = (char) Console.In.Read();
Console.Write(ch);
writer.Write(ch);
}
}
}
--->8---

-- Barry

--
http://barrkel.blogspot.com/
Jul 23 '06 #2
Hello Barry !

Thanks a lot !
I have modified my calling sequence to this:

TextWriter tw = new StreamWriter(filename);
T.CopyStream(tw, true, ref charCount);
tw.Flush(); /////NEW !!!!
tw.Close();

But even this does not help. BTW, your code has the same behavior like
mine:The output is always different. This happens only on larger
directory trees. While I originally "developed" my program, everything
looked fine :-(

The phenomen does not only exist for the "dir" command, xcopy also.
I re-wrote the proggi in VBScript and this gives excactly the same
result as "dir" itself. But I need it in .net because I am currently
writing some other filters too.

Best regards,
Manfred

Barry Kelly wrote:
mabra <mabra@homewrote:
>I wrote a little console helper tool, named TEE, which just duplicates
the StdIn to the StdOut AND an additional stream. Looks working
basically and the part that does this is like the following:
>But unexpectedly, the resuling textfile does not contain all text send
by the dir command. And, for each time, the resulting textfile has other
content. This lokks like, the loop, shown above, terminates for unknown
reason at a random point.

I do not know, what is wrong with my code.

StreamWriter (usually wrapped around a FileStream) buffers characters
before calling FileStream.Write(). What probably happened is that you
didn't dispose or flush the StreamWriter. Ideally you should put the
StreamWriter inside a using block. This program seems to work well for
me:

---8<---
using System;
using System.IO;

class Program
{
static void Main(string[] args)
{
using (TextWriter writer = File.CreateText(args[0]))
while (Console.In.Peek() != -1)
{
char ch = (char) Console.In.Read();
Console.Write(ch);
writer.Write(ch);
}
}
}
--->8---

-- Barry
Jul 23 '06 #3
mabra <mabra@homewrote:
But even this does not help. BTW, your code has the same behavior like
mine:The output is always different.
I see that now, it appears that TextReader uses different code paths
depending on whether you're reading a whole line, character by character
or in blocks - and the behaviour is different, too. It actually looks
like a bug in the BCL. I need to look into it further.

Here's a working version - it'll perform better too:

---8<---
using System;
using System.IO;

class Program
{
static void Main(string[] args)
{
char[] buffer = new char[1024];
using (TextWriter writer = File.CreateText(args[0]))
{
for (;;)
{
int read = Console.In.ReadBlock(buffer, 0,
buffer.Length);
if (read == 0)
break;

Console.Out.Write(buffer, 0, read);
writer.Write(buffer, 0, read);
}
}
}
}
--->8---

-- Barry

--
http://barrkel.blogspot.com/
Jul 23 '06 #4
Hello Barry,

and much thanks for your investigation.

Your lastest version really get's the whole input!! But I disagree on
your performance statement:The proggi has some strong pauses reading the
input - first, I thought, it hungs!

My posting here was just the attempt to address a problem. I normally
would like to read lines and apply a filter on it, but I found no way to
read a line of text and then determine the readers status, so I came to
the Peek() controlled loop. And I usually try to "echo" the readed line
to provide the flow/feedback of the operation to the user [for long
running operations]. I am missing something like "ReaderIsAtEnd" or
"ReaderClosed()" or a "ReaderDisconnected" event. "Peek()" seems to fail.

If I would - according to my original code snippet posted - use the
following:

string temp2 = Console.In.ReadToEnd();
outStream.Write(temp2);
if(dup) Console.Out.Write(temp2);

This works as expected, except for the feedback and the ability to
filter lines :-(

I just made another attempt:I started a new process and redirected it's
output. But there is no difference and the behaviors is excactly the same.

ProcessStartInfo psi = new ProcessStartInfo("cmd.exe", " /c dir /a:-d /s
/b d:\\develop");
psi.RedirectStandardOutput = true;
Process p = new Process();
p.StartInfo = psi;
p.Start();

do
{
Console.WriteLine(outputReader.ReadLine());
} while (outputReader.Peek() == -1);

This does not work [returns ONE line!!!] and the subprocess keeps
running until I use:

Console.Write(p.StandardOutput.ReadToEnd());

Additionally, with the console, mostly you have to use adiitional
P/Invoke code:Control-C events, logoff, PeekConsoleInput !!!

Some improvements would be really great, this is always work.
I am a System Manager not really a developer ;-)

Thanks so far and
best regards,
Manfred

Barry Kelly wrote:
mabra <mabra@homewrote:
>But even this does not help. BTW, your code has the same behavior like
mine:The output is always different.

I see that now, it appears that TextReader uses different code paths
depending on whether you're reading a whole line, character by character
or in blocks - and the behaviour is different, too. It actually looks
like a bug in the BCL. I need to look into it further.

Here's a working version - it'll perform better too:

---8<---
using System;
using System.IO;

class Program
{
static void Main(string[] args)
{
char[] buffer = new char[1024];
using (TextWriter writer = File.CreateText(args[0]))
{
for (;;)
{
int read = Console.In.ReadBlock(buffer, 0,
buffer.Length);
if (read == 0)
break;

Console.Out.Write(buffer, 0, read);
writer.Write(buffer, 0, read);
}
}
}
}
--->8---

-- Barry
Jul 23 '06 #5
Hi Barry and All !

Not best, but works [to my original code snippet]:

string temp2 = null;
while((temp2 = Console.In.ReadLine())!= null) //!!!!!!!!!!
{
outStream.WriteLine(temp2);
if(dup) Console.Out.WriteLine(temp2);
}

Just another idea, found in the wild of the internet ;-)
This works.

Best regards,
Manfred

mabra wrote:
Hello Barry,

and much thanks for your investigation.

Your lastest version really get's the whole input!! But I disagree on
your performance statement:The proggi has some strong pauses reading the
input - first, I thought, it hungs!

My posting here was just the attempt to address a problem. I normally
would like to read lines and apply a filter on it, but I found no way to
read a line of text and then determine the readers status, so I came to
the Peek() controlled loop. And I usually try to "echo" the readed line
to provide the flow/feedback of the operation to the user [for long
running operations]. I am missing something like "ReaderIsAtEnd" or
"ReaderClosed()" or a "ReaderDisconnected" event. "Peek()" seems to fail.

If I would - according to my original code snippet posted - use the
following:

string temp2 = Console.In.ReadToEnd();
outStream.Write(temp2);
if(dup) Console.Out.Write(temp2);

This works as expected, except for the feedback and the ability to
filter lines :-(

I just made another attempt:I started a new process and redirected it's
output. But there is no difference and the behaviors is excactly the same.

ProcessStartInfo psi = new ProcessStartInfo("cmd.exe", " /c dir /a:-d /s
/b d:\\develop");
psi.RedirectStandardOutput = true;
Process p = new Process();
p.StartInfo = psi;
p.Start();

do
{
Console.WriteLine(outputReader.ReadLine());
} while (outputReader.Peek() == -1);

This does not work [returns ONE line!!!] and the subprocess keeps
running until I use:

Console.Write(p.StandardOutput.ReadToEnd());

Additionally, with the console, mostly you have to use adiitional
P/Invoke code:Control-C events, logoff, PeekConsoleInput !!!

Some improvements would be really great, this is always work.
I am a System Manager not really a developer ;-)

Thanks so far and
best regards,
Manfred

Barry Kelly wrote:
>mabra <mabra@homewrote:
>>But even this does not help. BTW, your code has the same behavior
like mine:The output is always different.

I see that now, it appears that TextReader uses different code paths
depending on whether you're reading a whole line, character by character
or in blocks - and the behaviour is different, too. It actually looks
like a bug in the BCL. I need to look into it further.

Here's a working version - it'll perform better too:

---8<---
using System;
using System.IO;

class Program
{
static void Main(string[] args)
{
char[] buffer = new char[1024];
using (TextWriter writer = File.CreateText(args[0]))
{
for (;;)
{
int read = Console.In.ReadBlock(buffer, 0,
buffer.Length);
if (read == 0)
break;
Console.Out.Write(buffer, 0, read);
writer.Write(buffer, 0, read);
}
}
}
}
--->8---

-- Barry
Jul 23 '06 #6
mabra <mabra@homewrote:
string temp2 = null;
while((temp2 = Console.In.ReadLine())!= null) //!!!!!!!!!!
{
outStream.WriteLine(temp2);
if(dup) Console.Out.WriteLine(temp2);
}

Just another idea, found in the wild of the internet ;-)
This works.
It works, but it doesn't print characters as it receives them. Another
thing I'd suggest is constructing the stream reader with a buffer of one
character.

-- Barry

--
http://barrkel.blogspot.com/
Jul 24 '06 #7
Hello Barry !

Sorry, for being so late :-(

I just wrote a simple app which sends a message to the pipe and waits two
seconds. It sends ten messages. If I redirect the output to the TEE program,
the message is displayed immidiately!

Thanks for the one-byte-buffer suggestion. That might help.
I'l try this out also.

Thanks so far and
best regards,
Manfred
[the same:But from another account]

"Barry Kelly" <ba***********@gmail.comwrote in message
news:el********************************@4ax.com...
mabra <mabra@homewrote:
>string temp2 = null;
while((temp2 = Console.In.ReadLine())!= null) //!!!!!!!!!!
{
outStream.WriteLine(temp2);
if(dup) Console.Out.WriteLine(temp2);
}

Just another idea, found in the wild of the internet ;-)
This works.

It works, but it doesn't print characters as it receives them. Another
thing I'd suggest is constructing the stream reader with a buffer of one
character.

-- Barry

--
http://barrkel.blogspot.com/

Jul 24 '06 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Richard | last post by:
Good morning all I need a way in visual basic 6, to start a console process, like ping -A xxx.xxx.xxx.xxx > outputfile.txt and make vb hold its own execution till this process finishes....
4
by: Niel | last post by:
Hello friends, I am not sure if i am posting to the correct group but if anyone has an idea about this and the possible solution or the link to that solution then please let me know We have out...
7
by: Job Lot | last post by:
How can I terminate console application in Try…Catch…Finally…End Try block so that code in Finally gets executed. If I use End statement Finally does not get executed. Following is my code...
11
by: Chris | last post by:
Hi, For info I am using VS 2005 beta 2 I have a Console App and I want it to do the equivalent of a Change Directory (CD) command that you would do in normal command line mode as follows: ...
2
by: Matt Sollars | last post by:
Hi all. I'm having a nasty problem. A client's website was originally written with classic ASP. They requested a new portion of the site that was deemed a perfect candidate for ASP.NET. So, .NET...
5
by: Klaus Löffelmann | last post by:
Hi, it may be a stupid question and maybe I'm not seeing the wood for the trees, but how do I let the console window remaining open after the app terminates? (Console.Readline as last code...
3
by: Ramesh Dodamani | last post by:
Environment: XP Pro, VS.Net 2003, .Net 1.1.4322 with SP1 & KB Hotfix 886903 P4 2.2GHz, 1 GB RAM My system was working fine till a few weeks back when I started seeing the following errors. ...
1
by: Brad Wylie | last post by:
I have written a console project that uses a console window to display the output using Console.WriteLine. How do I keep the console window open after the writing the output as it seems to close...
4
by: Jake Yu | last post by:
hi, i want to make the console application running at the background but not as a service by hiding the console window... can anyone help me on this? Jake
12
by: Dilip | last post by:
Hi All I have a server based C# console application. This application must hide its console window when its launched out on the field. So I dutifully P/Invoke'd FindWindow/ShowWindow...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.