My assignment is to save a list of employees as a binary file (and later read from it). I'm working on the output portion now, below is the block of the function that is in question. This function does have about 10 more lines but they edit things on the TextField arraylist.
The Employee class is the parent of both the Supervisor and Secretary classes. all is the ArrayList that holds all the employee, secretary, and employee objects.
I'm using netbeans 8.0.2, when the program runs and I click the save button in the gui (onActionEvent() is this function) there are no compiler errors. The "IO Error" or "No Permissions..." doesn't output. Ive tried saving both with and without the employees.dat file being already created.
I'm not really sure what to do at this point, I contemplated saving each object as a the collection of int, String, etc but that's dumb, it should be able to work this way... right?
EDIT:
Employee, Supervisor, and Secretary are all Serializable.
private void saveChanges(ArrayList<Employee> all, ArrayList<TextField> text, int index) {
try ( ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("employees.dat", true)); ) {
for (int i = 0; i < all.size(); i++) {
if (all.get(i).getClass() == (new Secretary().getClass()))
output.writeObject(new Secretary((Secretary) all.get(i)));
else if (all.get(i).getClass() == (new Supervisor().getClass()))
output.writeObject(new Supervisor((Supervisor) all.get(i)));
else
output.writeObject(new Employee(all.get(i)));
}
output.flush();
} catch (IOException io) {
io.printStackTrace();
} catch (SecurityException se) {
se.printStackTrace();
}
}
EDIT:
I have edited the try-catch to this code...
try ( ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("employees.dat", true)); ) {
output.writeObject(all);
output.flush();
output.close();
} catch (IOException io) {
io.printStackTrace();
} catch (SecurityException se) {
se.printStackTrace();
}
Still not writing to file. I have permissions in the folder the .java files are in.
try ( ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("employees.dat", true)); ) {
Change true to false, or remove it. You can't append to files created as object output streams, at least not like this, and it's debatable whether you're even supposed to be doing so.
for (int i = 0; i < all.size(); i++) {
if (all.get(i).getClass() == (new Secretary().getClass()))
output.writeObject(new Secretary((Secretary) all.get(i)));
else if (all.get(i).getClass() == (new Supervisor().getClass()))
output.writeObject(new Supervisor((Supervisor) all.get(i)));
else
output.writeObject(new Employee(all.get(i)));
}
Change this entire mess to this:
output.writeObject(all);
If this still doesn't work there must have been an exception somewhere, and you're just going to have to find it, print it, and post it. Edit it into your question. Or else you're looking at the wrong file.
NB you will also have to change the code that reads the file, to just read the list in a single readObject() call.
By any chance are you happening to write an applet or JNLP without appropriate permissions?
do you have write access to the folder that you are outputting the file ? (which in this case is the directory that the program is running in. )
I would recomend calling io.printStackTrace() and se.printStackTrace(); in the exception handlers to provide significantly more information about the exceptions.
At the end of the file writing also dont forget to call output.close() to ensure that the stream is closed properly, the tail of the data is written and there are no left over open file handles on your system.
Related
I'm making a new game and I wanna make a coins collector to, later, buy things with those coins. I'm using eclipse.
void save() {
try {
PrintWriter out = new PrintWriter("coins.txt");
out.write(Integer.toString(nmonedas));
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
void load() {
StringBuffer texto=new StringBuffer();
try {
int c;
#SuppressWarnings("resource")
FileReader entrada=new FileReader("coins.txt");
while((c=entrada.read())!=-1){
texto.append((char)c);
}
}
catch (IOException ex) {}
labelshow.setText(texto.toString());
}
I have this code but i cant plus the info. NEED HELP PLS
Well, the thing is, I'm doing a game in eclipse and I want you to collect coins and keep them in a file.
They are collected perfectly and stored in the file, but when I start the game again I want them to be collected but they add up with the previous ones
I assume you are referring to appending text to a .TXT file. If so, you can use something like this:
Files.write(Paths.get("Path to text file here"), "Content".getBytes(), StandardOpenOption.APPEND);
I would put the above in a TRY CATCH block. Also look into PrintWriter as this may be more appopriate to what you need it for as it allows you to continuously write to the file.
I have a program that does a lot of processing with loops and writes strings to a file at many different points. I'm not sure about the overall design for how best to do this. I won't need to read from the file at any point during running, though will want to view it afterwards.
Firstly, is a BufferedWriter with FileWriter a reasonable way of doing this?
Secondly, presumably I don't want to be opening and closing this every time I want to write something (several times per second).
But if I use try with resources then I'd have to put practically the entire program inside that try, is this normal?
At the moment the skeleton looks like:
try (FileWriter writer = new FileWriter("filename.txt");
BufferedWriter bw = new BufferedWriter(writer)) {
} catch (IOException e) {
//catch IO error
}
for (//main loop){
bw.write(string);
for (//several sub loops){
bw.write(//more strings);
}
for (//several sub loops){
bw.write(//more strings);
}
}
bw.write(//final string);
try {
bw.close();
} catch (IOException ex) {
//catch IO error
}
Does this look reasonable or is there a better way? Thanks very much in advance for the help.
Edit - thanks to you all for the help, totally answered my questions.
Firstly, is a BufferedWriter with FileWriter a reasonable way of doing this?
Yes, it should be the most convenient way to do this.
Secondly, presumably I don't want to be opening and closing this every time I want to write something (several times per second).
You really shouldn't. But you would actually overwrite your progress this way everytime you open the file anyway. That's because you didn't tell the FileWriter to append to an existing file (via new FileWriter("filename.txt", true);.
But if I use try with resources then I'd have to put practically the entire program inside that try, is this normal?
I don't see a problem with that. You can (and should) always move your logic into own methods or classes, which may return the Strings to write. This way you get the actual business logic separated from the technical file writing logic and structure your code, making it easier to understand.
You could also just write into a giant big String and then write that String in the try-with-resources block. But that has it's limits with really big files and may not be the best choice sometimes.
It is totally OK to put the whole Code into a try-catch routine. Whenever you have issues to write into the file it will just catch it and does not give you an error. However, I would recommend you to try this structure with just one try-catch routine.
try { (FileWriter writer = new FileWriter("filename.txt");
BufferedWriter bw = new BufferedWriter(writer))
for (/*main loop*/){
bw.write(string);
for (/*several sub loops*/){
bw.write(/*more strings*/);
}
for (/*several sub loops*/){
bw.write(/*more strings*/);
}
}
bw.write(/*final string*/);
bw.close();
} catch (IOException e) {
System.out.println("error");
}
PS: If you comment something between some code use this:/* comment */ instead of this:// because it will comment out the whole line.
But if I use try with resources then I'd have to put practically the
entire program inside that try, is this normal?
Thats just how try-catch-with-resources work - it closes resources on exiting try block. If that is bothering you, don't use that construct and you manage writer yourself.
Above skeleton will not work as first try will open and close your writers;
Here is an alternate that does finer exception handling. In many cases, this is preferred. Having a catch block handle too many exceptions gets to be very confusing: Control flow is obscured, and diagnosing errors can be a lot harder.
Having a file open through the entire time a program is running is very usual. This is often the case for log files. If you know your program will be running for a long time, and if you suspect there will be long delays between output to a single file, you could open and close the file for each batch of close in time operations. But you would have to have a clear idea of the pattern of activity to do this, as you will want to match the open time of the file with expected close-in-time batches of writes. You should very much avoid high frequency open and close operations. That has all sorts of unwanted extra overhead.
package my.tests;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.function.Consumer;
public class WriterTest {
public static final String TARGET_NAME = "filename.txt";
public void performMainLoop() {
performWrites( this::mainLoop, TARGET_NAME );
}
public void performWrites( Consumer<Writer> writeActor, String targetName ) {
FileWriter fileWriter;
try {
fileWriter = new FileWriter(targetName);
} catch ( IOException e ) {
System.out.println("Open failure: " + e.getMessage());
e.printStackTrace();
return;
}
BufferedWriter bufferedWriter = null;
try {
bufferedWriter = new BufferedWriter(fileWriter);
writeActor.accept(bufferedWriter);
} finally {
if ( bufferedWriter != null ) {
try {
bufferedWriter.close();
} catch ( IOException e ) {
System.out.println("Unexpected close failure: " + e.getMessage());
e.printStackTrace();
}
} else {
try {
fileWriter.close();
} catch ( IOException e ) {
System.out.println("Unexpected close failure: " + e.getMessage());
e.printStackTrace();
}
}
}
}
public void mainLoop(Writer writer) {
for ( int loopNo = 0; loopNo < 10; loopNo++ ) {
try {
writer.write("Loop [ " + Integer.toString(loopNo) + " ]\n");
} catch ( IOException e ) {
System.out.println("Unexpected write failure: " + e.getMessage());
e.printStackTrace();
return;
}
}
}
}
Well, I am trying to write a line of information to log in a text file (.txt) but this is the part where the code fails to write. Everything else works, except this but doesn't give any errors.
public void writeConfig(File config, Boolean append, String errored){
try {
Writer output;
if (config != null){
output = new BufferedWriter(new FileWriter(config));
} else {
output = new BufferedWriter(new FileWriter(er));
}
if (append == true){
output.append(errored);
} else {
output.write(errored);
}
} catch (Exception e){
try {
loadErrorLog(error, true, "Failed to write to Boom's Log.\n");
} catch (Exception e1){
log.info("Major Malfunction #686 : Tell Maker immediatly.");
}
}
}
You're not closing the writer, which means all the data is just staying in the buffer.
You should close it in a finally block.
Additionally:
your use of the append parameter is distinctly dodgy - you should almost certainly be passing it to the constructor of the FileWriter (or FileOutputStream). I don't think append in Writer does what you think it does.
Try to avoid comparing with true - just if (append) would have been clearer
Using the conditional operator could make your FileWriter code cleaner, especially if you used it just for the file:
File file = config == null ? er : config;
Writer writer = new BufferedWriter(new FileWriter(file));
I would avoid using FileWriter in the first place, as it always uses the platform default encoding. Use a FileOutputStream wrapped in an OutputStreamWriter instead, specifying the encoding explicitly (e.g. UTF-8)
Avoid catching Exception in most places; here it would be cleaner to just catch IOException.
It looks like your loadErrorLog method should probably be doing that logging on failure, otherwise I suspect you'll be writing that block of code every time you call it.
Do you really want to continue if you fail to write the config? Is it definitely this method which should handle the exception? I'd potentially remove the catch block entirely (leaving just a try/finally) and let the IOException bubble up the stack
I am trying to create a file and keep on appending into that file. In my code file is getting created but It is not appending anything in that file. Don't know why? Can anyone suggest me what wrong I am doing..
Updated Code:-
File file =new File("D://GeoData1.txt");
BufferedWriter out = new BufferedWriter(new FileWriter(file, true));
int j = -1;
while(true) {
j++;
String ipAddress = generateIPAddress(j);
try {
out.write(ipAddress);
System.out.println(ipAddress);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
You should close the file or flush buffers I guess.
Are you closing the writer?
finally {
bufferWritter.close();
}
Update:
If you are using Java 7, try this:
final int NUMBER_OF_IPS_TO_APPEND = 5000; // or whatever size
Charset charset = Charset.defaultCharset();
Path file = Paths.get("myfile.txt");
try (BufferedWriter writer = Files.newBufferedWriter(file, charset,
StandardOpenOption.CREATE,
StandardOpenOption.APPEND)) {
for (int i = 1; i <= NUMBER_OF_IPS_TO_APPEND; i++) {
String ip = generateIPAddress(i);
System.out.printf("Generated ip: %s\n", ip);
writer.append(ip + "\n");
}
} catch (IOException x) {
System.err.format("IOException: %s\n", x);
}
Code adapted from The Java Tutorials.
Check if the IPS are being printed to the console and the file.
Fully working code with a mock implementation of generateIPAddress. It appends 5000 random IPv4 addresses (not checking for validity) to myfile.txt everytime it is executed.
I would try just passing the file writer the file object and getting rid of the .getName()
BufferedWriter out = new BufferedWriter(new FileWriter(file, true));
You have infinite loop with while(true). You should make a break point with a statemant or make the the "while" loop like while(i < xy)....
First of all, the loop is never-ending. You should at least make it stop at some point.
Also, you need to close the file to free any memory. Hope it helps!
--edit--
To close a file, its
file.close();
If you want to see the changes made to the file during the time the program is running you need to flush the writer. Please note that sooner or later it will be flushed automatically. The reason why you don't see changes in your text editor depends on your editor. For instance it is not able to open such big file (please note that in your program you are appending chars to this file very fast). Check the size of the file. If the size is increasing then it works.
If you want to monitor the file you can use tools like tail.
I'm having a problem writing to a file:
FileInputStream fin;
try
{
fin = new FileInputStream ("c:/text.txt");
PrintStream p = new PrintStream(fin);
p.println ("test");
fin.close();
}
catch (IOException ioe)
{
System.err.println (ioe.getMessage);
}
Is there a problem with this code?
You need to use a FileOutputStream.
Get used to the following structure. You'll use it a lot in Java.
PrintStream out = null;
try {
out = new PrintStream(new FileOutputStream("c:/text.txt"));
out.println ("test");
} catch (IOException e) {
System.err.println (e.getMessage);
} finally {
if (out != null) {
try { out.close(): } catch (Exception e) { }
}
out = null; // safe but not strictly necessary unless you reuse fin in the same scope
}
At least until ARM blocks hopefully eventuate in Java 7.
As noted, you should close the PrintStream and not the FileOutputStream so the above is a better form to use.
Problems with that code that immediately strike me:
Non-standard formatting.
Awkward variable names.
The exception handling is not good.
Failure to close the file in the case of exceptions. (Use acquire(); try { use(); } finally { release(); }.
Hidden use of default character encoding.
PrintStream swallows exceptions. BufferedOutputStream is better.
Failure to flush the decorator. It may still have data buffered. Although actually in this case you have left the PrintStream in auto-flush mode, which can be a performance issue.
Use / for a Windows path separator. You might be able to get away with it, but it's not good.
So:
FileOutputStream fileOut = new FileOutputStream(
"c:\\text.txt"
);
try {
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
fileOut,
"UTF-8" // Or, say, Charset.defaultCharset()
));
out.write("test");
out.newLine()
out.flush();
} finally {
fileOut.close();
}
The class: FileInputStream is used to read input from a file. If you want to write to the file, you can use: FileOutputStream. If you want to make your life really easy, you can use a BufferedOutputStream as well.
As pointed out, you should close your streams in the finally block. The reason why you want to do that is say your program isn't really small, and it's a larger application. If you forget to close file streams, for example, the application will hold on to it and if you try to do something to it on the file system (read: at least in Windows) you won't be able to it. We've all seen the 'File cannot be deleted because it's still in use' error.
Here's an example of using the FileOutputStream + BufferedOutputStream: http://www.javadb.com/write-to-file-using-bufferedoutputstream.