I'm trying to create a method where it reads doubles from my .txt file which looks like:
Homer Simpson, 50.0
Zoidberg, 100
Peter Griffin, 34.0
Lisa Simpson, 100
and sort them in descending order, here's my code:
public static void sortGrade() throws IOException {
FileReader reader = new FileReader("Grades.txt");
BufferedReader buffer = new BufferedReader(reader);
Scanner input = new Scanner ("Grades.txt");
Double dGrade=0.0;
ArrayList<Double> grade = new ArrayList<Double>();
while (input.hasNextDouble())
{
grade.add(dGrade);
}
reader.close();
Collections.sort(grade, Collections.reverseOrder());
FileWriter fileWriter = new FileWriter("Grades.txt");
PrintWriter out = new PrintWriter(fileWriter);
for (Double outputLine : grade)
{
out.println(outputLine);
}
out.close();
}
}
After I call the method, it deletes my .txt file and terminates the program. Does anyone know what i'm doing wrong syntactically or logically?
You have several problems in your code:
You declare BufferedReader buffer = new BufferedReader(reader); but never use the buffer to read the data, instead you use the Scanner input.
Scanner input = new Scanner ("Grades.txt"); uses Scanner(String) which means it will use the String parameter as the source to read the data. You should pass it as a File instead, like this:
Scanner input = new Scanner(new File("Grades.txt"));
You're creating an output file with the same name and path of the input file, noted here:
FileWriter fileWriter = new FileWriter("Grades.txt");
Use a different name and location for this file, like:
FileWriter fileWriter = new FileWriter("Grades-out.txt");
In case you want/need to append data to the end of the output, then use FileWriter(String, boolean) and pass the second parameter as true.
FileWriter fileWriter = new FileWriter("Grades-out.txt");
Be aware that when you use this approach you have to manually clear the file before executing the application, otherwise you may have duplicated data in your input.
From 2, since you haven't read any double from "Gradex.txt" string, then there's no output in the file, so the current output file, Grades.txt, will be an empty file.
I recommend you to create a class called Person where you store both the name string and the double (whatever it means), then store every instance of Person in a List<Person> (backed by an ArrayList<Person>) and sort this list using a custom Comparator<Person> or by implementing Comparable<Person> in Person class.
You can use something like this (I always use a charset for reading, if you don't need it just don't use it):
List<Double> result = new LinkedList<>();
try (Scanner scanner = new Scanner(Paths.get("Grades.txt"), StandardCharsets.UTF_8.name())) {
while (scanner.hasNextLine()) {
result.add(Double.valueOf(scanner.nextLine().split(",")[1]));
}
} catch (IOException e) {
System.err.printf("Something happened here...this is why: %s", e);
}
Collections.sort(result, Collections.reverseOrder());
// Do your other stuff from now on...
Related
I am looking at the performance of a particular stock over a period of 30 days. I downloaded the data from Yahoo finance which appears as a CSV file. If I would like to create a new column in my dataset to show the daily percentage change between open and close using java refer to column H as where the output should appear, how should I do so?
Thanks in advance!
You can just edit your file line-by-line and add a separator character using the concat() function.
Open the file with a FileReader or BufferedReader and then start parsing.
Official Javadoc: https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#concat(java.lang.String)
Please see also this.
With OpenCSV: http://opencsv.sourceforge.net/
public class OpenCSVTest {
public static void main(String[] args) {
StringWriter target = new StringWriter();
try(CSVReader reader = new CSVReader(new StringReader("my,test"));
CSVWriter writer = new CSVWriter(target);) {
for(String[] line : reader) {
String[] added = Arrays.copyOf(line, line.length + 1);
added[added.length-1] = "addition";
writer.writeNext(added);
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(target.toString());
}
}
You can replace the StringReader and StringWriter with your input and output. The reader will then iterate through each line in your csv for you. You can make a copy of the original line and add your new column and write it out into the target.
Breakdown of the code:
try(CSVReader reader = new CSVReader(new StringReader("my,test"));
CSVWriter writer = new CSVWriter(target);) { ... }
This is a try-with-resources block. It makes sure that the reader and writer are closed after they are done.
for(String[] line : reader) {
String[] added = Arrays.copyOf(line, line.length + 1);
added[added.length-1] = "addition";
writer.writeNext(added);
}
This is a standard for loop. The CSVReader implements the Iterable interface, which enables us to use it in the for loop directly.
Arrays.copyOf(line, line.length + 1); is a function that creates a copy of the array passed to it, but with a new size. Because you want to add a column, we make a copy of the original array my,test and add 1 more space at the end of it, where we can then assign the new value to it by doing: added[added.length-1] = "addition";
Finally, we just pass that to the writer which will then correctly write the values into the target, in this case a StringWriter, in your case likely a file.
the practice question i got says that i need to
create a java code that reads in csv file with name and height.
to read a file you must get a file name from user as string.
then you must store contents of file into two arrays one for name (string) and height(real number).
You should read the file at least twice, once to check how many students are in the file (so you know how many students you need to store) and a couple more times to actually read the file (to get the names and height).
then prompt the user for name you want height of. it should output the height for userinput.
example csv file is
chris,180
jess,161
james, 174
its not much but this is all i could come up with i have no idea how to store name and height separately and use that array to output the results. and would i need to use split somewhere in the code? i remember learning it but dont know if its used in this situation
import.java.util.*;
private class StudentNameHeight
private void main (string [] args)
{
String filename;
Scanner sc = new scanner(system.in);
System.out.println("enter file name")
filename = sc.nextline();
readFile (filename);
}
private void readFile (String filename)
{
FileInputStream fileStrm = null;
InputStreamReader rdr;
BufferedReader bufRdr;
try
{
fileStrm = new FileInputStream(filename);
rdr = new InputStreamReader(fileStrm);
bufRdr = new BufferedReader(rdr);
// ?
catch (IOException e)
{
if (fileStrm != null)
{
try {fileStrm.close(); } catch (IOException e2){}
}
System.out.println("error in processing" + e.getMessage());
}
}
im new to java so, any small tip or help would be great
thanks
You code looks messy. As far as I understand from your question, you are willing to read a CSV file containing two entities, one is name and another is height and store these two entities in two different data structures. I'm teaching you a simple way to accomplish this in below code snippet.
public void processCSVFile(String filePath){
try(BufferedReader fileReader = new BufferedReader(new FileReader(new File(filePath)))){
//Create two lists to hold name and height.
List<String> nameList = new ArrayList<>();
List<Integer> heightList = new ArrayList<>();
String eachLine = "";
/*
* Read until you hit end of file.
*/
while((eachLine = fileReader.readLine()) != null){
/*
* As it is CSV file, split each line at ","
*/
String[] nameAndHeightPair = eachLine.split(",");
/*
* Add each item into respective lists.
*/
nameList.add(nameAndHeightPair[0]);
heightList.add(Integer.parseInt(nameAndHeightPair[1]));
}
/*
* If you are very specific, you can convert these
* ArrayList to arrays here.
*/
}catch(IOException e1){
e1.printStackTrace();
}
}
So i'm trying to write to a file to use as a save point to access later, but i cant actually get it to write to the file. I'm trying to save the components of a class to access next time I open and run the program, by writing a string with the PIV's to the file as a save method and by using a scanner to search for tags at the beginning of each line to access later. My code so far though, will not actually write to the file. It compiles and runs fine, but the file shows being unchanged after the program runs.
public static void main(String[] args) throws FileNotFoundException, IOException
{
File f = new File("SaveFile");
Scanner sc = new Scanner(f);
String save = new String();
while(sc.hasNextLine())
{
save=sc.nextLine();
}
byte buf[]=save.getBytes();
FileOutputStream fos = new FileOutputStream(f);
for(int i=0;i<buf.length;i++)
fos.write(buf[i]);
if(fos != null)
{
fos.flush();
fos.close();
}
}
If anyone has a way to fix the code or even a better idea for saving please let me know, thanks
You are replacing save value in every single nextLine.
Change this line:
save = sc.nextLine();
to this one:
save += sc.nextLine();
Also, it's better to use a FileWriter when you are writing String to a file.
And because String is immutable, it will be a slow procedure. Consider using StringBuilder or CharBuffer instead of simple solution which I mentioned above.
Look at code included below:
public static void main (String[] args) throws Exception
{
File f = new File("SaveFile");
Scanner sc = new Scanner(f);
StringBuilder builder = new StringBuilder();
while (sc.hasNextLine())
{
builder.append(sc.nextLine() + "\n");
}
String save = builder.toString();
FileWriter writer = new FileWriter(f);
writer.write(save);
writer.close();
}
Also close() implicitly calls flush().
I am trying to finish a bank accounts homework assignment. I have a text file, "BankAccounts.txt" which is created if there is no file with that name. However, if the file exists, I do not create it. But Java desides to delete all my code inside of it :(. Can you help me identify why this happens? Thanks <3
Code:
static Scanner keyboard = new Scanner(System.in);
static File file;
static PrintWriter Vonnegut; //a great writer
static FileReader Max;
static BufferedReader Maxwell;
public static void main(String[] args) {
initialize();
}
static void initialize(){
try { // creating banking file
file = new File("src/BankAccounts.txt");
if(!file.isFile()) {file.createNewFile();} //if it doesn't exist, create it
Vonnegut = new PrintWriter("src/BankAccounts.txt","UTF-8");
Max = new FileReader("src/BankAccounts.txt");
Maxwell = new BufferedReader(Max);
//get list of usernames and passwords for later
usernames = new String[countLines() / 5];
passwords = new String[usernames.length];
checkingAccounts = new String[usernames.length];
savingsAccounts = new String[usernames.length];
} catch (IOException e) {
e.printStackTrace();
}
}
And this method keeps returning 0... regardless of whether or not my file has data in it.
static int countLines() throws IOException {
BufferedReader Kerouac = new BufferedReader(Max);
int lines = 0;
while(Kerouac.readLine() != null)
lines++;
Kerouac.close();
System.out.println(lines);
return lines;
}
After I run the program, unless I call a method that writes to the file, all the contents of the file will be gone.
if(!file.isFile()) {file.createNewFile();} //if it doesn't exist, create it
Redundant. Remove.
Vonnegut = new PrintWriter("src/BankAccounts.txt","UTF-8");
This always creates a new file, which is why the previous line is redundant. If you want to append to the file when it already exists:
Vonnegut = new PrintWriter(new FileOutputStream("src/BankAccounts.txt", true),"UTF-8");
The true parameter tells the FileOutputStream to append to the file.
See the Javadoc.
Or use a FileWriter instead of a FileOutputStream, same principle.
When you create a PrintWriter it will always delete the file if it already exists, from the javadoc:
... If the file exists then it will be truncated to zero size ...
(i. e. its content will be deleted)
Instead of using FileReader and PrintWriter you need to use a RandomAccessFile to write and/or read your file in this way:
RandomAccessFile myFile = new RandomAccessFile("/path/to/my/file", "rw");
In this way the file is automatically created if it doesn't exist, and if it does, it just opens it.
Here is my issue: I need to write the Interator to the file "random.txt" I am able to see all the data. The data is Store where suppose to, I can see it with the System.out.print but my file is in blank. I am able to create the file but not to writer to it.
I am reading a file from my comp. store in the Treemap and trying to write to the text file. ( I am able to doit with Array with not problem) But this Map with Iterator is bouncing my head.
If some one can help me a litter I will appreciated.
I need to use the TreeMap and the Iterator.
public static void main(String[] args) throws FileNotFoundException, IOException {
Map<String, String> Store = new TreeMap<>();
Scanner text=new Scanner(System.in);
System.out.println("enter file: ");
//C:\Users\Alex\Desktop\Fruits\fruits.txt
String rap=text.next();
File into = new File(rap);
try (Scanner in = new Scanner(into)) {
while (in.hasNext()){
String name=in.next();
String fruta = in.next();
Integer num= Integer.parseInt(in.next());
System.out.println(fruta+"\t"+name+"\t"+num);
if (Store.containsKey(fruta)){
Store.put(name,Store.get(name)+fruta );
}
else{
Store.put(name,fruta);
}
}
in.close();
}
System.out.println();
// insert data to store MAP
Set top=Store.entrySet();
Iterator it = top.iterator();
// debugging
System.out.println(top);
// Creating file???????
FileWriter fstream = new FileWriter("random.txt");
//identify File to be write??????
BufferedWriter out = new BufferedWriter(fstream);
//iterator Loop
while(it.hasNext()) {
Map.Entry m = (Map.Entry)it.next();
String key = (String)m.getKey();
String value = (String)m.getValue();
//writing to file?????
out.write("\t "+key+"\t "+value);
// debugging
System.out.println(key +"\t"+ value);
}
System.out.println("File created successfully.");
}
After your while loop (the one writing to file) is finished, do:
out.flush();
out.close();
Short explanation: BufferedWriter buffers in memory what you write. It doesn't immediately write to file when you call the write method. Once the while loop is finished and the data to write to file is prepared in buffer memory, you should call flush to do the actual writing to hard disk. And finally you should always close the BufferedWriter that will no longer be used, to avoid memory leaks.