Opening Files and Performing File Input [Java] - java

Goal of this assignment is to create a while loop that goes through file "flowers.dat" (I'll paste it later in this post) until the EoF is reached, then it should print a flowers name and if it'll grow in the shade or sun. Here's what I've got so far:
import java.io.*; // Import class for file input.
public class Flowers
{
public static void main(String args[]) throws Exception
{
// Declare variables here
String flowerName;
String sunOrShade;
File flower = new File("flowers.dat");
// Open input file.
// Create BufferedReader object.
BufferedReader reader;
// Write while loop that reads records from file.
while ((flowerName = reader.readLine()) != null) {
System.out.println(flowerName + "is grown in the " + sunOrShade);
}
// Print flower name and the words sun or shade.
flower.close();
System.exit(0);
} // End of main() method.
}
Here is the "flowers.dat". Here I noted that the Flower and sun/shade alternate, so it makes me think that I need to include a for loop in the while loop that alternates between each line, assigns one line to flowerName and the other to sunOrShade, then prints the line and it again until it reaches null.
Astilbe
Shade
Marigold
Sun
Begonia
Sun
Primrose
Shade
Cosmos
Sun
Dahlia
Sun
Geranium
Sun
Foxglove
Shade
Trillium
Shade
Pansy
Sun
Petunia
Sun
Daisy
Sun
Aster
Sun
Also, I'm getting this error message. I'm not sure why it doesn't close the .dat file
Flowers.java30: error : cannot find symbol
flower.close();
^
symbol: method close()
location: variable flower of type File
Error: could not find or load main class Flowers

The class File is just for the classpath, it is not about opening any stream. Not valid to call method close on the flower instance which is a File object.

flower is declared as a File object and there is no close() method for this object. You need to initialize your BufferedReader (reader)
BufferedReader reader = new BufferedReader(new FileReader(flower));
and close that since that is what will be accessing the file and reading it. It should be reader.close(). That should solve the particular error you mentioned. But take it a littler further so that you don't need close the reader and allow it to close itself when things are done or an Exception occurs by using Try With Resources when setting up the reader:
File flower = new File("flowers.dat");
try (BufferedReader reader = new BufferedReader(new FileReader(flower))) {
// Write while loop that reads records from file.
while ((flowerName = reader.readLine()) != null) {
//read in the next line to get the required lighting.
sunOrShade = reader.readLine();
System.out.println(flowerName + " is grown in the " + sunOrShade);
}
}
catch (FileNotFoundException ex) {
ex.printStackTrace();
}
catch (IOException ex) {
ex.printStackTrace();
}
And you don't need System.exit(0); to end the application. It will end when the main() method is finished.

Related

Need to break my main method into smaller methods

I have written the following code for a lab assignment, however, my professor wants me to break my main method down into other methods and call those methods in the main method. I tried creating methods for creating the input and output streams, and I tried to create a method for the actual writing of the reverse file but I am getting no where. Can someone point me in the right direction? do I need to create another class that I will instantiate and call these methods on? I'm new to java, so any help is appreciated!
import java.io.*;
import java.util.ArrayList;
import java.util.Scanner;
/**
* Reads lines of text from a file named testclass.txt and writes them to a file
* named output.txt in reverse order.
*/
public class ReverseFile {
public static void main(String[] args) {
Scanner fileRead; // input stream for reading text file.
PrintWriter fileWrite; // output stream for writing text file.
ArrayList<String> fileLines; // An ArrayList for holding the lines of the text file.
fileLines = new ArrayList<String>();
try { // Create the input stream.
fileRead = new Scanner(new File("testclass.txt"));
}
catch (FileNotFoundException e) {
System.out.println("Can't find text file");
return; // End the program by returning from main().
}
try { // Create the output stream.
fileWrite = new PrintWriter(new FileWriter("output.txt"));
}
catch (IOException e) {
System.out.println("Can't open file output.txt");
System.out.println("Error: " + e);
fileRead.close(); // Close the input file.
return; // End the program.
}
while ( fileRead.hasNextLine() ) { // Read until end-of-file.
String textLine = fileRead.nextLine();
System.out.println(textLine);
fileLines.add(textLine);
}
// Output the text in reverse order.
for (int i = fileLines.size()-1; i >= 0; i--)
fileWrite.println(fileLines.get(i));
//System.out.println(reverseLines);
System.out.println("Done, check output.txt");
fileRead.close();
fileWrite.close();
} // end of main()
}
Ideally each method should do one thing only and have a name that makes it clear what that one thing is.
My suggestion is that your main method should look something like:
public static void main(String[] args) {
List<String> lines = createAndReadInputStream();
reverse(lines);
createAndWriteOutputStream(lines);
}
That makes it perfectly clear to the reader exactly what the method does and all implementation details are in other methods.
Then do the same for the next method:
private List<String> createAndReadInputStream() {
Scanner inputScanner = createInputStream();
return scanToLines(inputScanner);
}
And so on. If correctly structured your class variables all become locally scoped variables and your code is straightforward and easy to read. You'll also find you need far fewer comments to explain what's happening: the names of the methods are generally enough on their own.
If you are interested in learning more about why your professor asked for this, and how to go about doing it, I highly recommend the book "Clean Code" by Robert Martin. The software development team of which I am a part (80 people in 11 agile teams) adopted it several years ago and the quality, readability and maintainability of our code has improved out of sight. While it takes some getting used to it's worth the effort. In my view the old adage that more code means more bugs is just completely false - as long as the extra code is there for readability, testability, maintainability then it means fewer bugs not more.
Here is an example. Move this section of code:
try { // Create the input stream.
fileRead = new Scanner(new File("testclass.txt"));
}
catch (FileNotFoundException e) {
System.out.println("Can't find text file");
return; // End the program by returning from main().
}
into a new private method called createInputStream within the ReverseFile class. Call the new member from the point in the code where you removed the section. Don't forget to return "fileRead" from the method.
What about this:
import java.io.*;
import java.util.ArrayList;
import java.util.Scanner;
/** * Reads lines of text from a file named testclass.txt and writes them to a file * named output.txt in reverse order. */
public class ReverseFile {
public static ArrayList<String> readFile(String fileName) {
Scanner fileRead; // Scanner for reading text file.
// Try to open file for reading
try {
fileRead = new Scanner(new File(fileName));
// On failure -> print message & return null
} catch (FileNotFoundException e) {
System.out.println("Can't find text file");
return null;
}
// Create ArrayList for readed lines
ArrayList<String> fileLines = new ArrayList<String>();
// Read file line-by-line until end-of-file.
while ( fileRead.hasNextLine() ) {
String textLine = fileRead.nextLine(); // Read next line
System.out.println(textLine); // Print line to terminal
fileLines.add(textLine); // Add line to ArrayList
}
// Close scanner -> will close allso opened file
fileRead.close();
// Return loaded lines
return fileLines;
}
public static void createReversedFile(String filename, ArrayList<String> fileLines) {
PrintWriter fileWrite; // PrintWriter for writing text file.
// Try to open file for writing
try {
fileWrite = new PrintWriter(new FileWriter(filename));
// On failure -> print message & return
} catch (IOException e) {
System.out.println("Can't open file output.txt");
System.out.println("Error: " + e);
fileRead.close(); // Close the input file.
return;
}
// Output the text in reverse order
for (int i = fileLines.size()-1; i >= 0; i--) {
fileWrite.println(fileLines.get(i));
//System.out.println(reverseLines);
}
System.out.println("Done, check " + filename);
// Close PrintWriter -> will close allso opened file
fileWrite.close();
}
public static void main(String[] args) {
// Read file & store it's lines into ArrayList
ArrayList<String> fileLines = readFile("testclass.txt");
// If file was not loaded due to FileNotFoundException exception -> exit
if (fileLines == null) {
return;
}
// Create reversed output.txt file
createReversedFile("output.txt", fileLines);
}
}

Text IO Stream Number Format Exception

I've been programming Monopoly on java and I've been running into a NumberFormatException when I pull the rent values from a .txt file.
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
Here's the code:
try{
//Searching for .txt file
fileName = "N://java/Monopoly/src/rent.txt";
//creating FileReader and BuffReader objects
FileReader input = new FileReader(fileName);
BufferedReader bufRead = new BufferedReader(input);
//reading first line
String line = bufRead.readLine();
while(line!=""){
//not sure why, but program doesn't run well without if statement
if(line!=""){
//creating array of in variable
splitArr = line.split(",");
//creating rent object
rent r = new rent(Integer.parseInt(splitArr[0]),Integer.parseInt(splitArr[1]),Integer.parseInt(splitArr[2]),Integer.parseInt(splitArr[3]),Integer.parseInt(splitArr[4]),Integer.parseInt(splitArr[5]));
//storing rent object to a public static Arraylist holding all rents for the game
rents.add(r);
//debugging code that has been commented out
//System.out.println(r.toString());
}
//debugging code that has been commented out
/*for(String s : splitArr){
System.out.print(s+", ");
}*/
//reading next line
line = bufRead.readLine();
}
//closing IO stream
bufRead.close();
//preventing out of bounds exception error
}catch (ArrayIndexOutOfBoundsException e){
System.out.println("Usage: java ReadFile filename: rent\n");
//preventing IOException error
}catch (IOException e){
e.printStackTrace();
//I can't quite remember I have this in there. I know it didn't work right without it at some point
}catch(NullPointerException e){
}
When I uncomment the enhanced for loop at line 16, I get some values followed by the error and then all of the rest of the values as if there was no problem. I have noticed that when I delete and re-enter the values where the error begins, the error moves to other places. I've checked the arguments in the rent class (it requires 6 int's) and have checked the .txt file where all the values are good.
How do I fix this or should I not worry about it and add another catch statement to ignore the error?
You're comparing strings with !=. You should use !line.equals(""). – Saviour Self

