how can you delete a sound file in java? - java

I have a sound file that's recorded in my Java code and I need some code to delete it.

What is so special about sound file??!!!
You can use this code.
public static void deleteFile(String file){
File myFile = new File(file);
if (!myFile.delete()){
System.out.println("Deletion was not sucessful");
}else{
System.out.println("File deleted");
}
}

Since the answer is so obvious (file.delete()), I suspect that you're actually having issues with deleting it. I.e, file.delete() has returned false and the file is in reality not been deleted from the disk file system.
In that case, you can not delete it when you still have pointers open on that file. For example, when you have a InputStream or OutputStream on the file in your Java code, then you will not be able to delete the file as long as you do not call close() on the streams.
So, to fix that issue, you need to ensure that you call close() on any InputStream and OutputStream in the finally block of the try block where you're using the streams.
E.g.
File file = new File(name);
OutputStream output = null;
try {
output = new FileOutputStream(file);
// Write to output here ...
file.delete(); // Will always fail because output is not closed.
} finally {
if (output != null) try { output.close(); } catch (IOException logOrIgnore) {}
}
file.delete(); // Will succeed after close of output.

Related

Error where FileOutputStream only writes to file after the program has been terminated

I've had this error in the past but never fully understood it. After closing an OutputStream, regardless of the location of the java file or the manner in which it is called, completely screws up all sequential runs or attempts to write to another file, even if a different method of writing to a file is used. For this reason I avoid closing streams even though it is a horrible habit not to. In my program, I created was trying a test case that had a close statement which destroyed all of my previous streams, making it for some reason that they only write to files after the program has been terminated.
I kept the file location open and it writes the Text in the text file at the appropriate time, however the "Preview" panel in Windows does not detect it (which used to happen). Note that this all worked perfectly before the stream was accidentally closed. Is there a manner to reset the stream? I've tried flushing it during the process but is still does not run as it did prior.
Here is the method used to create the file:
protected void createFile(String fileName, String content) {
try {
String fileLoc = PATH + fileName + ".txt";
File f = new File(fileLoc);
if(!f.isFile())
f.createNewFile();
FileOutputStream outputStream = new FileOutputStream(fileLoc);
byte[] strToBytes = content.getBytes();
outputStream.write(strToBytes);
} catch (IOException e) {
e.printStackTrace();
return;
}
}
as well as the method used to read the file:
protected String readFile(String fileName) {
try {
StringBuilder sb = new StringBuilder("");
String fileLoc = PATH + fileName + ".txt";
File f = new File(fileLoc);
if(!f.exists())
return "null";
Scanner s = new Scanner(f);
int c = 0;
while(s.hasNext()) {
String str = s.nextLine();
sb.append(str);
if(s.hasNext())
sb.append("\n");
}
return sb.toString();
} catch(Exception e) {
e.printStackTrace();
return "null";
}
}
I'd be happy to answer any clarification questions if needed. Thank you for the assistance.
without try-resource, you need close in final clause to make sure no leak. Or use Stream.flush() if you need more 'in-time' update.
} catch (IOException e) {
e.printStackTrace();
return;
} finally {
outputStream.close();
}
You need to call flush() on the stream to write the bytes to the stream.
You're currently calling write() by itself, like this:
FileOutputStream outputStream = new FileOutputStream(fileLoc);
outputStream.write(content.getBytes());
What you want to do is this:
FileOutputStream outputStream = new FileOutputStream(fileLoc);
outputStream.write(content.getBytes());
outputStream.flush();
From the Javadoc (https://docs.oracle.com/javase/8/docs/api/java/io/OutputStream.html#flush--) for OutputStream (where FileOutputStream is an OutputStream), this is what it says for flush():
Flushes this output stream and forces any buffered output bytes to be written out. The general contract of flush is that calling it is an indication that, if any bytes previously written have been buffered by the implementation of the output stream, such bytes should immediately be written to their intended destination.
Even better would be to close the stream in a finally block, so that no matter what your code always tries to free up any open resources, like this:
FileOutputStream outputStream = null;
try {
outputStream = new FileOutputStream(fileLoc);
outputStream.write(content.getBytes());
outputStream.flush();
} finally {
if (outputStream != null) {
outputStream.close();
}
}
or use automatic resource management, like this:
try (FileOutputStream outputStream = new FileOutputStream(fileLoc)) {
outputStream.write(content.getBytes());
outputStream.flush();
}

Temporary File not deleted on close

I'm using Java in a really big application and some time i have to use temp file. Those file i want to be deleted at the application close, this is a simple snapshot i'm using:
File tempFile = File.createTempFile("sign_", "tmp.pdf");
tempFile.deleteOnExit();
I'm not reporting all the code since is really big and i have many class working each other. I would know which could be the reason that avoid the delete on closure of certain file (some file are deleted other not, but they came always from the same piece of code the one that are not deleted).
Edit: i have already read this example but i think i need some "theoric" motivation and not code example to find the reason.
The method "deleteOnExit()" only works if the VM terminates normally. If the VM crash or forced termination the file might remain undeleted.
I don't know how it is implemented, but you could try to put the tempFile.deleteOnExit() inside the finally.
File tempFile = null;
try{
tempFile = File.createTempFile("sign_", "tmp.pdf");
}catch(IOException e){
e.printStackTrace();
} finally {
if (tempFile != null) {
tempFile.deleteOnExit();
tempFile = null;
//Added a call to suggest the Garbage Collector
//To collect the reference and remove
System.gc();
}
}
Or maybe, close all the references to the file and then call "File.delete()" to delete immediate.
If anyone is working, problably some reference to the file exists. In this way, you can try to force the file to be deleted using the org.apache.commons.io.FileUtils.
Example org.apache.commons.io.FileUtils:
File tempFile = null;
try{
tempFile = File.createTempFile("sign_", "tmp.pdf");
}catch(IOException e){
e.printStackTrace();
} finally {
if (tempFile != null) {
FileUtils.forceDelete(tempFile);
System.out.println("File deleted");
}
}
Example org.apache.commons.io.FileDeleteStrategy:
File tempFile = null;
try{
tempFile = File.createTempFile("sign_", "tmp.pdf");
}catch(IOException e){
e.printStackTrace();
} finally {
if (tempFile != null) {
FileDeleteStrategy.FORCE.delete(tempFile);
System.out.println("File deleted");
}
}

Writing to an External File on Android --- File Doesn't Register, But Java Can Read

I'm trying to write to an external txt (or csv) file for Android. I can run an app, close it, and run it again, and readData() will read back to my log what I've stored. However, the dirFile (file directory) appears nowhere within my Android files (even if I connect it to a computer and search).
Something interesting, though: if I clear my log (similar to a list of print statements shown within Eclipse) and disconnect my phone from my computer, then reconnect it, the log reappears with everything I've ever written to my file (even if I later overwrote it)...yet the app isn't even running!
Here is my code. Please help me understand why I cannot find my file!
(Note: I've tried appending a "myFile.txt" extension to the directory, but it just causes an EISDIR exception.)
public void writeData(String dirName){
try
{
File root = new File(getExternalFilesDir(null), dirName);
// Writes to file
//
// The "true" argument allows the file to be appended. Without this argument (just root),
// the file will be overwritten (even though we later call append) rather than appended to.
FileWriter writer = new FileWriter(root, true);
writer.append("Append This Text\n");
writer.flush();
writer.close();
// Checks if we actually wrote to file by reading it back in (appears in Log)
//readData(dirName);
}
catch(Exception e)
{
Log.v("2222", "2222 ERROR: " + e.getMessage());
}
}
If you're interested, here's the function I wrote to read in the data:
public void readData(String dirName){
try
{
File root = new File(getExternalFilesDir(null), dirName);
// Checks to see if we are actually writing to file by reading in the file
BufferedReader reader = new BufferedReader(new FileReader(root));
try {
String s = reader.readLine();
while (s != null) {
Log.v("2222", "2222 READ: " + s);
s = reader.readLine();
}
}
catch(Exception e) {
Log.v("2222", "2222 ERROR: " + e.getMessage());
}
finally {
reader.close();
}
}
catch(Exception e) {
Log.v("2222", "2222 ERROR: " + e.getMessage());
}
}
Thanks!
even if I connect it to a computer and search
if I clear my log (similar to a list of print statements shown within Eclipse) and disconnect my phone from my computer, then reconnect it, the log reappears with everything I've ever written to my file (even if I later overwrote it).
What you are seeing on your computer is what is indexed by MediaStore, and possibly a subset of those, depending upon whether your computer caches information it gets from the device in terms of "directory" contents.
To help ensure that MediaStore indexes your file promptly:
Use a FileOutputStream (optionally wrapped in an OutputStreamWriter), not a FileWriter
Call flush(), getFD().sync(), and close() on the FileOutputStream, instead of calling flush() and close() on the FileWriter (sync() will ensure the bytes are written to disk before continuing)
Use MediaScannerConnection and scanFile() to tell MediaStore to index your file
You can then use whatever sort of "reload" or "refresh" or whatever option is in your desktop OS's file manager, and your file should show up.
This blog post has more on all of this.
public void create(){
folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES),"video");
boolean success = true;
if (!folder.exists()) {
success=folder.mkdirs();
}
if (success) {
readfile();
} else {
System.out.println("failed");
}
}
The above code will be used to crete the directory in th emobile at desired path
private void readfile() {
// TODO Auto-generated method stub
AssetManager assetManager = getResources().getAssets();
String[] files = null;
try {
files = assetManager.list("clipart");
} catch (Exception e) {
Log.e("read clipart ERROR", e.toString());
e.printStackTrace();
}
for(String filename : files) {
System.out.println("File name => "+filename);
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open("clipart/" + filename);
out = new FileOutputStream(folder + "/" + filename);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch(Exception e) {
Log.e("copy clipart ERROR", e.toString());
e.printStackTrace();
}
}}private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}}
this is my code used to write file in internal memory from the assets folder in project. This code can read all type(extension) of file from asset folder to mobile.
Don't forget to add permission in manifest file
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
and call the above function by
readfile();//this call the function to read and write the file
I hope this may help you.
Thank you.

