Reputation: 21
I have a simple question. My program asks the user to type a name, range, and length to generate random numbers. The result will be printed into a file from the console. I want to know is it possible to print to the console that the file has been printed when it's done.
Currently this is my set up to print to a file:
Scanner s = new Scanner(System.in);
System.out.println("-----------------------------------------------");
System.out.println("Choose a name to your file: ");
String fn = s.nextLine();
System.out.println("-----------------------------------------------");
System.out.println("Choose your range: ");
String rn = s.nextLine();
System.out.println("-----------------------------------------------");
System.out.println("Choose your length of array: ");
String ln = s.nextLine();
System.out.println("-----------------------------------------------");
int rangeToInt = Integer.parseInt(rn);
int lengthToInt = Integer.parseInt(ln);
File file = new File(fn +".txt");
PrintStream stream = new PrintStream(file);
//System.out.println("File Has been Printed");
System.setOut(stream);
int[] result = getRandomNumbersWithNoDuplicates(rangeToInt, lengthToInt);
for(int i = 0; i < result.length; i++) {
Arrays.sort(result);
System.out.println(result[i] + " ");
}
System.out.println("Current Time in Millieseconds = " + System.currentTimeMillis());
System.out.println("\nNumber of element in the array are: " + result.length + "\n");
}// end of main
```
Upvotes: 1
Views: 7035
Reputation: 338181
Answer by rzwitserloot is correct. For fun, let's rewrite the code in the Question using the benefits of modern Java. Our rewrite includes the new (preview) class java.io.IO
for console access that avoids the error found by rzwitserloot.
No need to use System.currentTimeMillis()
anymore. Supplanted by the java.time classes, specifically Instant.now()
which captures the current moment as seen in UTC.
In Java 8, this resolves to milliseconds, while in Java 9 and later this resolves to the finer level microseconds in many implementations.
Instant start = Instant.now() ;
Calculate elapsed time using Duration
.
Duration duration = Duration.between ( start , Instant.now() ) ;
java.io.IO
Using preview feature in Java 23 & 24, use new java.io.IO
class for easier console use. The IO
class has three simple methods: print
, println
, and readln
. See another Question, Newer easier ways to interact with the console in Java 23+?.
Note how we conveniently pass the user-prompt as an argument to IO.readln
to do double-duty: Print a prompt on the console, while also taking input from the user.
// Gather inputs.
String fileName = IO.readln ( "Choose a name to your file: " );
String rangeInput = IO.readln ( "Specify our range:" );
int range = Integer.parseInt ( rangeInput );
String arrayInput = IO.readln ( "Specify length of array:" );
int arrayLength = Integer.parseInt ( arrayInput );
// Dump to console
IO.println ( "fileName = " + fileName );
IO.println ( "range = " + range );
IO.println ( "arrayLength = " + arrayLength );
In real work, we would add more code for error-handling. Errors might include the user entering an empty string for file name, or entering characters other than digits for numeric inputs. But we omit that code to keep this demo simple and clear.
When run:
Choose a name to your file: Bogus
Specify our range:42
Specify length of array:7
fileName = Bogus
range = 42
arrayLength = 7
Stream
Write some logic to get your array of distinct values. Using the Stream
feature in Java 8+ makes this quite simple.
int[] ints =
ThreadLocalRandom
.current ( )
.ints ( 0 , range )
.distinct ( )
.limit ( arrayLength )
.toArray ( );
ints = [41, 19, 11, 40, 16, 34, 35]
Java 21 and later now benefits from sequenced collections, additional interfaces added to the Java Collections Framework. See talk by Stuart Marks. SequencedCollection
is a super-interface to List
and others.
Convert from our domain data, an array of int
primitives, to our data for serialization, a SequencedCollection
of String
objects.
SequencedCollection < String > lines =
Arrays
.stream ( ints )
.mapToObj ( Integer :: toString )
.toList ( );
Modern Java offers the NIO.2 features for easier file-handling.
We can easily write a collection of lines of text with a call to Files.write
.
Path path = Paths.get ( "/Users/basil_dot_work/" , fileName );
Path resultingPath;
try { resultingPath = Files.write ( path , lines , StandardCharsets.UTF_8 ); }
catch ( IOException e ) { throw new RuntimeException ( e ); }
You asked:
I want to know is it possible to print to the console that the file has been printed when it's done.
In the code above, a Path
object is returned by our call to Files.write
if we have success. If a file system problem occurs, an exception is thrown. We can print the returned Path
object to the console with another IO.println
.
For your copy-paste convenience, here is the entire app.
package work.basil.example.console;
import java.io.IO;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import java.time.Instant;
import java.util.Arrays;
import java.util.SequencedCollection;
import java.util.concurrent.ThreadLocalRandom;
public class MakeFile
{
public static void main ( String[] args )
{
// Gather inputs.
String fileName = IO.readln ( "Choose a name to your file: " );
String rangeInput = IO.readln ( "Specify our range:" );
int range = Integer.parseInt ( rangeInput );
String arrayInput = IO.readln ( "Specify length of array:" );
int arrayLength = Integer.parseInt ( arrayInput );
// Start the stopwatch.
Instant start = Instant.now ( );
// Domain data.
int[] ints =
ThreadLocalRandom
.current ( )
.ints ( 0 , range )
.distinct ( )
.limit ( arrayLength )
.toArray ( );
// Serialized data.
SequencedCollection < String > lines =
Arrays
.stream ( ints )
.mapToObj ( Integer :: toString )
.toList ( );
// Write file
Path path = Paths.get ( "/Users/basil_dot_work/" , fileName );
Path resultingPath;
try { resultingPath = Files.write ( path , lines , StandardCharsets.UTF_8 ); }
catch ( IOException e ) { throw new RuntimeException ( e ); }
// Dump to console
IO.println ( "fileName = " + fileName );
IO.println ( "range = " + range );
IO.println ( "arrayLength = " + arrayLength );
IO.println ( "ints = " + Arrays.toString ( ints ) );
IO.println ( "lines.toString(): " + lines );
IO.println ( "path: " + path );
IO.println ( "resultingPath = " + resultingPath );
IO.println ( "Elapsed: " + Duration.between ( start , Instant.now ( ) ) );
}
}
When run on Java 23.0.1 from IntelliJ IDEA 2024.3 Beta (Ultimate Edition) on a MacBook Pro with M1 Pro Apple Silicon on macOS Sonoma 14.7.1.
Choose a name to your file: Bogus
Specify our range:42
Specify length of array:7
fileName = Bogus
range = 42
arrayLength = 7
ints = [40, 37, 8, 4, 18, 41, 24]
lines.toString(): [40, 37, 8, 4, 18, 41, 24]
path: /Users/basil_dot_work/Bogus
resultingPath = /Users/basil_dot_work/Bogus
Elapsed: PT0.002611S
Upvotes: 2
Reputation: 102804
Don't call System.setOut
. When you do that, you can no longer print to the console. Instead of System.out.println
to write to the file, just... stream.println
to write to the file. Then you can use System.out
to print to the console.
Upvotes: 3