Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #31879 > unrolled thread

basic output question

Started by"Russ P." <russ.paielli@gmail.com>
First post2015-06-29 11:39 -0700
Last post2015-06-30 15:27 -0400
Articles 10 — 4 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  basic output question "Russ P." <russ.paielli@gmail.com> - 2015-06-29 11:39 -0700
    Re: basic output question Arne Vajhøj <arne@vajhoej.dk> - 2015-06-29 14:53 -0400
    Re: basic output question Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-06-29 15:32 -0400
    Re: basic output question e.d.programmer@gmail.com - 2015-06-30 05:45 -0700
      Re: basic output question Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-06-30 09:05 -0400
        Re: basic output question e.d.programmer@gmail.com - 2015-06-30 11:28 -0700
          Re: basic output question Arne Vajhøj <arne@vajhoej.dk> - 2015-06-30 14:55 -0400
            Re: basic output question e.d.programmer@gmail.com - 2015-06-30 12:14 -0700
              Re: basic output question Arne Vajhøj <arne@vajhoej.dk> - 2015-07-27 22:25 -0400
          Re: basic output question Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-06-30 15:27 -0400

#31879 — basic output question

From"Russ P." <russ.paielli@gmail.com>
Date2015-06-29 11:39 -0700
Subjectbasic output question
Message-ID<635be647-55fb-43f9-8609-0320306ca853@googlegroups.com>
Suppose I need a function (or method) for printing some (text-based) information to a file or to standard output. What is the recommended way to do this while minimizing duplication of code? Here's a simplification of what I came up with (in Scala, but using the Java standard library):

    def printInformation(out: java.io.PrintStream = System.out) {

        // print information here
        }

    def printInformation(fileName: String) {
        printInformation(new java.io.PrintStream(fileName))
        }

So if I call printInformation with no arguments, the output goes to standard output, but if I give it a filename the output goes to the file. Is this the best way to do it, or is there a simpler/better way? I'd also like to be able to append the output to an existing file as well as create a new file. Thanks.

[toc] | [next] | [standalone]


#31880

FromArne Vajhøj <arne@vajhoej.dk>
Date2015-06-29 14:53 -0400
Message-ID<55919420$0$295$14726298@news.sunsite.dk>
In reply to#31879
On 6/29/2015 2:39 PM, Russ P. wrote:
> Suppose I need a function (or method) for printing some (text-based)
> information to a file or to standard output. What is the recommended
> way to do this while minimizing duplication of code? Here's a
> simplification of what I came up with (in Scala, but using the Java
> standard library):
>
> def printInformation(out: java.io.PrintStream = System.out) {
>
> // print information here }
>
> def printInformation(fileName: String) { printInformation(new
> java.io.PrintStream(fileName)) }
>
> So if I call printInformation with no arguments, the output goes to
> standard output, but if I give it a filename the output goes to the
> file. Is this the best way to do it, or is there a simpler/better
> way? I'd also like to be able to append the output to an existing
> file as well as create a new file. Thanks.

You will need some overloads to achieve what you want.

But it should be trivial to do.

I would make sure to close any stream opened before returning.

And in general I would recommend having data classes only know
how to produce a string representation and let another class do the
actual IO.

I also somewhat suspect that you may be better off using a
logging framework.

:-)

Arne

[toc] | [prev] | [next] | [standalone]


#31882

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2015-06-29 15:32 -0400
Message-ID<mms6eo$810$1@dont-email.me>
In reply to#31879
On 6/29/2015 2:39 PM, Russ P. wrote:
> Suppose I need a function (or method) for printing some (text-based) information to a file or to standard output. What is the recommended way to do this while minimizing duplication of code? Here's a simplification of what I came up with (in Scala, but using the Java standard library):
>
>      def printInformation(out: java.io.PrintStream = System.out) {
>
>          // print information here
>          }
>
>      def printInformation(fileName: String) {
>          printInformation(new java.io.PrintStream(fileName))
>          }
>
> So if I call printInformation with no arguments, the output goes to standard output, but if I give it a filename the output goes to the file. Is this the best way to do it, or is there a simpler/better way? I'd also like to be able to append the output to an existing file as well as create a new file. Thanks.

     I'm not Scalacious and may misunderstand your intent, but it