writing to a file, but not just at the end

I want to write something to a file line by line.
I have the problem, that this process takes a lot of time and get canceld sometimes. The current version write the stuff to the file just at the end. Is it possible to write it to the file line by line?
E.g. if I abboard after line 4 (of 400) the file currently is empty. But I want to have the 4 line already in the file.
Here is my code:
String path = args[0];
String filename = args[1];
BufferedReader bufRdr = // this does not matter
BufferedWriter out = null;
FileWriter fstream;
try {
fstream = new FileWriter(path + "Temp_" + filename);
out = new BufferedWriter(fstream);
} catch (IOException e) {
System.out.println(e.toString());
}
String line = null;
try {
while ((line = bufRdr.readLine()) != null) {
// HERE I'm doing the writing with out.write
out.write(...);
}
} catch (IOException e) {
System.out.println(e.toString());
}
try {
out.close();
} catch (IOException e) {
System.out.println(e.toString());
}
Use the flush function when you want to make sure the data that is already been written to the writer gets into the file
out.flush()
Try out.flush() after out.write(...)
Use out.flush() after calling out.write(...).
Considering the java documentation FileWriter, you can directly write things to a file using the FileWriter, without using a BufferedWriter.
Also, as pointed out, you need to flush your datas before closing your buffer. The function write only fill your buffer, but it doesn't write to the file on the disk. This operation is done by using flush or close (to write the current content of the buffer to the disk). The difference between these two functions is that flush let's you write things after and close closes the stream definitely.
The data you write to the buffer normally will not actually be written until out.flush() or out.close() is closed. so for your requirement you should use out.flush();

