Reassign standard Output Stream.

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • dmjpro
    Top Contributor
    • Jan 2007
    • 2476

    #16
    Originally posted by r035198x
    When you redirect the output you don't change the out variable itself. It is final and cannot be reassigned.
    You just provide the runtime with a new PrintStream object to use when printing out.
    That can be done using [code=java]System.setOut(n ew PrintStream(..) )[/code]
    But how this function redirects the O/P?
    When System.out.prin tln("") is called then System.out is still standard O/P, in spite of that how the O/P redirects to new one?
    Please help !

    Kind regards,
    Dmjpro.

    Comment

    • Nepomuk
      Recognized Expert Specialist
      • Aug 2007
      • 3111

      #17
      Originally posted by dmjpro
      That can be done using [code=java]System.setOut(n ew PrintStream(..) )[/code]
      But how this function redirects the O/P?
      When System.out.prin tln("") is called then System.out is still standard O/P, in spite of that how the O/P redirects to new one?
      Please help !

      Kind regards,
      Dmjpro.
      The System class has a PrintWriter from the beginning. You just assign a new PrintWriter in it's position.
      It would look something like this:
      [CODE=java]
      public class System {
      private static PrintWriter ps = new PrintStream(... ); // Whatever the standard output is
      public static void setOut(PrintWri ter nps)
      {
      ps = nps;
      }
      }
      [/CODE]
      Greetings,
      Nepomuk

      Comment

      • dmjpro
        Top Contributor
        • Jan 2007
        • 2476

        #18
        Originally posted by nepomuk
        The System class has a PrintWriter from the beginning. You just assign a new PrintWriter in it's position.
        It would look something like this:
        [CODE=java]
        public class System {
        private static PrintWriter ps = new PrintStream(... ); // Whatever the standard output is
        public static void setOut(PrintWri ter nps)
        {
        ps = nps;
        }
        }
        [/CODE]
        Greetings,
        Nepomuk
        Ok!
        Then how do System.out.prin tln method come to know that standard O/P changed and println method writes to the new one.
        Actually println method should have the track of that :-)
        Please help !

        Kind regards,
        Dmjpro.

        Comment

        • JosAH
          Recognized Expert MVP
          • Mar 2007
          • 11453

          #19
          Originally posted by dmjpro
          Ok!
          Then how do System.out.prin tln method come to know that standard O/P changed and println method writes to the new one.
          Actually println method should have the track of that :-)
          Please help !

          Kind regards,
          Dmjpro.
          When you install a jdk on your computer. in the jdk's home directory a src.zip
          file is stored; it contains all the sources of all the classes in the core library,
          including System's source code. Read it and see for yourself how this class
          redirects the 'standard' streams.

          kind regards,

          Jos

          Comment

          • Nepomuk
            Recognized Expert Specialist
            • Aug 2007
            • 3111

            #20
            Originally posted by dmjpro
            Ok!
            Then how do System.out.prin tln method come to know that standard O/P changed and println method writes to the new one.
            Actually println method should have the track of that :-)
            Please help !

            Kind regards,
            Dmjpro.
            It doesn't. It doesn't even care.

            It could look like this (simplified):
            [CODE=java]
            public class System {
            private static PrintStream ps = new PrintStream(... ); // standard OutputStream
            public static setOut(Printstr eam nps)
            {
            ps = nps;
            }
            public static void print(char c)
            {
            ps.write(c);
            }
            public static void print(String s)
            {
            for(int i=0; i<s.length(); i++)
            {
            print(s.charAt( i));
            }
            }
            public static void println(String s)
            {
            print(s + '\n');
            }
            // ...
            }
            [/CODE]so it will just use the PrintStream (ps) that's there. It uses that, when no PrintStream was set manually (it will use the standard PrintStream) and it will use that, after it was changed. It doesn't care, that it's a different Stream, as the name is the same.

            Greetings,
            Nepomuk

            Comment

            • dmjpro
              Top Contributor
              • Jan 2007
              • 2476

              #21
              Originally posted by nepomuk
              It doesn't. It doesn't even care.

              It could look like this (simplified):
              [CODE=java]
              public class System {
              private static PrintStream ps = new PrintStream(... ); // standard OutputStream
              public static setOut(Printstr eam nps)
              {
              ps = nps;
              }
              public static void print(char c)
              {
              ps.write(c);
              }
              public static void print(String s)
              {
              for(int i=0; i<s.length(); i++)
              {
              print(s.charAt( i));
              }
              }
              public static void println(String s)
              {
              print(s + '\n');
              }
              // ...
              }
              [/CODE]so it will just use the PrintStream (ps) that's there. It uses that, when no PrintStream was set manually (it will use the standard PrintStream) and it will use that, after it was changed. It doesn't care, that it's a different Stream, as the name is the same.

              Greetings,
              Nepomuk
              println is not the method of System class here :-)

              Kind regards,
              Dmjpro.

              Comment

              • JosAH
                Recognized Expert MVP
                • Mar 2007
                • 11453

                #22
                Originally posted by nepomuk
                It doesn't. It doesn't even care.

                It could look like this (simplified):
                [CODE=java]
                public class System {
                private static PrintStream ps = new PrintStream(... ); // standard OutputStream
                public static setOut(Printstr eam nps)
                {
                ps = nps;
                }
                public static void print(char c)
                {
                ps.write(c);
                }
                public static void print(String s)
                {
                for(int i=0; i<s.length(); i++)
                {
                print(s.charAt( i));
                }
                }
                public static void println(String s)
                {
                print(s + '\n');
                }
                // ...
                }
                [/CODE]so it will just use the PrintStream (ps) that's there. It uses that, when no PrintStream was set manually (it will use the standard PrintStream) and it will use that, after it was changed. It doesn't care, that it's a different Stream, as the name is the same.

                Greetings,
                Nepomuk
                But you don't do 'System.print( ... )', you have to use 'System.out.pri nt( ... )'.

                kind regards,

                Jos

                Comment

                • dmjpro
                  Top Contributor
                  • Jan 2007
                  • 2476

                  #23
                  Originally posted by JosAH
                  But you don't do 'System.print( ... )', you have to use 'System.out.pri nt( ... )'.

                  kind regards,

                  Jos
                  That's right Jos :-)
                  I will surely read the API Doc :-)

                  Kind regards,
                  Dmjpro.

                  Comment

                  • r035198x
                    MVP
                    • Sep 2006
                    • 13225

                    #24
                    Originally posted by nepomuk
                    ...
                    ps = nps;
                    ...
                    That wouldn't be the case because ps is actually final.

                    Comment

                    • JosAH
                      Recognized Expert MVP
                      • Mar 2007
                      • 11453

                      #25
                      Originally posted by r035198x
                      That wouldn't be the case because ps is actually final.
                      And it isn't called 'ps', its name is 'out' ;-)

                      kind regards,

                      Jos

                      Comment

                      • Nepomuk
                        Recognized Expert Specialist
                        • Aug 2007
                        • 3111

                        #26
                        Arg, I hadn't seen it was final... But ok, I've found a solution, which will allow you to reset the standard output. (It may not be the way, it's done within the System class, but it works!)

                        [CODE=java]
                        import java.io.*;

                        public class Sys {
                        private static NewPrintStream pStream = new NewPrintStream( System.out);
                        // Of course, this won't be with "System.out ", but that way you can see the output - they must get an OutputStream from somewhere
                        public static final PrintStream out = pStream;
                        public static void setOut(PrintStr eam nps)
                        {
                        pStream.setOut( nps);
                        }
                        }
                        class NewPrintStream extends PrintStream {
                        public NewPrintStream( OutputStream os)
                        {
                        super(os);
                        }
                        public void setOut(PrintStr eam ps)
                        {
                        this.out = ps;
                        }
                        }
                        [/CODE]When testing it with this
                        [CODE=java]
                        import java.io.*;

                        public class Test {
                        public static void main(String[] args)
                        {
                        Sys.out.println ("Hi");
                        try
                        {
                        Sys.setOut(new PrintStream(new FileOutputStrea m(new File("hello.txt "))));
                        }
                        catch(FileNotFo undException fnfe)
                        {
                        System.err.prin tln("Didn't work.");
                        }
                        Sys.out.println ("Hi");
                        }
                        }
                        [/CODE]It prints the first output of "Hi" to the standard output and the second one to a file called "hello.txt" .

                        Greetings,
                        Nepomuk

                        Comment

                        • r035198x
                          MVP
                          • Sep 2006
                          • 13225

                          #27
                          Originally posted by nepomuk
                          Arg, I hadn't seen it was final... But ok, I've found a solution, which will allow you to reset the standard output. (It may not be the way, it's done within the System class, but it works!)

                          [CODE=java]
                          import java.io.*;

                          public class Sys {
                          private static NewPrintStream pStream = new NewPrintStream( System.out);
                          // Of course, this won't be with "System.out ", but that way you can see the output - they must get an OutputStream from somewhere
                          public static final PrintStream out = pStream;
                          public static void setOut(PrintStr eam nps)
                          {
                          pStream.setOut( nps);
                          }
                          }
                          class NewPrintStream extends PrintStream {
                          public NewPrintStream( OutputStream os)
                          {
                          super(os);
                          }
                          public void setOut(PrintStr eam ps)
                          {
                          this.out = ps;
                          }
                          }
                          [/CODE]When testing it with this
                          [CODE=java]
                          import java.io.*;

                          public class Test {
                          public static void main(String[] args)
                          {
                          Sys.out.println ("Hi");
                          try
                          {
                          Sys.setOut(new PrintStream(new FileOutputStrea m(new File("hello.txt "))));
                          }
                          catch(FileNotFo undException fnfe)
                          {
                          System.err.prin tln("Didn't work.");
                          }
                          Sys.out.println ("Hi");
                          }
                          }
                          [/CODE]It prints the first output of "Hi" to the standard output and the second one to a file called "hello.txt" .

                          Greetings,
                          Nepomuk
                          Well the System class already has a setOut so there's no need to reinvent the wheel is there?

                          Comment

                          • Nepomuk
                            Recognized Expert Specialist
                            • Aug 2007
                            • 3111

                            #28
                            Originally posted by r035198x
                            Well the System class already has a setOut so there's no need to reinvent the wheel is there?
                            Reason: Curiosity! ^^

                            The OP did ask, how it is done and I've posted a possible solution that may be used. That's it.

                            By the way, if anyone ever wants to change an Object defined as "final", this might be of interest...

                            Greetings,
                            Nepomuk

                            Comment

                            Working...