seems a poor idea to create a brand-new PrintStream every time you
call printInformation().  You don't show them being closed, which
means they'll hang around until they're garbage-collected.  Also,
late arrivals will (attempt to) empty the output file and clobber
whatever the early birds may already have written.

     Instead, I'd suggest providing the PrintStream rather than
the file name: That way, you control the "external" aspects of the
stream and let the method focus solely on generating output:

	void printInfo(PrintStream out) {
	    // print information here
	}

     A simple overload handles the System.out default:

	void printInfo() {
	    printInfo(System.out);
	}

     As for appending vs. overwriting, that's a choice you can make
when you construct the PrintStream.  Instead of using the convenience
constructors that take a file name or a File, build the OutputStream
explicitly and construct the PrintStream from it:

	boolean append = ...;  // true to append, false to clobber
	PrintStream out = new PrintStream(
	    new FileOutputStream(fileName, append));

     Finally, note that separating the stream-handling from the
output-generation gives you more flexibility: You can now send output
to any destination you like, not just to a file.

     "Really finally," I second Arne Vajhøj's suggestion that you might
want to consider using an existing logging framework instead of rolling
your own wheel.  Much depends on what kind of information you're
printing and on what uses you'll make of it, but if it's "status and
progress" kind of stuff -- well, that's what logging's for.

-- 
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM

[toc] | [prev] | [next] | [standalone]


#31886

Frome.d.programmer@gmail.com
Date2015-06-30 05:45 -0700
Message-ID<450dd941-b331-4f46-9e9c-e7db4033e0ca@googlegroups.com>
In reply to#31879
On Monday, June 29, 2015 at 2:40:05 PM UTC-4, Russ P. wrote:
> Suppose I need a function (or method) for printing some (text-based) information to a file or to standard output. What is the recommended way to do this while minimizing duplication of code? Here's a simplification of what I came up with (in Scala, but using the Java standard library):
> 
>     def printInformation(out: java.io.PrintStream = System.out) {
> 
>         // print information here
>         }
> 
>     def printInformation(fileName: String) {
>         printInformation(new java.io.PrintStream(fileName))
>         }
> 
> So if I call printInformation with no arguments, the output goes to standard output, but if I give it a filename the output goes to the file. Is this the best way to do it, or is there a simpler/better way? I'd also like to be able to append the output to an existing file as well as create a new file. Thanks.

I never quite got the logging frameworks ie commons logging.  You have to deal with someone else's API, set warning levels, and include an extra jar in the classpath.  I wrote my own logging class since System.out.println() by itself is a bit too basic, and you don't want to write more than one line each time you print a log message.  My logging class does just use System.out.println() but with overloads to print a String, a number, or an Object.  All overloads call a common method which prints the message with a timestamp and gets the method that printed the message from the StackTrace.  The Object method has the condition to check if it's an array to print the value of each element.  Writing to a file I use another class, since as you say we want to avoid duplication.  You may want to print log messages to a file but there are a lot of other things you may want to write to a file.

[toc] | [prev] | [next] | [standalone]


#31887

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2015-06-30 09:05 -0400
Message-ID<mmu43k$tkm$1@dont-email.me>
In reply to#31886
On 6/30/2015 8:45 AM, e.d.programmer@gmail.com wrote:
> On Monday, June 29, 2015 at 2:40:05 PM UTC-4, Russ P. wrote:
>> Suppose I need a function (or method) for printing some (text-based) information to a file or to standard output. What is the recommended way to do this while minimizing duplication of code? Here's a simplification of what I came up with (in Scala, but using the Java standard library):
>>
>>      def printInformation(out: java.io.PrintStream = System.out) {
>>
>>          // print information here
>>          }
>>
>>      def printInformation(fileName: String) {
>>          printInformation(new java.io.PrintStream(fileName))
>>          }
>>
>> So if I call printInformation with no arguments, the output goes to standard output, but if I give it a filename the output goes to the file. Is this the best way to do it, or is there a simpler/better way? I'd also like to be able to append the output to an existing file as well as create a new file. Thanks.
>
> I never quite got the logging frameworks ie commons logging.

     s/ie/eg/

