I'm having some trouble reading in a file from the command line.
I've never used command line arguments before so I guess I'm a little lost.
Here's what I'm trying so far:
FileInputStream fin1 = null;
for (int i = 0; i < args.length; i++) //command line argument for file input
{
fin1 = new FileInputStream(args[i]);
}
//Scanner scan = new Scanner(fiin1);
I've commented out my scanner because I'm using a different method (into which I'm passing in fin1 as a parameter) and that method has a scanner in it. However, I'm not too sure if I still need the scanner there (maybe to pass into the other method as a param).
Anyway, if I run my code, I get a NullPointerException, which I assume comes from the fact that I initialized my FileInputStream as null. But if I'm changing it in the for loop, why does that matter?
Also, I need to keep my main method the way it is so I can do more in it.
Can anyone help?
Notice that it is called FileInputStream , and so we need to be using a File .
You can simply use a Scanner , and set it to System.in :
Scanner scanner = new Scanner(System.in);
And then afterwards, you can initialize that FileInputStream
How to Read Strings from Scanner in console Application JAVA?
Use following code.
if (args.length < 1) {
System.out.println("No file was given as an argument..!");
System.exit(1);
}
String fileName = args[0];
Scanner scanner = new Scanner(new File(fileName));
if you want to use a FileInputStream then change the last line to create a FileInputStream instance.
fin1 = new FileInputStream(fileName);
No need to use a for-loop if you are giving only one filename as the argument. You can run your code as follow.
javac MyClass.java //Compile your code(Assumed that your file is MyClass.java
java MyClass filename //Change filename with the path to your file
You are getting NullPointerException probably because you are not using filename as a argument when you run your java code.
First of all : when you run your code, you'll reach only the last argument.
You should do like this:
FileInputStream fileInputStream = null;
for (String argument : args) {
fileInputStream = new FileInputStream(argument);
//you should process your argument in block together with creating fis
Scanner scanner = new Scanner(fileInputStream);
//now, when a scanner copy is created, you can use it (or you can use your own
while (scanner.hasNext()) {
System.out.println(scanner.nextLine());
}
}
Related
So I am making a program that renders pictures from .ppm files. I have got another version working but have now moved on to the other part which is reading multiple images from the same document and to basically use this to animate it with a small delay inbetween switching pictures, and then the following error has come up and am completely stumped by it:
java.io.ioexception is never thrown in body of corresponding try statement
Any help would be much appreciated.
public void renderAnimatedImage(){
String image = UI.askString("Filename: ");
int keepingCount =0; //Variables
int numCount = 1;
try{
Scanner fileScan = new Scanner(image); // making scanners
Scanner scan = new Scanner(image);
File myFile = new File(image); //making files
File myFile2 = new File(image);
int num = 0;
while(scan.hasNextLine()){
String Line = scan.nextLine();
Scanner keywordSc = new Scanner (Line);
while(keywordSc.hasNext()) {
String Keyword = keywordSc.next();
if (Keyword.equals("P3")) {
num++;
}
else { break; }
}
}
while (keepingCount< numCount) {
this.renderImageHelper(scan); // calling upon an earlier method which works.
keepingCount++;
}
}
catch(IOException e) {UI.printf("File failure %s \n", e); }
}
It means the code you're writing inside your try/catch is never throwing an IOException, which makes the clause unnecessary. You can just remove it and keep your code without it.
I bet that you think there could be an IOException because of this line:
Scanner fileScan = new Scanner(image); // making scanners
But that line is not doing what you think it does. Since image is a String this will use the Scanner(String) constructor. But that constructor treats its argument as a string to be scanned, not the name of a file to be scanned.
Hence new Scanner(image) is not doing any I/O and is not declared as throwing an IOException.
And the rest of the code in the block won't throw IOException either. The Scanner next / hasNext methods that you are using will throw a different exception if there is an I/O error while reading. (Check the javadocs.)
Also, you seem to be misunderstanding what File is / does.
File myFile = new File(image); //making files
The comment is incorrect. That does not make a file.
Actually, it makes a File object which is an in-memory representation of a filename / pathname. Creating a File object doesn't cause a file to be created in the file system. (Again, check the javadocs.)
I'm trying to figure out how to pass two files (input.txt and output.txt) as arguments to my main method, read the input file, pass it to a recursive method, then write the mutated string to an output file. I've never worked with commandline arguments before, so I'm not sure how to go about making it work. Here's the code so far:
public static void main(String[] args)
{
ArrayList<String> fileInput = new ArrayList<String>();//ArrayList to hold data from input file
File file = new File(args[0]);
try
{
Scanner scan = new Scanner(new File(args[0]));
FileInputStream readFile = new FileInputStream("input.txt"); // readFile passed from args[0]; args[0] is the argument passed as a string that is held at the 0 index of the args array
fileInput.add(file); //red error line under Add
}
catch(IOException e)
{
e.printStackTrace();
System.exit(0);
}
ArrayList<String> strArray = new ArrayList<String>();
String s;
for(int i = 0; i < file.length() ; i++) //int i = 0; length of stored string data object; i++)
{
//recursiveMarkUp is a string type
strArray.add(file.recursiveMarkUp());//call the markup method and save to an array so we can print to the output file later
//line to print output to output.txt
}
}
When you pass in arguments, they are stored in the args[] array and are accessed like any normal array within main.
File input = new File(args[0]);
File output = new File(args[1]); // make sure you check array bounds
Your comment pointing out the red error line occurs because you are trying to add a File object to an ArrayList<String> which are incompatible. However there's no need to do this step anyway.
You can construct the output stream with the file above:
output.createNewFile(); // create the file so that it exists before writing output
FileOutputStream outStream = new FileOutputStream(output);
OutputStreamWriter outWriter = new OutputStreamWriter(outStream);
If you're using Java 8+, using Files.lines() you can process every line of the file as a stream of Strings
Files.lines(input.toPath())
.map(line -> recursiveMarkup(line))
.forEach(markedUp -> outWriter.write(markedUp));
To do this without streams:
BufferedReader reader = new BufferedReader(new FileReader(input));
String line = "";
while(line != null) {
line = recursiveMarkup(reader.readLine());
outWriter.write(line);
}
I've excluded try/catch blocks for brevity. I've also assumed that you do actually want to process the input file one line at a time; if that's not the case, adjust as necessary. You should also consider explicitly defining file encodings (UTF-8, etc.) when reading/writing data, though here I've also left it out for brevity.
I am trying to complete a simple program that uses the command line to replace a specified String in a file. Command line entry would be java ReplaceText textToReplace filename
The code completes, but the file does not replace the specified string. I have Googled similar situations but I cannot figure out why my code is not working.
import java.io.*;
import java.util.*;
public class ReplaceText{
public static void main(String[] args)throws IOException{
if(args.length != 2){
System.out.println("Incorrect format. Use java ClassName textToReplace filename");
System.exit(1);
}
File source = new File(args[1]);
if(!source.exists()){
System.out.println("Source file " + args[1] + " does not exist.");
System.exit(2);
}
File temp = new File("temp.txt");
try(
Scanner input = new Scanner(source);
PrintWriter output = new PrintWriter(temp);
){
while(input.hasNext()){
String s1 = input.nextLine();
String s2 = s1.replace(args[0], "a");
output.println(s2);
}
temp.renameTo(source);
source.delete();
}
}
}
Edit: edited the code so I am not reading and writing to the file at the same time, but it still does not work.
First of all you have a problem with your logic. You are renaming your temporary file then immediately deleting it. Delete the old one first, then rename the temporary file.
Another problem is that you are attempting to do perform the delete and rename within your try block:
try(
Scanner input = new Scanner(source);
PrintWriter output = new PrintWriter(temp);
){
...
temp.renameTo(source);
source.delete();
}
Your streams are not automatically closed until the try block ends. You will not be able to rename or delete while the stream is open. Both delete and renameTo return a boolean to indicate whether they were successful so it may be prudent to check those values.
Correct code may look something like:
try(
Scanner input = new Scanner(source);
PrintWriter output = new PrintWriter(temp);
){
while(...)
{
...
}
}
// Try block finished, resources now auto-closed
if (!source.delete())
{
throw new RuntimeException("Couldn't delete file!");
}
if (!temp.renameTo(source))
{
throw new RuntimeException("Couldn't rename file!");
}
You can't replace strings a file in general. You need to read the input line by line, replace each line as necessary, and write each line to a new file. Then delete the old file and rename the new one.
Is there a way for me to be able to use the same scanner for both a System.in Input and for a FileInputStream Input?
Here is how I have initialized the scanner in my main class:
public class Nimsys {
public static Scanner keyboardIn;
static {
keyboardIn = new Scanner(System.in);
} ...
In the main class Nimsys here is how I get input:
String inputString1 = keyboardIn.nextLine();
In another class here is how I use the scanner from Nimsys:
int inputInt1 = Nimsys.keyboardIn.nextInt();
But now in my main class Nimsys I am trying to scan in a whole file - so far I have used another scanner, as you can see in the code below. However, is it possible to have it all done by the original scanner?
try
{
inputStream = new Scanner(new FileInputStream("file.txt"));
}
catch (FileNotFoundException e)
{
System.out.println("File morestuff.txt was not found");
}
String[] reopenPlayers = new String[100];
int i = 0;
while(inputStream.hasNextLine()){
reopenPlayers[i]=inputStream.nextLine();
System.out.println(reopenPlayers[i]);
}
Thanks a lot!
Tom
If I understand your question (not that I think a global variable is a great solution), you could change (and perhaps rename)
keyboardIn = new Scanner(System.in);
to something like
try {
keyboardIn = new Scanner(new FileInputStream("file.txt"));
} catch (FileNotFoundException e) {
System.out.println("file \"file.txt\" not found");
e.printStackTrace();
}
and then remove the try-catch from
inputStream = new Scanner(new FileInputStream("file.txt"));
and modify it to something like
inputStream = Nimsys.keyboardIn;
(or replace inputStream with Nimsys.keyboardIn and not to be prescriptive but perhaps rename Nimsys.keyboardIn to Nimsys.in). Hopefully you're using an IDE that supports refactoring.
No you cannot do that, Scanner is just a wrapper class, which means the actual stream sources you are using are FileInputStream and system.in, obviously you cannot do this, and there is not much benefit if you can do this.
I would recommend against you trying to use the same scanner for multiple sources. From what I can tell from the code you've described, you wouldn't gain anything by it. In general, one Scanner should represent a single source of data.
However, if you're dead-set on the idea, you can write your own implementation of InputStream which combines the input from System.in and your FileInputStream. For ideas on how to do this, see this related question. Then construct the scanner with an instance of your two-source InputStream.
This brings up a host of other questions though- how exactly do you intend to properly combine the input from the two sources? The file contents will be available as soon as the file has been opened. The input from System.in will be available as the user types it. How should your combined Scanner choose what to output and when? These are questions you would have to answer if you choose to write your own InputStream to wrap the two sources.
I had a quick questions about prompting and accepting a file name, then making the file-text a scanner object.
I want the program to prompt the user to enter the name of a file, until he gets one which exists, then for the file-text to be used as a scanner object.
This is the code I have so far, it works to the point where I exit the while {} loop, but then when I try and process the scanner item like while (input.hasNextLine()) { it gives me an error saying it can't find the scanner item.
It's probably a silly mistake, but I just cannot seem to get it.
The whole code is below:
import java.io.*;
import java.util.*;
public class PersonalityTest {
public static void main(String[] args) throws FileNotFoundException {
boolean isFile = false;
Scanner sc = new Scanner(System.in);
System.out.print("Input file name? ");
String fileName = sc.next();
File inputFile = new File(fileName);
while (isFile == false) {
if (inputFile.exists()) {
Scanner input = new Scanner(inputFile);
isFile = true;
}
}
while(input.hasNextLine()) {
}
}
The scope of the input variable is local to the while (isFile == false) block. Declare it outside otherwise it won't be visible.
For the first part "I want the program to prompt the user to enter the name of a file, until he gets one which exists": Move this code:
Scanner sc = new Scanner(System.in);
System.out.print("Input file name? ");
String fileName = sc.next();
File inputFile = new File(fileName);
into a method and call it inside the while (isFile == false) block before the exists check (the method should return with the file or make the variable visible in the block by some other means).
You can't access input outside the if statement, sice the compiler is not sure, it will pass the test, you can do this:
Scanner sc = new Scanner(System.in);
Scanner input = null;
boolean isFile = false;
while (isFile == false){
System.out.print("Input file name? ");
String fileName = sc.next();
File inputFile = new File(fileName);
if (inputFile.exists()){
input = new Scanner(inputFile);
isFile = true;
}
}
But will throw a NullPointerException if it is null.
I changed the code a little bit, that way, it will not exceed if the file doesn't exist.
The Scanner input is local to your if statement. Your while (input.hasNextLine()) { statement will not work because of that. The Java compiler will treat input as a separate Scanner object and that is where the problems crop up, because to the Java compiler, the input that you are trying to use does not exist.
I would follow MouseEvent's suggested code as it does not run into the problem mentioned above.
The other answers have addressed your immediate question, but I want to point out a couple of other problems with your code:
The way that you are checking to see if the file can be opened is flawed. A better way to write the code is to attempt to open the file ... and retry when there is an exception. For example:
Scanner input = null;
do {
System.out.print("Input file name? ");
String fileName = sc.next();
File inputFile = new File(fileName);
try {
input = new Scanner(inputFile);
} catch (IOException ex) {
System.out.println("Cannot open: " + ex.getMessage());
}
} while (input == null);
Why is this better than calling File.exists()?
There are lots of reasons why you might be able to open a file. It might not exist at all. It might be a directory or a special file that can't be opened as a file. The application might not have permission. The file might be on a remote mounted file system and the remote mount might have just died.
There is a small time gap between the File.exists() call (and any others that you might make) and actually opening the file. In that time gap, it is possible that something to your program could do something to make the file unopenable; e.g. it could change its permissions or delete it.
The second problem is that your code potentially leaks a file descriptor because the scanner is not closed. In your specific application (as written) this doesn't matter because you are going to exit the application immediately after using the scanner. But if your weren't ... and this code was called lots of times ... you could find that you are unable to open files after a bit.
The correct way to deal with this would be to write your code something like this:
public static void main(String[] args) {
try (Scanner input = openInput()) {
while (input.hasNextLine()) {
// do stuff
}
}
}
This uses Java 7's new "try with resource" syntax, that ensures that the resource is closed when the try statement completes. (You can do the same thing in pre-Java 7 using a try / finally, but the code is a bit more cumbersome.)