How do I:
Write in .txt file: Automatically create 100 blank records (fields: record id,name,age,etc) in a .txt file at the start of the program. Record id wont be blank
edit: I will enter a record id (ranging from 1-100) to add or edit data to the blank record, record id cant be edited
display in JOptionPane: I will enter a record id and all corresponding data will be displayed in JOptionPane (I know how to use JOptionPane to display stuff, but i dont know how to display only the selected data from a .txt file)
Can anyone please help to me how to do a program like this?
I know java, but im still a noob.
ok so far this is what I've got. no idea what to do next
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
public class writer {
public void writing() {
try {
File Text = new File(filepath here);
FileOutputStream FOS = new FileOutputStream(Text);
OutputStreamWriter OSW = new OutputStreamWriter(FOS);
Writer w = new BufferedWriter(OSW);
for(int x=1;x<101;x++){
w.write("Account #"+x);
}w.close();
} catch (IOException e) {
System.err.println("Problem writing to the file!");
}
}
public static void main(String[]args) {
writer write = new writer();
write.writing();
}
}
Ok, this sounds a lot like homework, so I'll give you some pointers which should hopefully allow you to find the results yourself with some directed searching...
Depending on how much data you wish to put in the .txt file, you might want to edit it by hand, in a CSV format:
accountId,name,age,etc
You are looking to have 100 records - while you can do it this way, you could start with just a handful created by hand, as an initial step, before writing something to produce your records.
After that, you need to design your model (ie. the Account object), this is likely to be a Plain Old Java Object (POJO), which is a standard class, with some private attributes, and getters and setters to access the data stored within.
You'll also need to read in the source data file and turn them into (Account) objects that will be later used - in instances like this, I like to use the BufferedReader class, as it allows you to read in an entire line of a text file in one go:
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(new (File("/path/to/file")))));
You are then able to read in a line of the file with String line = reader.readLine()
Look at the methods available in the String class to see if you can find a suitable method to break up a string, based on a given separating value (in this case a comma, since it's csv) - you then create a new Account object and populate it with the values provided.
Several people have (rightly) pointed out the use of a Map to store the created objects - Hint: Look up HashMap (the account id can be the key)
When it comes to getting input from the user, JOptionPane.showInputDialog() will be what you need (parentComponent can be null)
I hope that is enough to get you going, without actually completing your homework for you.
If you have more questions, feel free to ask away.
Related
I'm reading a file line by line, and I am trying to make it so that if I get to a line that fits my specific parameters (in my case if it begins with a certain word), that I can overwrite that line.
My current code:
try {
FileInputStream fis = new FileInputStream(myFile);
DataInputStream in = new DataInputStream(fis);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
if (line.startsWith("word")) {
// replace line code here
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
...where myFile is a File object.
As always, any help, examples, or suggestions are much appreciated.
Thanks!
RandomAccessFile seems a good fit. Its javadoc says:
Instances of this class support both reading and writing to a random access file. A random access file behaves like a large array of bytes stored in the file system. There is a kind of cursor, or index into the implied array, called the file pointer; input operations read bytes starting at the file pointer and advance the file pointer past the bytes read. If the random access file is created in read/write mode, then output operations are also available; output operations write bytes starting at the file pointer and advance the file pointer past the bytes written. Output operations that write past the current end of the implied array cause the array to be extended. The file pointer can be read by the getFilePointer method and set by the seek method.
That said, since text files are a sequential file format, you can not replace a line with a line of a different length without moving all subsequent characters around, so to replace lines will in general amount to reading and writing the entire file. This may be easier to accomplish if you write to a separate file, and rename the output file once you are done. This is also more robust in case if something goes wrong, as one can simply retry with the contents of the initial file. The only advantage of RandomAccessFile is that you do not need the disk space for the temporary output file, and may get slight better performance out of the disk due to better access locality.
Your best bet here is likely going to be reading in the file into memory (Something like a StringBuilder) and writing what you want your output file to look like into the StringBuilder. After you're done reading in the file completely, you'll then want to write the contents of the StringBuilder to the file.
If the file is too large to accomplish this in memory you can always read in the contents of the file line by line and write them to a temporary file instead of a StringBuilder. After that is done you can delete the old file and move the temporary one in its place.
An old question, recently worked on this. Sharing the experience
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public static void updateFile(Path file) {
// Get all the lines
try (Stream<String> stream = Files.lines(file,StandardCharsets.UTF_8)) {
// Do the replace operation
List<String> list = stream.map(line -> line.replaceAll("test", "new")).collect(Collectors.toList());
// Write the content back
Files.write(file, list, StandardCharsets.UTF_8);
} catch (IOException e) {
e.printStackTrace();
}
}
Recently I am doing a code review, the code is like this:
File j = new File(aFile);
System.out.println(j.length());
BufferedReader fileReader = new BufferedReader(new FileReader(j));
BufferedWriter fileWriter = new BufferedWriter(new FileWriter(aFile.getPath());
System.out.println(j.length());
I have two questions:
Is j a duplicate of aFile, because I have seen other huge methods for copying files, like here.
The first System.out.println() prints 32 and the second, after creating a file reader, prints 0. So, why are the contents getting deleted? Could someone explain what's happening here?
I put those System.out.println() statements to check if the file is empty or not.
Solution:
After Reading through the answers, I think I found what's wrong with the code. If j is just a reference, then the fileWriter is trying to write into the same file and it is cyclic. Am I right here?
EDIT: This is not a duplicate of suggested question, as the whole confusion was thinking that the j is clone or duplicate of aFile.
You're not showing us everything, are you?
The presented code definitely does not change or delete the file, as is already indicated by the names of the classes you are using: BufferedReader, FileReader (note Reader in both).
I thought there might be a slim chance that some operating systems would lock the file once you create the Readers, hence not even allowing a File object to read the length() property anymore. However, I couldn't find that documented or reported anywhere, so I highly doubt it.
I ran the following code, where test is a plain text file containing 0123456789 (length 10):
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
public class StackOverflow {
public static void main(String[] args) {
File f = new File("test");
System.out.println("Length before: " + f.length());
try {
BufferedReader fileReader = new BufferedReader(new FileReader(f));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
System.out.println("Length after: " + f.length());
}
}
Result:
Length before: 10
Length after: 10
Hence, I suspect the issue lies elsewhere.
EDIT:
Now that OP updated the question, we finally have the relevant line:
BufferedWriter fileWriter = new BufferedWriter(new FileWriter(aFile.getPath());
That's why the file is empty and its length 0. FileWriter will open the file for writing and overwrite the existing contents, if any. You can prevent this by passing in a second parameter, making use of another constructor of FileWriter, one that accepts an append flag:
public FileWriter(String fileName, boolean append) throws IOException
public FileWriter(File file, boolean append) throws IOException
Constructs a FileWriter object given a File object/name. If the second argument is true, then bytes will be written to the end of the file rather than the beginning.
In other words, if you don't want the contents to be overridden, change your above line to:
BufferedWriter fileWriter = new BufferedWriter(new FileWriter(aFile.getPath(), true);
1) j is not a duplicate, it is a reference to a new file object that wraps the actual file.
2) There is no way this code should delete (or even change) the file. Is there any more code?
1) Is j a duplicate of aFile, because I have seen other huge methods for copying files, like here and here.
It is a File object constructed from aFile, whatever that may be. This process has nothing whatsoever to do with copying files, whether huge or hugely or otherwise. File just wraps a file name. Not its contents. Your first link has nothing to do with copying files either.
2) The first result prints 32 and the second result after creating a file reader prints 0. So, why are the contents getting deleted?
Obviously this is not the real code. The real test is whether fileReader.read() immediately returns -1.
I wanted to make a demo of reading input from console then using JOptionPane. If I first type br.readLine() then use JOption... the input dialog is not showing and I can still write in the console like somebody would wait for it... I want input dialog to show up.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import javax.swing.JOptionPane;
public class Kalkulator {
public static void main(String[] args) {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Type number");
int liczba1 = Integer.valueOf(br.readLine());
br.close();
int liczba2 = Integer.valueOf(JOptionPane.showInputDialog("Type number"));
System.out.println(liczba1 + liczba2);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Simply because System.in is a stream. When you type, you provide data. That data is stored in some kind of queue.
When one calls br.readLine, a part of the queue is read out (and sometimes blocks until data is provided)...
Closing a stream simply means that you recycle some resources (like for instance mark a file again as available). Now a console keeps accepting data. You only won't read it anymore.
It is up to the console program (bash, sh, cmd.exe,...) to handle the fact that a user enters data. A console program then redirects the entered values to System.in. Java has no control over that program...
You can always type in the console. No one has to be listening. When you type in the console, the characters are stored in a buffer called a stream. If no one is reading the stream, the character just queue up. Calling br.readLine() draws characters out of the stream until a newline is seen.
Most consoles these days echo the characters typed themselves, and you can't generally turn that off, so even when you've stopped listening, the user can still type (pointlessly). If you don't want them to, and you think they probably will, the best you can do is output a message telling them not to (politely).
I'm reading a file line by line, and I am trying to make it so that if I get to a line that fits my specific parameters (in my case if it begins with a certain word), that I can overwrite that line.
My current code:
try {
FileInputStream fis = new FileInputStream(myFile);
DataInputStream in = new DataInputStream(fis);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
if (line.startsWith("word")) {
// replace line code here
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
...where myFile is a File object.
As always, any help, examples, or suggestions are much appreciated.
Thanks!
RandomAccessFile seems a good fit. Its javadoc says:
Instances of this class support both reading and writing to a random access file. A random access file behaves like a large array of bytes stored in the file system. There is a kind of cursor, or index into the implied array, called the file pointer; input operations read bytes starting at the file pointer and advance the file pointer past the bytes read. If the random access file is created in read/write mode, then output operations are also available; output operations write bytes starting at the file pointer and advance the file pointer past the bytes written. Output operations that write past the current end of the implied array cause the array to be extended. The file pointer can be read by the getFilePointer method and set by the seek method.
That said, since text files are a sequential file format, you can not replace a line with a line of a different length without moving all subsequent characters around, so to replace lines will in general amount to reading and writing the entire file. This may be easier to accomplish if you write to a separate file, and rename the output file once you are done. This is also more robust in case if something goes wrong, as one can simply retry with the contents of the initial file. The only advantage of RandomAccessFile is that you do not need the disk space for the temporary output file, and may get slight better performance out of the disk due to better access locality.
Your best bet here is likely going to be reading in the file into memory (Something like a StringBuilder) and writing what you want your output file to look like into the StringBuilder. After you're done reading in the file completely, you'll then want to write the contents of the StringBuilder to the file.
If the file is too large to accomplish this in memory you can always read in the contents of the file line by line and write them to a temporary file instead of a StringBuilder. After that is done you can delete the old file and move the temporary one in its place.
An old question, recently worked on this. Sharing the experience
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public static void updateFile(Path file) {
// Get all the lines
try (Stream<String> stream = Files.lines(file,StandardCharsets.UTF_8)) {
// Do the replace operation
List<String> list = stream.map(line -> line.replaceAll("test", "new")).collect(Collectors.toList());
// Write the content back
Files.write(file, list, StandardCharsets.UTF_8);
} catch (IOException e) {
e.printStackTrace();
}
}
at the moment I have this:
import java.util.*;
import java.io.*;
import java.io.BufferedReader;
import java.io.FileReader;
public class StudentID {
public static void main(String[] args)throws Exception{
System.out.println ("Please enter StudentID: ");
BufferedReader reader = new BufferedReader (new FileReader("CW2_data.csv"));
File file = new File("CW2_data.csv");
try {
BufferedReader r = new BufferedReader(
new InputStreamReader(
new FileInputStream("CW2_data.csv")));
String line;
while((line = r.readLine()) != null)
System.out.println(line);
r.close();
} catch(IOException e) {
System.out.println(" There was an Error Reading the file. " + e.getMessage());
}
}
}
I am trying to get the program to prompt the user for its StudentID, then search through the data file for that StudentId and return their marks for all the modules. Unfortunatly all my codes does is list the whole file back to me.
I tried to add StudetnID=Userinput.readstring; right after so that user was given an opertunity to type in the username but then I realise that wouldn't work unless I tell it scan the whole document for it. I was reading up on maps (as recomendeded by user on here) but I still haven't got to grips with it and I don't know if it would it even work here. The data file is in form of 3 columns and about 282 rows of data, ie
UserID: Module: Mark
ab006, GYH095, 56
Any help would appreciated.
As that this appears to be homework (and how it relates to your previous question) I will not give a full solution.
The buffered reader reads an entire line of text. So you'll get strings similar to this:
"ab006, GYH095, 56"
With that string you can use something like StringTokenizer or String.split to seperate the individual elements, which now become "ab06", "GYH095", "56" ...
The reason this program just writes the entire file back to you is that the program just scans through the file, without doing anything to what it reads.
Well, it is good progress that you are getting the file to be read properly. What you first want to do is get the user's input before reading the file. This can be done with the Java Scanner class. Take a look there for examples on how to use it (you will want to read a String from the user. Hint: the nextLine() method). The rest can be done via stevens explanation.
To load the data, how about you make a simple class that represents a line from your datafile, and then store it in a List. Yes, you'll have to scan through the entire list each time but it doesn't seem that large anyway (if there is a natural key you can use, which appears to be the case, you could indeed use a Map). Check out the java tutorial on collections.