> You have to deal with someone else's API, [...]

     That's called "component reuse," and most people think of it
as a Good Thing.  In moderation, of course.

> [...] set warning levels, and include an extra jar in the classpath. [...]

     There's also the built-in java.util.logging package, assuming you're
using a post-2002 Java version.

-- 
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM

[toc] | [prev] | [next] | [standalone]


#31893

Frome.d.programmer@gmail.com
Date2015-06-30 11:28 -0700
Message-ID<91961835-9633-4c29-968d-027ce3fb9ff7@googlegroups.com>
In reply to#31887
> > On Monday, June 29, 2015 at 2:40:05 PM UTC-4, Russ P. wrote:
> >> Suppose I need a function (or method) for printing some (text-based) information to a file or to standard output. What is the recommended way to do this while minimizing duplication of code? Here's a simplification of what I came up with (in Scala, but using the Java standard library):
> >>
> >>      def printInformation(out: java.io.PrintStream = System.out) {
> >>
> >>          // print information here
> >>          }
> >>
> >>      def printInformation(fileName: String) {
> >>          printInformation(new java.io.PrintStream(fileName))
> >>          }
> >>
> >> So if I call printInformation with no arguments, the output goes to standard output, but if I give it a filename the output goes to the file. Is this the best way to do it, or is there a simpler/better way? I'd also like to be able to append the output to an existing file as well as create a new file. Thanks.
> >
> > I never quite got the logging frameworks ie commons logging.
> 
>      s/ie/eg/
> 
> > You have to deal with someone else's API, [...]
> 
>      That's called "component reuse," and most people think of it
> as a Good Thing.  In moderation, of course.
> 
> > [...] set warning levels, and include an extra jar in the classpath. [...]
> 
>      There's also the built-in java.util.logging package, assuming you're
> using a post-2002 Java version.
> 
> -- 
> esosman@comcast-dot-net.invalid
> "Don't be afraid of work. Make work afraid of you." -- TLM

Most people seem to be using the Apache Commons Logging.  I'm not sure why.
I just looked at java.util.logging.Logger and most of that seems irrelevant when all you want to do is write messages to System.out.  In my static log class I just add the timestamp and calling method and line number to every output line.  I don't want to get an instance of a logger object for every line to print much less configure a handler or assign a level.

[toc] | [prev] | [next] | [standalone]


#31894

FromArne Vajhøj <arne@vajhoej.dk>
Date2015-06-30 14:55 -0400
Message-ID<5592e61d$0$292$14726298@news.sunsite.dk>
In reply to#31893
On 6/30/2015 2:28 PM, e.d.programmer@gmail.com wrote:
>>> On Monday, June 29, 2015 at 2:40:05 PM UTC-4, Russ P. wrote:
>>>> So if I call printInformation with no arguments, the output
>>>> goes to standard output, but if I give it a filename the output
>>>> goes to the file. Is this the best way to do it, or is there a
>>>> simpler/better way? I'd also like to be able to append the
>>>> output to an existing file as well as create a new file.
>>>> Thanks.
>>>
>>> I never quite got the logging frameworks ie commons logging.
>>
>> s/ie/eg/
>>
>>> You have to deal with someone else's API, [...]
>>
>> That's called "component reuse," and most people think of it as a
>> Good Thing.  In moderation, of course.
>>
>>> [...] set warning levels, and include an extra jar in the
>>> classpath. [...]
>>
>> There's also the built-in java.util.logging package, assuming
>> you're using a post-2002 Java version.
>
> Most people seem to be using the Apache Commons Logging.  I'm not
> sure why.

It allows the code to be used with a different actual logging framework
with no code changes.

>     I just looked at java.util.logging.Logger and most of that
> seems irrelevant when all you want to do is write messages to
> System.out.

Usually people at some point end up needing to do something
more advanced that just writing to System.out.

