Path: csiph.com!optima2.xanadu-bbs.net!xanadu-bbs.net!feeder.erje.net!1.eu.feeder.erje.net!newsfeed.fsmpi.rwth-aachen.de!newsfeed.straub-nv.de!eternal-september.org!feeder.eternal-september.org!mx02.eternal-september.org!.POSTED!not-for-mail From: Eric Sosman Newsgroups: comp.lang.java.programmer Subject: Re: basic output question Date: Mon, 29 Jun 2015 15:32:58 -0400 Organization: A noiseless patient Spider Lines: 57 Message-ID: References: <635be647-55fb-43f9-8609-0320306ca853@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 8bit Injection-Date: Mon, 29 Jun 2015 19:31:36 +0000 (UTC) Injection-Info: mx02.eternal-september.org; posting-host="858a9d65d95f4ea4d355bd116aa2cdbf"; logging-data="8224"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX189tN+MhMUqXJfaPrg1IPRj" User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.0.1 In-Reply-To: <635be647-55fb-43f9-8609-0320306ca853@googlegroups.com> Cancel-Lock: sha1:VSHLCoAE2/2FDKgowOF+KlkTerM= Xref: csiph.com comp.lang.java.programmer:31882 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