Java -- Need help to enhance the code

I wrote a simple program to read the content from text/log file to html with conditional formatting.
Below is my code.
import java.io.*;
import java.util.*;
class TextToHtmlConversion {
public void readFile(String[] args) {
for (String textfile : args) {
try{
//command line parameter
BufferedReader br = new BufferedReader(new FileReader(textfile));
String strLine;
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
Date d = new Date();
String dateWithoutTime = d.toString().substring(0, 10);
String outputfile = new String("Test Report"+dateWithoutTime+".html");
FileWriter filestream = new FileWriter(outputfile,true);
BufferedWriter out = new BufferedWriter(filestream);
out.write("<html>");
out.write("<body>");
out.write("<table width='500'>");
out.write("<tr>");
out.write("<td width='50%'>");
if(strLine.startsWith(" CustomerName is ")){
//System.out.println("value of String split Client is :"+strLine.substring(16));
out.write(strLine.substring(16));
}
out.write("</td>");
out.write("<td width='50%'>");
if(strLine.startsWith(" Logged in users are ")){
if(!strLine.substring(21).isEmpty()){
out.write("<textarea name='myTextBox' cols='5' rows='1' style='background-color:Red'>");
out.write("</textarea>");
}else{
System.out.println("else if block:");
out.write("<textarea name='myTextBox' cols='5' rows='1' style='background-color:Green'>");
out.write("</textarea>");
} //closing else block
//out.write("<br>");
out.write("</td>");
}
out.write("</td>");
out.write("</tr>");
out.write("</table>");
out.write("</body>");
out.write("</html>");
out.close();
}
//Close the input stream
in.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
}
public static void main(String args[]) {
TextToHtmlConversion myReader = new TextToHtmlConversion();
String fileArray[] = {"D:/JavaTesting/test.log"};
myReader.readFile(fileArray);
}
}
I was thinking to enhance my program and the confusion is of either i should use Maps or properties file to store search string. I was looking out for a approach to avoid using substring method (using index of a line). Any suggestions are truly appreciated.
From top to bottom:
Don't use wildcard imports.
Don't use the default package
restructure your readFile method in more smaller methods
Use the new Java 7 file API to read files
Try to use a try-block with a resource (your file)
I wouldn't write continuously to a file, write it in the end
Don't catch general Exception
Use a final block to close resources (or the try block mentioned before)
And in general: Don't create HTML by appending strings, this is a bad pattern for its own. But well, it seems that what you want to do.
Edit
Oh one more: Your text file contains some data right? If your data represents some entities (or objects) it would be good to create a POJO for this. I think your text file contains users (right?). Then create a class called Users and parse the text file to get a list of all users in it. Something like:
List<User> users = User.parse("your-file.txt");
Afterwards you have a nice user object and all your ugly parsing is in one central point.

Parse a text file into multiple text file

I want to get multiple file by parsing a input file Through Java.
The Input file contains many fasta format of thousands of protein sequence and I want to generate raw format(i.e., without any comma semicolon and without any extra symbol like ">", "[", "]" etc) of each protein sequence.
A fasta sequence starts form ">" symbol followed by description of protein and then sequence of protein.
For example ► >lcl|NC_000001.10_cdsid_XP_003403591.1 [gene=LOC100652771]
[protein=hypothetical protein LOC100652771] [protein_id=XP_003403591.1] [location=join(12190..12227,12595..12721,13403..13639)]
MSESINFSHNLGQLLSPPRCVVMPGMPFPSIRSPELQKTTADLDHTLVSVPSVAESLHHPEITFLTAFCL
PSFTRSRPLPDRQLHHCLALCPSFALPAGDGVCHGPGLQGSCYKGETQESVESRVLPGPRHRH
Like above formate the input file contains 1000s of protein sequence. I have to generate thousands of raw file containing only individual protein sequence without any special symbol or gaps.
I have developed the code for it in Java but out put is : Cannot open a file followed by cannot find file.
Please help me to solve my problem.
Regards
Vijay Kumar Garg
Varanasi
Bharat (India)
The code is
/*Java code to convert FASTA format to a raw format*/
import java.io.*;
import java.util.*;
import java.util.regex.*;
import java.io.FileInputStream;
// java package for using regular expression
public class Arrayren
{
public static void main(String args[]) throws IOException
{
String a[]=new String[1000];
String b[][] =new String[1000][1000];
/*open the id file*/
try
{
File f = new File ("input.txt");
//opening the text document containing genbank ids
FileInputStream fis = new FileInputStream("input.txt");
//Reading the file contents through inputstream
BufferedInputStream bis = new BufferedInputStream(fis);
// Writing the contents to a buffered stream
DataInputStream dis = new DataInputStream(bis);
//Method for reading Java Standard data types
String inputline;
String line;
String separator = System.getProperty("line.separator");
// reads a line till next line operator is found
int i=0;
while ((inputline=dis.readLine()) != null)
{
i++;
a[i]=inputline;
a[i]=a[i].replaceAll(separator,"");
//replaces unwanted patterns like /n with space
a[i]=a[i].trim();
// trims out if any space is available
a[i]=a[i]+".txt";
//takes the file name into an array
try
// to handle run time error
/*take the sequence in to an array*/
{
BufferedReader in = new BufferedReader (new FileReader(a[i]));
String inline = null;
int j=0;
while((inline=in.readLine()) != null)
{
j++;
b[i][j]=inline;
Pattern q=Pattern.compile(">");
//Compiling the regular expression
Matcher n=q.matcher(inline);
//creates the matcher for the above pattern
if(n.find())
{
/*appending the comment line*/
b[i][j]=b[i][j].replaceAll(">gi","");
//identify the pattern and replace it with a space
b[i][j]=b[i][j].replaceAll("[a-zA-Z]","");
b[i][j]=b[i][j].replaceAll("|","");
b[i][j]=b[i][j].replaceAll("\\d{1,15}","");
b[i][j]=b[i][j].replaceAll(".","");
b[i][j]=b[i][j].replaceAll("_","");
b[i][j]=b[i][j].replaceAll("\\(","");
b[i][j]=b[i][j].replaceAll("\\)","");
}
/*printing the sequence in to a text file*/
b[i][j]=b[i][j].replaceAll(separator,"");
b[i][j]=b[i][j].trim();
// trims out if any space is available
File create = new File(inputline+"R.txt");
try
{
if(!create.exists())
{
create.createNewFile();
// creates a new file
}
else
{
System.out.println("file already exists");
}
}
catch(IOException e)
// to catch the exception and print the error if cannot open a file
{
System.err.println("cannot create a file");
}
BufferedWriter outt = new BufferedWriter(new FileWriter(inputline+"R.txt", true));
outt.write(b[i][j]);
// printing the contents to a text file
outt.close();
// closing the text file
System.out.println(b[i][j]);
}
}
catch(Exception e)
{
System.out.println("cannot open a file");
}
}
}
catch(Exception ex)
// catch the exception and prints the error if cannot find file
{
System.out.println("cannot find file ");
}
}
}
If you provide me correct it will be much easier to understand.
This code will not win prices, due to missing java expertice. For instance I would expect OutOfMemory even if it is correct.
Best would be a rewrite. Nevertheless we all began small.
Give full path to file. Also on the output the directory is probably missing from the file.
Better use BufferedReader etc. i.o. DateInputStream.
Initialize i with -1. Better use for (int i = 0; i < a.length; ++i).
Best compile the Pattern outside the loop. But remove the Matcher. You can do if (s.contains(">") as well.
. One does not need to create a new file.
Code:
const String encoding = "Windows-1252"; // Or "UTF-8" or leave away.
File f = new File("C:/input.txt");
BufferedReader dis = new BufferedReader(new InputStreamReader(
new FileInputStream(f), encoding));
...
int i= -1; // So i++ starts with 0.
while ((inputline=dis.readLine()) != null)
{
i++;
a[i]=inputline.trim();
//replaces unwanted patterns like /n with space
// Not needed a[i]=a[i].replaceAll(separator,"");
Your code contains the following two catch blocks:
catch(Exception e)
{
System.out.println("cannot open a file");
}
catch(Exception ex)
// catch the exception and prints the error if cannot find file
{
System.out.println("cannot find file ");
}
Both of these swallow the exception and print a generic "it didn't work" message, which tells you that the catch block was entered, but nothing more than that.
Exceptions often contain useful information that would help you track down where the real problem is. By ignoring them, you're making it much harder to diagnose your problem. Worse still, you're catching Exception, which is the superclass of a lot of exceptions, so these catch blocks are catching lots of different types of exceptions and ignoring them all.
The simplest way to get information out of an exception is to call its printStackTrace() method, which prints the exception type, exception message and stack trace. Add a call to this within both of these catch blocks, and that will help you see more clearly what exception is being thrown and from where.

Passing a file as a command line argument and reading its lines

this is the code that i have found in the internet for reading the lines of a file and also I use eclipse and I passed the name of files as SanShin.txt in its argument field. but it will print :
Error: textfile.txt (The system cannot find the file specified)
Code:
public class Zip {
public static void main(String[] args){
try{
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream("textfile.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
// Print the content on the console
System.out.println (strLine);
}
//Close the input stream
in.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
}
}
please help me why it prints this error.
thanks
...
// command line parameter
if(argv.length != 1) {
System.err.println("Invalid command line, exactly one argument required");
System.exit(1);
}
try {
FileInputStream fstream = new FileInputStream(argv[0]);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Get the object of DataInputStream
...
> java -cp ... Zip \path\to\test.file
When you just specify "textfile.txt" the operating system will look in the program's working directory for that file.
You can specify the absolute path to the file with something like new FileInputStream("C:\\full\\path\\to\\file.txt")
Also if you want to know the directory your program is running in, try this:
System.out.println(new File(".").getAbsolutePath())
Your new FileInputStream("textfile.txt") is correct. If it's throwing that exception, there is no textfile.txt in the current directory when you run the program. Are you sure the file's name isn't actually testfile.txt (note the s, not x, in the third position).
Off-topic: But your earlier deleted question asked how to read a file line by line (I didn't think you needed to delete it, FWIW). On the assumption you're still a beginner and getting the hang of things, a pointer: You probably don't want to be using FileInputStream, which is for binary files, but instead use the Reader set of interfaces/classes in java.io (including FileReader). Also, whenever possible, declare your variables using the interface, even when initializing them to a specific class, so for instance, Reader r = new FileReader("textfile.txt") (rather than FileReader r = ...).

Categories

Resources