OP already reached that level.

>             In my static log class I just add the timestamp and
> calling method and line number to every output line.  I don't want to
> get an instance of a logger object for every line to print much less
> configure a handler or assign a level.

Rolling file appenders, syslog integration, the ability to adjust
log level etc. are important in most big applications.

Arne


[toc] | [prev] | [next] | [standalone]


#31896

Frome.d.programmer@gmail.com
Date2015-06-30 12:14 -0700
Message-ID<16cd77ab-e259-40b5-8599-de59a7db5dbd@googlegroups.com>
In reply to#31894
> >>> On Monday, June 29, 2015 at 2:40:05 PM UTC-4, Russ P. wrote:
> >>>> So if I call printInformation with no arguments, the output
> >>>> goes to standard output, but if I give it a filename the output
> >>>> goes to the file. Is this the best way to do it, or is there a
> >>>> simpler/better way? I'd also like to be able to append the
> >>>> output to an existing file as well as create a new file.
> >>>> Thanks.
> >>>
> >>> I never quite got the logging frameworks ie commons logging.
> >>
> >> s/ie/eg/
> >>
> >>> You have to deal with someone else's API, [...]
> >>
> >> That's called "component reuse," and most people think of it as a
> >> Good Thing.  In moderation, of course.
> >>
> >>> [...] set warning levels, and include an extra jar in the
> >>> classpath. [...]
> >>
> >> There's also the built-in java.util.logging package, assuming
> >> you're using a post-2002 Java version.
> >
> > Most people seem to be using the Apache Commons Logging.  I'm not
> > sure why.
> 
> It allows the code to be used with a different actual logging framework
> with no code changes.
> 
> >     I just looked at java.util.logging.Logger and most of that
> > seems irrelevant when all you want to do is write messages to
> > System.out.
> 
> Usually people at some point end up needing to do something
> more advanced that just writing to System.out.
> 
> OP already reached that level.
> 
> >             In my static log class I just add the timestamp and
> > calling method and line number to every output line.  I don't want to
> > get an instance of a logger object for every line to print much less
> > configure a handler or assign a level.
> 
> Rolling file appenders, syslog integration, the ability to adjust
> log level etc. are important in most big applications.
> 
> Arne

OP mentioned wanting to do System.out.println().  java.util.logging.Logger is not static, so if you want to write a single statement to create a log message without creating a new instance of an object it makes sense to write your own.  If you write your own logging class it makes sense to have your own class to write text files.  If you want to get an instance every time, if you want a logging API to open a log file for you, if it can keep it open to append while you're running and close it automatically when you're done, it might make sense to use the API.

[toc] | [prev] | [next] | [standalone]


#32172

FromArne Vajhøj <arne@vajhoej.dk>
Date2015-07-27 22:25 -0400
Message-ID<mp6p6o$19j$3@speranza.aioe.org>
In reply to#31896
On 6/30/2015 3:14 PM, e.d.programmer@gmail.com wrote:
>>>>> On Monday, June 29, 2015 at 2:40:05 PM UTC-4, Russ P. wrote:
>>>>>> So if I call printInformation with no arguments, the
>>>>>> output goes to standard output, but if I give it a filename
>>>>>> the output goes to the file. Is this the best way to do it,
>>>>>> or is there a simpler/better way? I'd also like to be able
>>>>>> to append the output to an existing file as well as create
>>>>>> a new file. Thanks.

>>> I just looked at java.util.logging.Logger and most of that seems
>>> irrelevant when all you want to do is write messages to
>>> System.out.
>>
>> Usually people at some point end up needing to do something more
>> advanced that just writing to System.out.
>>
>> OP already reached that level.
>>
>>> In my static log class I just add the timestamp and calling
>>> method and line number to every output line.  I don't want to get
>>> an instance of a logger object for every line to print much less
>>> configure a handler or assign a level.
>>
>> Rolling file appenders, syslog integration, the ability to adjust
>> log level etc. are important in most big applications.
>
> OP mentioned wanting to do System.out.println().

OP also mentioned wanting to write to a file.

Arne

