package q1;
import java.io.FileNotFoundException;
import java.util.ArrayList;
/**
* <p>This is where you put your description about what this class does. You
* don't have to write an essay but you should describe exactly what it does.
* Describing it will help you to understand the programming problem better.</p>
*
* #author Your Name goes here
* #version 1.0
*/
public class Household {
/**
* <p>This is the main method (entry point) that gets called by the JVM.</p>
*
* #param args command line arguments.
* #throws FileNotFoundException
*/
public static void main(String[] args) throws FileNotFoundException {
// your code will go here!!!
Survey s1 = new Survey();
s1.getSurveyList();
System.out.println();
}
};
-------------------------------------------------------------------------------------------
package q1;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class Survey {
ArrayList<Integer> surveyList = new ArrayList<Integer>();
public Survey(){
}
public ArrayList<Integer> getSurveyList() throws FileNotFoundException{
Scanner sc = new Scanner(new File("survey.txt"));
while (sc.hasNextLine()) {
sc.useDelimiter(" ");
int i = sc.nextInt();
surveyList.add(i);
}
System.out.println(surveyList.get(0));
sc.close();
return surveyList;
}
}
Now it says that the system cannot find the file specified. Not sure how to use the File class because it is the first time I have had to do it.
Any ideas? Also how would one format the output of the text file so that it displays it in a table? Is there some method that does that?
The error "Could not find main class" has nothing to do with the way you are using the File or Scanner class. It sounds like your classpath is wrong. Ensure that your project root is configured correctly. You could try to use this tutorial for using Eclipse for a reference on how to set up your project correctly. If you are not using an IDE, check out the contents of the file you are running and make sure the correct information is in there. It would help a lot if you could specify your question a lot more such as which operating system are you using, are you using an IDE (if yes, which one), are you compiling it as a jar file or are you running it from a directory with class files... etc.
Changed Array to Double instead of Integer and changed the scanner line to this:
Scanner sc = new Scanner(
new File("src" + File.separator + "survey.txt"));
Related
I'm currently working on a project and I'm running into a couple of issues. This project involves working with 2 classes, Subject and TestSubject. Basically, I need my program (in TestSubject class) to read details (subject code and subject name) from a text file and create subject objects using this information, then add those to an array list. The text file looks like this:
ITC105: Communication and Information Management
ITC106: Programming Principles
ITC114: Introduction to Database Systems
ITC161: Computer Systems
ITC204: Human Computer Interaction
ITC205: Professional Programming Practice
the first part is the subject code i.e. ITC105 and the second part is the name (Communication and Information Management)
I have created the subject object with the code and name as strings with getters and setters to allow access (in the subject class):
private static String subjectCode;
private static String subjectName;
public Subject(String newSubjectCode, String newSubjectName) {
newSubjectCode = subjectCode;
newSubjectName = subjectName;
}
public String getSubjectCode() {
return subjectCode;
}
public String getSubjectName() {
return subjectName;
}
public void setSubjectCode(String newSubjectCode) {
subjectCode= newSubjectCode;
}
public void setSubjectName(String newSubjectName) {
subjectName = newSubjectName;
}
The code I have so far for reading the file and creating the array list is:
public class TestSubject {
#SuppressWarnings({ "null", "resource" })
public static void main(String[] args) throws IOException {
File subjectFile = new File ("A:\\Assessment 3 Task 1\\src\\subjects.txt");
Scanner scanFile = new Scanner(subjectFile);
System.out.println("The current subjects are as follows: ");
System.out.println(" ");
while (scanFile.hasNextLine()) {
System.out.println(scanFile.nextLine());
}
//This array will store the list of subject objects.
ArrayList <Object> subjectList = new ArrayList <>();
//Subjects split into code and name and added to a new subject object.
String [] token = new String[3];
while (scanFile.hasNextLine()) {
token = scanFile.nextLine().split(": ");
String code = token [0] + ": ";
String name = token [1];
Subject addSubjects = new Subject (code, name);
//Each subject is then added to the subject list array list.
subjectList.add(addSubjects);
}
//Check if the array list is being filled by printing it to the console.
System.out.println(subjectList.toString());
This code isn't working, the array list is just printing as blank. I have tried doing this several ways including a buffered reader but I can't get it to work so far. The next section of code allows a user to enter a subject code and name, which is then added to the array list as well. That section of code works perfectly, I'm just stuck on the above part. Any advice on how to fix it to make it work would be amazing.
Another small thing:
File subjectFile = new File ("A:\\Assessment 3 Task 1\\src\\subjects.txt"); //this file path
Scanner scanFile = new Scanner(subjectFile);
I'd like to know how I can change the file path so that it will still work if the folder is moved or the files are opened on another computer. The .txt file is in the source folder with the java files. I have tried:
File subjectFile = new File ("subjects.txt");
But that doesn't work and just throws errors.
That is because you have already read through the file
while (scanFile.hasNextLine()) {
System.out.println(scanFile.nextLine());
}
The contents are exhausted. So when you do
while (scanFile.hasNextLine()) {
token = scanFile.nextLine().split(": ");
there is no data left.
Remove the first loop or re-open the file.
Or as #UsagiMiyamoto mentions
Or read the line to a String variable, print it, then split it... All in one loop.
I assume you are just beginning with learning Java and hence the below code is probably way too advanced, but it may help others who are trying to do something similar to you and also give you a glimpse of what you will probably learn in future.
The below code uses the following (in no particular order):
Streams
Accessing resources
Records
try-with-resources
Multi-catch
Method references
NIO.2
More notes after the code.
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public record Subject(String subjectCode, String subjectName) {
private static final String DELIMITER = ": ";
private static Path getPath(String filename) throws URISyntaxException {
URL url = Subject.class.getResource(filename);
URI uri = url.toURI(); // throws java.net.URISyntaxException
return Paths.get(uri);
}
private static Subject makeSubject(String line) {
String[] parts = line.split(DELIMITER);
return new Subject(parts[0].trim(), parts[1].trim());
}
/**
* Reads contents of a text file and converts its contents to a list of
* instances of this record and displays that list.
*
* #param args - not used.
*/
public static void main(String[] args) {
try {
Path path = getPath("subjects.txt");
try (Stream<String> lines = Files.lines(path)) { // throws java.io.IOException
lines.map(Subject::makeSubject)
.collect(Collectors.toList())
.forEach(System.out::println);
}
}
catch (IOException | URISyntaxException x) {
x.printStackTrace();
}
}
}
A Java record is applicable for an immutable object and it simply saves you from writing code for methods including getters as well as equals, hashCode and toString. (There are no setters since a record is immutable.) It's a bit like Project Lombok. I would say that a Subject is immutable since I don't think the code or name would need to be changed and that's why I thought making Subject a record was applicable.
Running the above code produces the following output:
Subject[subjectCode=ITC105, subjectName=Communication and Information Management]
Subject[subjectCode=ITC106, subjectName=Programming Principles]
Subject[subjectCode=ITC114, subjectName=Introduction to Database Systems]
Subject[subjectCode=ITC161, subjectName=Computer Systems]
Subject[subjectCode=ITC204, subjectName=Human Computer Interaction]
Subject[subjectCode=ITC205, subjectName=Professional Programming Practice]
Regarding
I'd like to know how I can change the file path so that it will still work if the folder is moved
I placed file subjects.txt in the same folder as file Subject.class, which allowed me to use method getResource. Refer to the Accessing resources link, above. Note that this can't be used if
the files are opened on another computer
Alternatively, there are several directories whose paths are stored in System properties including
java.home
java.io.tmpdir
user.home
user.dir
what did your debug console said about the exception?
your code works very well in my editor.
code result
and you should code like below if you want to read file through relative path
before ->
new File ("A:\Assessment 3 Task 1\src\subjects.txt");
after ->
new File (".\\subjects.txt");
I'm using constructor chaining, and I'm worried that it's causing a resource leak. Here are my two constructors:
/**
* Constructor to build the map based off of a file. Redirects to the Scanner-based constructor
* #param fileName the name of the file to open
*/
public GeoMap(String fileName) throws FileNotFoundException {
this(new Scanner(new File(fileName)));
}
/**
* Constructor to build the map based off of a Scanner. (Probably from an open file.)
* #param scanner the Scanner to read
*/
public GeoMap(Scanner scanner) {
// goes on to read the string data and make an object...
It's important that the object be created from any type of Scanner (keyboard, file, etc.), though it'll usually be from a file. The problem is that I think there's a resource leak going on here. Whenever I'm reading a file, I like to close it when I'm done. Problem is, the constructor chaining means that the this() call must be the first line. I'd be inclined to do something like this:
this(Scanner scannerToClose = new Scanner(new File(fileName)));
In my mind that would give me the name of a Scanner I could then close out. But that seems to really confuse the compiler--I get about 5 compile-time errors out of it, including a lot of "cannot find symbol" problems that imply that the compiler's just not wired for this sort of thing. Does Java support this? Or do I need to make a totally different initFromScanner() function that both constructors call? (Not elegant.)
Thanks.
Call scanner.close() at the end of your GeoMap(Scanner scanner) constructor.
This will close the Scanner created in GeoMap(String filename) since a reference to it is passed into the GeoMap(Scanner scanner) as scanner.
In essence, the scanner variable points to the new scanner that was created, so calling scanner.close() anywhere, in any method, closes it for any and all other methods it may be in the scope of.
Here is a program which demonstrates the object oriented nature of Scanners:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Main
{
static class Test
{
String name;
public Test(String filename) throws FileNotFoundException
{
this(new Scanner(new File(filename)));
}
public Test(Scanner scanner)
{
name = scanner.nextLine();//body of constructor
scanner.close();
System.out.println("Your name is "+ name);
scanner.close();
/*These next lines of code show that the Scanner is closed */
String throwsException = scanner.nextLine();
System.out.println(throwsException + "here");//unreachable
}
}
public static void main(String[] args)
{
try
{
Test temp = new Test("input.txt");
}
catch(Exception e)
{
System.out.println(e);
}
}
}
input.txt:
Smitty
output:
Your name is Smitty
java.lang.IllegalStateException: Scanner closed
In essence it doesn't matter where the Scanner is created, if it is closed at any point, it is closed everywhere that it is in scope.
I assume that your issue is that you only want to close the involved scanner if you have created it in your constructor that takes fileName. I don't think there's anything wrong with your idea of having an init method that both of your constructors call. I don't think that's inelegant.
I think what I would do is create a third private constructor instead of an init method. It's really the same thing either way, although maybe at some point you'd want to be able to pass in a pre-built Scanner that you want closed at the end of the constructor call, in which case you could make this new constructor public so you could call it from the outside.
In either case, what I'd do is pass a boolean "closeScanner" parameter to the new constructor/method that indicates if the scanner should be closed or not. Here's my idea in code:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
class GeoMap {
/**
* Constructor to build the map based off of a file. Redirects to the Scanner-based constructor
*
* #param fileName the name of the file to open
*/
public GeoMap(String fileName) throws FileNotFoundException {
this(new Scanner(new File(fileName)), true);
}
/**
* Constructor to build the map based off of a Scanner. (Probably from an open file.)
*
* #param scanner the Scanner to read
*/
public GeoMap(Scanner scanner) {
this(scanner, false);
}
private GeoMap(Scanner scanner, boolean closeScanner) {
// goes on to read the string data and make an object...
if (closeScanner)
scanner.close();
}
}
Lets start with this:
public GeoMap(Scanner scanner) {
...
}
Is there a resource leak here? Well, it depends on where the responsibility for closing the Scanner lies.
If responsibility lies in the constructor, then we can plug the leak like this:
public GeoMap(Scanner scanner) {
try (Scanner s = scanner) {
// original body
}
}
This is the ideal solution, but it assumes that the effect lifetime of the Scanner is the constructor.
If it is the caller responsibility, then the caller needs to deal with leak prevention. That is doable ... but outside of the scope of this question.
If it is neither the constructor or the caller's responsibility, then you need to treat the GeoMap itself as a resource, with all that that entails.
Now we consider this:
public GeoMap(String fileName) throws FileNotFoundException {
this(new Scanner(new File(fileName)));
}
Firstly, does new Scanner(new File(fileName)) present a potential resource leak?
In theory, yes. The Scanner constructor could open a stream for the file, and then fail, leaving the stream open.
In practice, it is highly unlikely. If we ignore bugs in the class library, and application bugs like using unrecognized character set names, the only cause of a spontaneous failure of new Scanner that could leak a file descriptor, etc is if you got an OOME. But that is likely to trigger a full GC anyway.
So what happens after that?
The answer depends on the earlier answer of where the responsibility lies in the GeoMap(Scanner) constructor.
If the responsibility lies in that constructor, we know how to avoid the leak; see above.
Otherwise ... we have problem:
There are possible solutions, but they may involve changing the way that the Scanner is used.
There may also be leaks involving the use of the that constructor directly.
In summary, depending on how you specify and implement GeoMap(Scanner), the GeoMap(String) constructor can be implemented to be leak proof in practice.
First, your class GeoMap should define how it handles a scanner that is given to it in the constructor; usually, when it is allowed to create its own Scanner instances as in your sample, the policy is that the GeoMap instance can do whatever it wants with that scanner, including closing it – this means it owns it, and ownership is transferred in the respective constructor.
If this is not the case (it does not own the scanner), you either have to drop the GeoMap(String) constructor (because, when not the GeoMap instance owns it, who else do and takes care of it later?), or you have to come to a design similar to that below:
class GeoMap
{
private final Scanner m_Scanner;
private final boolean m_MayCloseScanner;
/**
* Creates a GeoMap from a file.
*
* #param fileName The name of the file to open.
*/
public GeoMap( String fileName ) throws FileNotFoundException
{
this( new Scanner( new File( fileName ) ), true );
} // GeoMap()
/**
* Creates a GeoMap from a Scanner instance.
*
* #param scanner The Scanner to read
*/
public GeoMap( Scanner scanner )
{
this( scanner, false );
} // GeoMap()
/**
* Internal constructor.
*
* #param scanner The scanner to read.
* #param mayClose true, if this instance of GeoMap may close the
* given Scanner instance, false otherwise.
*/
private GeoMap( Scanner scanner, boolean mayClose )
{
m_Scanner = scanner;
m_MayCloseScanner = mayClose;
} // GeoMap()
…
}
// class GeoMap
Here the ownership is tracked by the flag m_MayCloseScanner.
Unfortunately, this does not yet solve your issue with the resource leak: the scanner will still not be closed, when the GeoMap instance is no longer used.
When your GeoMap instance will not own the scanner at all, you don't care, the resources taken by the scanner are a POOP (a problem of other people).
Ok, when you will need the scanner only for the initialisation of the GeoMap instance, you can have an init() method that closes the scanner when done:
…
public void init()
{
// Do something with the scanner ...
…
// Close the scanner when done.
m_Scanner.close()
} // init()
…
Of course, when GeoMap may or may not own the scanner, the closing line needs to look like this: if( m_MayCloseScanner ) m_Scanner.close;.
But if that init option does not work, you need a destructor for GeoMap instances. The concept of a destructor does not exist in Java, the closest to it was to implement finalize(), but this was deprecated some time ago (finally with Java 9), with good reason.
Have a look to this post on how to use Cleaner, PhantomReference and Closeable for your GeoMap class. It looks a bit confusing in the beginning, but reveals to be relatively straight forward in the end.
Ok, before anyone starts flaming me for asking "dumb" questions, please note that I have pretty much exhausted every other option that I know of and come up empty handed. Still if you feel like it, please go ahead and downvote/report this question.
Now, for those that care
I am trying to take a String input from user and store it into a file Text.txt which will be created in the current working directory.
Following is the code
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.Scanner;
public class Encryption {
public static void main(String[] args) throws Exception {
System.out.println("Enter a String you wish to encrypt : ");
new BufferedWriter(new FileWriter(".\\Text.txt")).write(new Scanner(System.in).nextLine());
System.out.println("Done");
}
}
My problem is, the file is getting generated at the correct destination, but is always empty. I have tried it on multiple JDK versions and on different machines. Still getting the blank text file.
Please tell me, what is it that I am doing wrong.
You are not closing with .close() the BufferedWriter (which would then flush the last buffer and close the file).
You can however do that task in new style:
Files.write(Paths.get(".\\Text.txt"),
Arrays.asList(new Scanner(System.in).nextLine()),
Charset.defaultCharset());
Otherwise you would need to introduce a variable, and gone is the one-liner.
Some changes i made your code to work
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.Scanner;
public class Encryption {
public static void main(String[] args) throws Exception {
System.out.println("Enter a String you wish to encrypt : ");
String text = new Scanner(System.in).nextLine();
BufferedWriter b = new BufferedWriter(new FileWriter(".\\Text.txt"));
b.write(text);
b.close();
System.out.println("Done");
}
}
I'm looking for a way to run a cluster of classes under the same package from the command line, but despite successfully compiling, I keep getting "could not load main" errors. I've changed the path and classpath to what they need to be, as well as tried building a subfolder named for the package I'm using ("com.company"), but to no avail. I've tried the following on command line while in the package-named subfolder directory, as well as the folder above that:
>java com.company.myclassname
>java myclassname
>java com\company\myclassname
>java -cp . com.company.myclassname
All have left me with the same "Error: Could not find or load main class".
At this point I've been poring over StackOverflow questions and tutorials for 3 hours to avoid having a repeat question, but I'm desperate. I've got to turn this homework assignment in in two hours. It works just fine within my IDE, and even through my backup beta IDE, but not command line. Can anyone please shed some light on this for me?
Edit: Source code:
package com.company;
import static com.company.myclassname.quantInput;
import static com.company.myclassname.costInput;
public class GroceryList {//This is the parent class for the program.
private static int counter = 0;//Used to ensure that the number of items is limited to ten.
private static GroceryList[] List = new GroceryList[10];//Used to hold the first ten grocery items in the add method.
public GroceryList(){//Basic constructor
}
.... Plus a few methods.
Client code:
package com.company;
import java.io.File;
import java.io.FileNotFoundException;
import java.text.DecimalFormat;
import java.util.Scanner;
public class myclassname {
private static String[] nameInput = new String[10];//for holding names from each line, then gets sent to constructor by index
public static int[] quantInput = new int[10];//for holding quantity from each line, then gets sent to constructor by index
public static double[] costInput = new double[10];//for holding price from each line, then gets sent to constructor by index
public static GroceryItemOrder[] GIOList = new GroceryItemOrder[10];//for holding GroceryItemOrder objects, then gets sent to toString() for printing
public static double TotalCost = 0;//initializes total cost variable
public static DecimalFormat f = new DecimalFormat("#####0.00");//Ensures proper output format for doubles
private static int counter;//Used for indexing
private static String target;//File path
public static void main(String[] args) throws FileNotFoundException, NullPointerException {
target = args[0];//User-supplied file path is assigned to variable "target"
try {//protects against NullPointerException
input();//Sends file path to input method, which sends that data to all other relevant methods and classes
System.out.printf("%-20s", "Item");//These lines provide headers for output message
System.out.printf("%-10s", "Quantity");
System.out.printf("%-10s", "Price");
System.out.printf("%-12s", "Total Price");
System.out.println();
for (int i = 0; i < counter; i++) {//Ensures only correct objects are printed to user
System.out.println(GIOList[i].toString());//public object array sends data to the toString() method, which
//then prints formatted output string, limited by counter in order to ensure only proper data prints
}if (counter<10){//If the file contains under 11 items, this prints to the user
System.out.println("Total cost: $" + f.format(TotalCost));}
else{//if the file contains 11 or more lines, this statement makes clear that only the first 10 items
//will be included in the total cost.
System.out.println("Total cost of the first ten items in your file: $" + f.format(TotalCost));
}
} catch (NullPointerException e){//safeguard against printing null strings to user
}
}
Plus an input method
Please try this quick workaround.
create a folder hierarchy com\company or com/company (depending on you OS).
Put the myclassname.class file inside the com\company folder.
from top level folder (which is at same level as com folder), run
java com.company.myclassname
Regards,
Ravi
I want to write a program that copies one file to another. I got my program to execute and run but nothing happens! I have no errors to go by so I'm stuck and don't know what to do! It doesn't create the files or copies them into one file.
Here's the command I typed:
java CopyFile report.txt report.sav
The program should create another copy of the file report.txt in report.sav. Your program should print the following error message for inappropriate number of input arguments (for e.g., java CopyFile report.txt):
Here's my code:
import java.io.FileNotFoundException;
import java.io.File;
import java.io.PrintWriter;
import java.util.Scanner;
/**
This program copies one file to another.
*/
public class CopyFile
{
public static void main(String[] args) throws FileNotFoundException
{
if (args.length != 2)
{
System.out.println("Usage: java CopyFile fromFile toFile");
return;
}
String source = args[0];
}
}
use this-
Files.copy(source.toPath(), dest.toPath());
This method you can find in java 7.
Refer to this link for other ways-
http://examples.javacodegeeks.com/core-java/io/file/4-ways-to-copy-file-in-java/
You can use FileUtils from Apache IOCommons
FileUtils.copyFile(src, dest)