I have been frustrated for almost 2 days trying to find the flaw because the registry.delete() method does not delete the file "Registry.txt". I'm working with a GUI, and every time I click on a row of a JTable and then click on the "Ban" button, it does not delete the file "Registry.txt", and it does not write either! However, if I do it from another class, like the class that has the main() method, it clears properly. What I wanted to do is delete a line from the Registry.txt, writing in another .txt file all of the lines that did not contain a certain String name, and then rename it to the name Registry.txt. I do not know what is happening. Below is my code:
ActionListener ban = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int fila = table.getSelectedRow();
String nombre = (String) modelo.getValueAt(fila, 0);
modelo.removeRow(fila);
try {
removeUser(nombre);
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
};
btnBanear.addActionListener(ban);
...
public void removeUser(String nombre) throws IOException {
String lee = null;
String usuario = "";
CharSequence aux = nombre;
try {
registro = new File("Registro.txt");
tempFile = new File("Registro1.txt");
lector = new BufferedReader(new FileReader(registro));
fw = new FileWriter(tempFile);
writer = new BufferedWriter(fw);
} catch (FileNotFoundException ex) {
System.out.println(ex.getMessage());
} catch (IOException ex) {
System.out.println(ex.getMessage());
} catch (NullPointerException e) {
System.out.println(e.getMessage());
}
while ((lee = lector.readLine()) != null) {
System.out.println(aux);
if (lee.contains(nombre)) {
continue;
} else {
writer.write(lee);
}
}
lector.close();
fw.close();
writer.close();
registro.delete();
}
I don't think we have quite enough data to see exactly why this is happening, but I can give you some strong suspicions.
File.delete() throws four possible exceptions; three of which apply here. NoSuchFileException (worth specifically checking for), IOException, and SecurityException. NoSuchFileException is derived from IOException and would be caught anyway; though you might want to catch for it still as casting it to an IOException is going to remove relevant data. SecurityException is generally when a security manager gets in the way, which happens all the time on web-based programs. I'm wondering if your file is some kind of an applet or its modern equivalent, the web application? SecurityException is a RuntimeException, so you don't have to catch for it, but you can and probably should. That would explain worlds.
Lastly, you can also use File.deleteIfExists(). This returns a value of true if the file was actually present to be deleted, and false if it could not be found. Worth looking into, because if your path is getting skewed and the file can't be found at the provided location, then it won't be deleted. It's reasonable to think that your program might have a different working directory than you're thinking it does. This is more or less the same as checking for NoSuchFileException, though.
You might even check your working directory, to be sure, with System.out.println(System.getProperty("user.dir")).
My money is on SecurityException or the path being wrong. However, if I'm wrong about this, it would be nice if you could show us your other button code, because there could be a relevant problem there, too.
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;
}
}
}
}
I load a xml content, and save it to the disk. Then I read it, and try to parse.
When I have successfully parsed xml, should I ignore IOException in 7 line?
catch (IOException ignore) {}
Or some problems may occured?
private HashMap <String, VideoDto> loadContent(String url){
try {
BufferedInputStream bStream = httpGateway.loadContents();
cachedContent = xmlParser.parseVideos(bStream);
try {
bStream.close();
} catch (IOException ignore) {}
return cachedContent;
} catch (XMLStreamException e) {
throw new IllegalStateException("I/O error during integration", e);
}
}
public BufferedInputStream loadContents() {
URL source = config.getContentPath();
URL target= config.getLastImportedFile();
try {
ReadableByteChannel rbc = Channels.newChannel(source.openStream());
FileOutputStream fos = new FileOutputStream(target.getFile());
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
} catch (MalformedURLException e) {
throw new IllegalArgumentException("Wrong url format", e);
} catch (IOException e) {
throw new IllegalArgumentException("I/O error while saving "+target, e);
}
return createBufferStream(config.getLastImportedFile());
}
private BufferedInputStream createBufferStream(URL url){
try {
return new BufferedInputStream(url.openConnection().getInputStream());
} catch (IOException e) {
throw new IllegalArgumentException(e);
}
}
There are three parts to this question:
Q1: Should one ever ignore (squash) an exception?
I think that the answer is ... "it depends".
If the exception cause is known AND it you can catch it precisely (i.e. without also catching exceptions with different causes) AND the correct thing to do is to ignore it then ... IMO ... Yes it is acceptable.
Otherwise. No.
Q2: What does and IOException mean in this case, and does it matter?
The answer is that it is not at all clear. Under normal circumstances, one would not expect an IOException when closing an input stream, and it is hard to know what it might mean. Intuitively it is probably harmless. On the other hand, if you don't know what might cause something it is hard to say whether or not it matters.
Q3: Should you simply ignore this IOException?
I would say no. But I would handle it like this:
} catch (IOException ex) {
// possibly log the exception here.
throw new AssertionError("Unexpected exception", ex);
}
The rationale is that if something totally unexpected does occur, then it would be a good thing if the developer / maintainer could find out, and figure out how to deal with it.
On the other hand, if you could make an a priori assessment that any IOException here is harmless, then simply logging (or even squashing) it might be sufficient.
Never ignore exceptions, even if nothing goes wrong. This is the seed of bugs.
The desired thing to do, if you don't need any actions to be done, is, print its stack trace.
e.printStackTrace();
You may ignore that at any time, but may help you in the long run.
Use the try syntax that exists since Java 7:
try (BufferedInputStream bStream = httpGateway.loadContents();) {
cachedContent = xmlParser.parseVideos(bStream);
}
With this you don't have to call .close() manually.
You should catch all exceptions that are thrown inside the try block, though.
This means that the stream will (probably) still be open, whether that is a problem in your program only you will know. At the very least you should log the exception, otherwise you might get strange results that are hard to detect.
You might also want to look at the try-with-resources syntax which doesn't pose this dilemma:
try (BufferedInputStream bStream = httpGateway.loadContents()) {
cachedContent = xmlParser.parseVideos(bStream);
}
In Effective Java Joshua Bloch gives this as an example of an exception you might want to log and ignore. He says, however, that in general you want to do more than just logging an exception.
I wrote a object using ObjectOutputStream, and read it using ObjectInputStream, and tested it , I get the expected result. But when write the object in other machine, read it in my computer, the read object's members are empty. Could someone help me? thanks
public class TrustNet implements Serializable{
public double[][] trusts;
public double avg = 0;
public TrustNet(int size){
trusts = new double[size][size];
}
public void writeToFile(String fileName){
try(ObjectOutputStream writer = new ObjectOutputStream(new FileOutputStream(fileName))){
writer.writeObject(this);
writer.flush();
} catch (IOException ex) {
ex.printStackTrace();
}
}
public static TrustNet readFromFile(String fileName){
try(ObjectInputStream writer = new ObjectInputStream(new FileInputStream(fileName))){
return (TrustNet) writer.readObject();
} catch (IOException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
return null;
}
}
It took me a day to figure out what's going on. I think I finally have the answer. May be it will help other people having similar problem.
In my case, the problem was due of using ProGuard.
ProGuard minifyed the code, giving new shorts names to fields, like
a, b, c, etc.
When serializing, the names of fields get stored into the stream. When reading the stream, the names must match.
When I minifyed code the last time (for the new Production version of the app), ProGuard gave different names to fields (in my case it
was due of changed ProGuard settings, but may be due of other
reasons too, not sure if ProGuard guarantee the same names every
time).
As result, when I deserialize the object in the new version, because of the names are not match, all the fields set to default values.
I have the following code in a java Web Service:
public boolean makeFile(String fileName, String audio)
{
if (makeUserFolder())
{
File file = new File(getUserFolderPath() + fileName + amr);
FileOutputStream fileOutputStream = null;
try
{
file.createNewFile();
fileOutputStream = new FileOutputStream(file);
fileOutputStream.write(Base64.decode(audio));
return true;
}
catch(FileNotFoundException ex)
{
return false;
}
catch(IOException ex)
{
return false;
}
finally{
try {
fileOutputStream.close();
convertFile(fileName);
} catch (IOException ex) {
Logger.getLogger(FileUtils.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
else
return false;
}
public boolean convertFile(String fileName)
{
Process ffmpeg;
String filePath = this.userFolderPath + fileName;
try {
ProcessBuilder pb = new ProcessBuilder("ffmpeg","-i",filePath + amr,filePath + mp3);
pb.redirectErrorStream();
ffmpeg = pb.start();
} catch (IOException ex) {
return false;
}
return true;
}
It used to work and now it simply won't execute the ffmpeg conversion for some reason. I thought it was a problem with my file but after running the command from terminal no errors are thrown or anything, thought it was maybe permissions issue but all the permissions have been granted in the folder I'm saving the files. I noticed that the input BufferedReader ins being set to null after running the process, any idea what's happening?
First of all, a small nitpick with your code...when you create the FileOutputStream you create it using a string rather than a File, when you have already created the File before, so you might as well recycle that rather than force the FileOutputStream to instantiate the File itself.
Another small nitpick is the fact that when you are writing out the audio file, you should enclose that in a try block and close the output stream in a finally block. If you are allowed to add a new library to your project, you might use Guava which has a method Files.write(byte[],File), which will take care of all the dirty resource management for you.
The only thing that I can see that looks like a definite bug is the fact that you are ignoring the error stream of ffmpeg. If you are blocking waiting for input on the stdout of ffmpeg, then it will not work.
The easiest way to take care of this bug is to use ProcessBuilder instead of Runtime.
ProcessBuilder pb = new ProcessBuilder("ffmpeg","-i",filePath+amr,filePath+mp3);
pb.redirectErrorStream(); // This will make both stdout and stderr be redirected to process.getInputStream();
ffmpeg = pb.start();
If you start it this way, then your current code will be able to read both input streams fully. It is possible that the stderr was hiding some error that you were not able to see due to not reading it.
If that was not your problem, I would recommend using absolute paths with ffmpeg...in other words:
String lastdot = file.getName().lastIndexOf('.');
File mp3file = new File(file.getParentFile(),file.getName().substring(0,lastdot)+".mp3");
ProcessBuilder pb = new ProcessBuilder("ffmpeg","-i",file.getAbsolutePath(),mp3file.getAbsolutePath());
// ...
If that doesn't work, I would change ffmpeg to be an absolute path as well (in order to rule out path issues).
Edit: Further suggestions.
I would personally refactor the writing code into its own method, so that you can use it elsewhere necessary. In other other words:
public static boolean write(byte[] content, File to) {
FileOutputStream fos = new FileOutputStream(to);
try {
fos.write(content);
} catch (IOException io) {
// logging code here
return false;
} finally {
closeQuietly(fos);
}
return true;
}
public static void closeQuietly(Closeable toClose) {
if ( toClose == null ) { return; }
try {
toClose.close();
} catch (IOException e) {
// logging code here
}
}
The reason that I made the closeQuietly(Closeable) method is due to the fact that if you do not close it in that way, there is a possibility that an exception will be thrown by the close() method, and that exception will obscure the exception that was thrown originally. If you put these in a utility class (although looking at your code, I assume that the class that it is currently in is named FileUtils), then you will be able to use them throughout your application whenever you need to deal with file output.
This will allow you to rewrite the block as:
File file = new File(getUserFolderPath() + fileName + amr);
file.createNewFile()
write(Base64.decode(audio),file);
convertFile(fileName);
I don't know whether or not you should do this, however if you want to be sure that the ffmpeg process has completed, then you should say ffmpeg.waitFor(); to be sure that it has completed. If you do that, then you should examine ffmpeg.exitValue(); to make sure that it completed successfully.
Another thing that you might want to do is once it has completed, write what it output to a log file so you have a record of what happened, just in case something happens.