[toc] | [prev] | [next] | [standalone]


#31897

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2015-06-30 15:27 -0400
Message-ID<mmuqgk$214$1@dont-email.me>
In reply to#31893
On 6/30/2015 2:28 PM, e.d.programmer@gmail.com wrote:
>>> On Monday, June 29, 2015 at 2:40:05 PM UTC-4, Russ P. wrote:
>>>> Suppose I need a function (or method) for printing some (text-based) information to a file or to standard output. What is the recommended way to do this while minimizing duplication of code? Here's a simplification of what I came up with (in Scala, but using the Java standard library):
>>>>
>>>>       def printInformation(out: java.io.PrintStream = System.out) {
>>>>
>>>>           // print information here
>>>>           }
>>>>
>>>>       def printInformation(fileName: String) {
>>>>           printInformation(new java.io.PrintStream(fileName))
>>>>           }
>>>>
>>>> So if I call printInformation with no arguments, the output goes to standard output, but if I give it a filename the output goes to the file. Is this the best way to do it, or is there a simpler/better way? I'd also like to be able to append the output to an existing file as well as create a new file. Thanks.
>>>
>>> I never quite got the logging frameworks ie commons logging.
>>
>>       s/ie/eg/
>>
>>> You have to deal with someone else's API, [...]
>>
>>       That's called "component reuse," and most people think of it
>> as a Good Thing.  In moderation, of course.
>>
>>> [...] set warning levels, and include an extra jar in the classpath. [...]
>>
>>       There's also the built-in java.util.logging package, assuming you're
>> using a post-2002 Java version.
>>
>> --
>> esosman@comcast-dot-net.invalid
>> "Don't be afraid of work. Make work afraid of you." -- TLM
>
> Most people seem to be using the Apache Commons Logging.  I'm not sure why.
> I just looked at java.util.logging.Logger and most of that seems irrelevant when all you want to do is write messages to System.out.  In my static log class I just add the timestamp and calling method and line number to every output line.  I don't want to get an instance of a logger object for every line to print much less configure a handler or assign a level.

     If all you want to do is write to System.out, just do it -- don't
bother with any logging framework at all, either pre-packaged or
home-brewed.  Use a logging framework when you may want to change the
logging destination after the fact, even after deployment, and route it
to System.out/err, to a file, to a socket, to a remote log-monitoring
service, to multiple destinations simultaneously, ...

     Also, most people I've met have considered the level-sensitivity
of logging to be an advantage.  You can sprinkle the logging statements
throughout the code and turn them on and off (by level or by filter) at
run time, without recompiling or redeploying or whatever.  That way,
when trouble arises in the field you can crank up the logging level on
*exactly* the same code that's already installed.  Beats heck out of
"Hey, developer, can you send me a freshly-compiled version with a few
more println() calls in it?"

     Finally, there's no need to "get an instance of a Logger" for every
line of output.  For one thing, the Logger class caches the instances
and re-uses them.  If simply looking them up seems too expensive (as it
might well be for FINEST logging in a tight loop), just give yourself a
static field:

	public class Clown {
	    private static final Logger LOGGER =
	        Logger.getLogger(Clown.class.getName());
	    ...
	    LOGGER.info("Remember this moment, my son.");
	    ...
	}

Or you can create the Logger lazily:

	public class Clown {
	    private static Logger cachedLogger;
	    private static synchronized logger() {
	        if (cachedLogger == null) {
	            cachedLogger = Logger.getLogger(...);
	        }
	        return cachedLogger;
	    }
	    ...
	    logger().severe("That swan is black! Black, I say!");
	    ...
	}

     I haven't any personal experience with the Apache Commons logging
framework, and don't know why (or, truly, whether) people prefer it to
java.util.logging; perhaps it's better.  But even if Java's package is
less capable than log4j, it's certainly more capable and more versatile
than the home-brew implementation you've described, which makes me
wonder why you bothered.  Even if you like your own API better, I'd
suggest you re-implement it as a wrapper around one of these industrial-
strength frameworks to get the benefits of in-the-field adjustment.

-- 
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.programmer


csiph-web