Inputstream and Outputstream with reading a list of files

I have this ArrayList files
for(File file : files){
InputStream in = FileInputStream(file);
// process each file and save it to file
OutputStream out = FileOutputStream(file);
try{
} finally {
in.close();
out.close();
}
}
the performance is really slow since every loop there is a in/out close(), is there a better way to do this? I tried to put outputstream oustide of the loop, it doesn't work.
Using buffered streams makes a huge difference.
Try this:
for(final File file : files) {
final InputStream in = new BufferedInputStream(new FileInputStream(file));
final OutputStream out = new BufferedOutputStream(new FileOutputStream(new File(...)));
try {
// Process each file and save it to file
}
finally {
try {
in.close();
}
catch (IOException ignored) {}
try {
out.close();
}
catch (IOException ignored) {}
}
}
Note that the IOExceptions that can be thrown when closing the streams must be ignored, or you will lose the potential initial exception.
Another problem is that both streams are on the same file, which doesn't work. So I suppose you're using two different files.
A close() can take up to 20 ms. I doubt this is your program unless you have 1000's of files.
I suspect your performance problem is a lack of buffering the input and output. Can you show your buffering wrappers as well?
you can of course build a queue of OutputStreams and offload that to a background thread that handles the closing of these outputstreams. Same for InputStreams.
Alternatively you can leave it down to the JVM to do that -- simply don't close the files and leave it to the GC to do that when objects are finalized.

Categories

Resources