Unable to delete text file using delete() - java

I am trying to transfer the data from old textfile to new textfile. Although the code below is able to transfer successfully, it does not delete the old textfile. May I know why is this so?
private void dataTransfer(String oldFilePath, String newFilePath) {
byte[] buffer = new byte[10000];
try {
FileInputStream fileInput = new FileInputStream(oldFilePath);
BufferedInputStream bufferedInput = new BufferedInputStream(fileInput);
FileOutputStream fileOutput = new FileOutputStream(newFilePath);
BufferedOutputStream bufferedOutput = new BufferedOutputStream(fileOutput);
while(true) {
int length = fileInput.read(buffer);
if(length == -1) {
break;
} else {
bufferedOutput.write(buffer);
bufferedOutput.flush();
}
}
fileInput.close();
bufferedInput.close();
fileOutput.close();
bufferedOutput.close();
File oldFile = new File(oldFilePath);
oldFile.delete();
} catch (IOException e) {
e.printStackTrace();
System.out.println(ERROR_TRANSFER_DATA);
}
}

Update the JRE and JDK, make sure you have the rights on the file. Try with a file created by you.
Also, add a catch block for SecurityException

For deleting a file it should work fine but for deleting a directory you have to make sure that Directory is Empty.

You can use the following code block. It works, though don't know. Even without setWritable, it works,
oldFile.setWritable(true);
if(!oldFile.delete()){
System.out.println("de;eted");
}

According to Oracle's docs, the delete method does not guarantee that it will delete the file.
http://docs.oracle.com/javase/7/docs/api/java/io/File.html#delete()
Deleting a file will fail if:
file does not exist
there is a lock on that file it might be opened by another process
file does not exist on the disk
you don't have enough permissions to delete that file (in this case a SecurityException is thrown)

I agree with #panagdu that you might not have sufficient rights to delete the file.
Just as a fluke try closing bufferedStream before fileInputStream
like
bufferedInput.close();
fileInput.close();
bufferedOutput.close();
fileOutput.close();
But I don't think this will help.
Test your code for files with sufficient permission. For example Java does not allow the delete() for system files.

Related

FileOutputStream(FileDescriptor) that overwrites instead of appending data?

Im writing to a file through a FileOutputStream that is opened via its constructor taking a FileDescriptor.
My desired behavior: When I write to the file I want that to be the only content of it. E.g. writing "Hello" should result in the file containing just "Hello".
Actual behavior: Each time I write something, it is simply appeneded. E.g. in the above example I will get "HelloHello".
How can I open a FileOutputStream like Im doing, and have it not be in append mode?
Note: I am forced to use a FileDescriptor.
According to the ContentProvider.java file documentation, you can use "rwt" mode to read and write in file in truncating it.
ParcelFileDescriptor pfd = context.getContentResolver.openFileDescriptor(uri, "rwt");
FileOutputStream fos = new FileOutputStream(pfd.getFileDescriptor());
#param mode Access mode for the file. May be "r" for read-only access,
"rw" for read and write access, or "rwt" for read and write access
that truncates any existing file.
Hope this help despite that the question was posted a long time ago.
If you use FileOutoutStream then the ctor provides an option for you to specify whether you want to open the file to append or not. Set it to false and it will work.
OutputStream out = null;
try {
out = new FileOutputStream("OutFile", false);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
FileOutputStream(File file, boolean append)
Make the argument append to false, so it overrides the existing data everytime when you call.
https://docs.oracle.com/javase/7/docs/api/java/io/FileOutputStream.html#FileOutputStream(java.io.File,%20boolean)
FileOutputStream outputStream;
try {
outputStream = openFileOutput("your_file", Context.MODE_PRIVATE);
//Context.MODE_PRIVATE -> override / MODE_APPEND -> append
outputStream.write("your content");
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}

How to make a copy of a file containing images and text using java

I have some word documents and excel sheets which has some images along with the file text content. I want to create a copy of that file and keep it at a specific location. I tried the following method which is creating file at specified location but the file is corrupted and cannot be read.
InputStream document = Thread.currentThread().getContextClassLoader().getResourceAsStream("upgradeworkbench/Resources/Upgrade_TD_Template.docx");
try {
OutputStream outStream = null;
Stage stage = new Stage();
stage.setTitle("Save");
byte[] buffer= new byte[document.available()];
document.read(buffer);
FileChooser fileChooser = new FileChooser();
fileChooser.setInitialFileName(initialFileName);
if (flag) {
fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("Microsoft Excel Worksheet", "*.xls"));
} else {
fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("Microsoft Word Document", "*.docx"));
}
fileChooser.setTitle("Save File");
File file = fileChooser.showSaveDialog(stage);
if (file != null) {
outStream = new FileOutputStream(file);
outStream.write(buffer);
// IOUtils.copy(document, outStream);
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
Can anyone suggest me any different ways to get the proper file.
PS: I am reading the file using InputStream because it is inside the project jar.
PPS: I also tried Files.copy() but it didnt work.
I suggest you never trust on InputStream.available to know the real size of the input, because it just returns the number of bytes ready to be immediately read from the buffer. It might return a small number, but doesn't mean the file is small, but that the buffer is temporarily half-full.
The right algorithm to read an InputStream fully and write it over an OutputStream is this:
int n;
byte[] buffer=new byte[4096];
do
{
n=input.read(buffer);
if (n>0)
{
output.write(buffer, 0, n);
}
}
while (n>=0);
You can use the Files.copy() methods.
Copies all bytes from an input stream to a file. On return, the input stream will be at end of stream.
Use:
Files.copy(document, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
As the class says, the second argument is a Path, not a File.
Generally, since this is 2015, use Path and drop File; if an API still uses File, make it so that it uses it at the last possible moment and use Path all the way.

jcifs.smb.SmbException: Access is Denied. exception for smb directories

In the below code statement:
SmbFileInputStream din==new SmbFileInputStream(src);
I am trying to create a SmbFileInputStream object. This will works fine if SmbFile 'src' is a file, but if 'src' is a smb Directory then it throws exception:
jcifs.smb.SmbException: Access is Denied.
at jcifs.smb.SmbTransport.checkStatus(SmbTransport.java:622)
at jcifs.smb.SmbTransport.send(SmbTransport.java:722)
at jcifs.smb.SmbSession.send(SmbSession.java:262)
at jcifs.smb.SmbTree.send(SmbTree.java:119)
at jcifs.smb.SmbFile.send(SmbFile.java:785)
at jcifs.smb.SmbFile.open0(SmbFile.java:1009)
at jcifs.smb.SmbFile.open(SmbFile.java:1026)
at jcifs.smb.SmbFileInputStream.<init>(SmbFileInputStream.java:73)
at jcifs.smb.SmbFileInputStream.<init>(SmbFileInputStream.java:65)
at testhelp.main(testhelp.java:25)
What is wrong with this code? or where am I going wrong?
Hi please check this code:
case DOWNLOAD2:
/*This code snippet is used to download a file/folder from smb nETWORK to android sd card.
when I run this code its throwing some exception. It have commented where ever necessary. rest of the code is self
explanatory. So please go through the code and please tell why this exception is thrown.
IF POSSIBLE PLEASE ADD A PROGRESS BAR WHICH SHOULD HELP USER SAYING SOME WORK IS GOING ON.
I have tried including a progress bar, but its not working. I ve read some materials related to this,
but every thing makes use threads. I am not that good at threads. So is it possible to include a progess bar,
without using threads?If possible please help me to do it.
And this code is working file for smb files, I dont know why its throwing exception in case of directories.
Please see why this is throwing exception..
So please see that the modified code contains:
a)no exceptions
b)a progress bar(more specifically a horizontal bar)*/
/*exception thrown:
jcifs.smb.SmbException: Access is Denied.
at jcifs.smb.SmbTransport.checkStatus(SmbTransport.java:622)
at jcifs.smb.SmbTransport.send(SmbTransport.java:722)
at jcifs.smb.SmbSession.send(SmbSession.java:262)
at jcifs.smb.SmbTree.send(SmbTree.java:119)
at jcifs.smb.SmbFile.send(SmbFile.java:785)
at jcifs.smb.SmbFile.open0(SmbFile.java:1009)
at jcifs.smb.SmbFile.open(SmbFile.java:1026)
at jcifs.smb.SmbFileInputStream.<init>(SmbFileInputStream.java:73)
at jcifs.smb.SmbFileInputStream.<init>(SmbFileInputStream.java:65)
at testhelp.main(testhelp.java:25)*/
StatFs statFs = new StatFs(Environment.getExternalStorageDirectory().getAbsolutePath());
//if sd card is mounted then only this operation occur:
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
{
//object.getCount() gets the number of objects in list view
for(int i=0;i<object.getCount();i++)
{
//for each object in list view, if it is checked:
if(object.getter(i)==true)
{
SmbFileInputStream din=null;
FileOutputStream dout=null;
try
{
//I have used a hash table, which maps list view name with smb object
SmbFile src=map.get(object.getItem(i));
long blockSize = statFs.getBlockSize();
long freeSize = statFs.getFreeBlocks()*blockSize;
long diff=freeSize-src.length();
boolean can=false;
if(!(diff<0))
{
can=true;
}
if(!src.isHidden() && can)
{
try
{
if(src.isFile())
{
din=new SmbFileInputStream(src);
dout=new FileOutputStream(Environment.getExternalStorageDirectory()+"/"+src.getName());
}
else
{
din=new SmbFileInputStream(src);
File outputFile = new File(Environment.getExternalStorageDirectory()+"/"+src.getName()); // ADDED
outputFile.mkdirs(); // ADDED
dout=new FileOutputStream(outputFile); // CHANGED
}
int c;
while((c=din.read())!=-1)
{
dout.write(c);
}
}
finally
{
if (din != null)
{
din.close();
}
if (dout != null)
{
dout.close();
}
}
}
else
{
Toast.makeText(this,src.getName()+" cannot be downloaded",Toast.LENGTH_LONG).show();
}
}
catch(IOException e)
{
Toast.makeText(this,"DOWNLOAD FAILED--IO EXCEPTION\n"+e,Toast.LENGTH_LONG).show();
}
}
}
}
else
{
Toast.makeText(this,"DOWNLOAD FAILED--NO SD CARD FOUND",Toast.LENGTH_LONG).show();
}
return true;
You can't create an SmbFileInputStream for a directory, because you can't read/write directly to the directory object. A directory doesn't have any content, at least not in the same way that a file has content.
If you're trying to read the contents of a directory, you should probably be using SmbFile instead (for example, use the listFiles() method). The SmbFileInputStream object is only for reading information from a file.
To write a file to a directory, do this...
File file = new File("/mnt/sdcard/filename.txt");
file.mkdirs(); // this creates all the directories that are missing
FileOutputStream os = new FileOutputStream (file);
// now write the file data
os.write(...);
In your code, change the following few lines...
try
{
din=new SmbFileInputStream(src);
dout=new FileOutputStream(Environment.getExternalStorageDirectory()+"/"+src.getName());
int c;
while((c=din.read())!=-1)
To this...
try
{
din=new SmbFileInputStream(src);
File outputFile = new File(Environment.getExternalStorageDirectory()+"/"+src.getName()); // ADDED
outputFile.mkdirs(); // ADDED
dout=new FileOutputStream(outputFile); // CHANGED
int c;
while((c=din.read())!=-1)
Also change the following...
if(src.isFile()){
din=new SmbFileInputStream(src);
//dout=new FileOutputStream(Environment.getExternalStorageDirectory()+"/"+src.getName());// REMOVE THIS LINE
File outputFile = new File(Environment.getExternalStorageDirectory()+"/"+src.getName()); // ADDED
outputFile.mkdirs(); // ADDED
dout=new FileOutputStream(outputFile); // ADDED
}
else {
//din=new SmbFileInputStream(src); // REMOVE THIS LINE
File outputFile = new File(Environment.getExternalStorageDirectory()+"/"+src.getName());
outputFile.mkdirs();
//dout=new FileOutputStream(outputFile); // REMOVE THIS LINE
}

File Delete and Rename in Java

I have the following Java code which will search in an xml for a specific tag and then will add some text to it and save that file. I couldnt find a way to rename the emporary file to the original file. Please suggest.
import java.io.*;
class ModifyXML {
public void readMyFile(String inputLine) throws Exception
{
String record = "";
File outFile = new File("tempFile.tmp");
FileInputStream fis = new FileInputStream("InfectiousDisease.xml");
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
FileOutputStream fos = new FileOutputStream(outFile);
PrintWriter out = new PrintWriter(fos);
while ( (record=br.readLine()) != null )
{
if(record.endsWith("<add-info>"))
{
out.println(" "+"<add-info>");
out.println(" "+inputLine);
}
else
{
out.println(record);
}
}
out.flush();
out.close();
br.close();
//Also we need to delete the original file
//outFile.renameTo(InfectiousDisease.xml);//Not working
}
public static void main (String[] args) {
try
{
ModifyXML f = new ModifyXML();
f.readMyFile("This is infectious disease data");
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
Thanks
First delete the original file and then rename the new file:
File inputFile = new File("InfectiousDisease.xml");
File outFile = new File("tempFile.tmp");
if(inputFile.delete()){
outFile.renameTo(inputFile);
}
A good method to rename files is.
File file = new File("path-here");
file.renameTo(new File("new path here"));
In your code there are several issues.
First your description mentions renameing the original file and adding some text to it. Your code doesn't do that, it opens two files, one for reading and one for writing (with the additional text). That is the right way to do things, as adding text in-place is not really feasible using the techniques you are using.
The second issue is that you are opening a temporary file. Temporary files remove themselves upon closing, so all the work you did adding your text disappears as soon as you close the file.
The third issue is that you are modifying XML files as plain text. This sometimes works as XML files are a subset of plain text files, but there is no indication that you attempted to ensure that the output file was an XML file. Perhaps you know more about your input files than is mentioned, but if you want this to work correctly for 100% of the input cases, you probably want to create a SAX writer that writes out all a SAX reader reads, with the additional information in the correct tag location.
You can use
outFile.renameTo(new File(newFileName));
You have to ensure these files are not open at the time.

Creating a file is causing problem, the File.getPath() doesn't seem to work

I am trying to create a back up file for an html file on a web server.
I want the backup to be in the same location as the existing file (it's a quick fix). I want to create the file using File file = new File(PathName);
public void backUpOldPage(String oldContent) throws IOException{
// this.uri is a class variable with the path of the file to be backed up
String fileName = new File(this.uri).getName();
String pathName = new File(this.uri).getPath();
System.out.println(pathName);
String bckPath = pathName+"\\"+bckName;
FileOutputStream fout;
try
{
// Open an output stream
fout = new FileOutputStream (bckFile);
fout.close();
}
// Catches any error conditions
catch (IOException e)
{
System.err.println ("Unable to write to file");
System.exit(-1);
}
}
But if instead I was to set bckPath like this, it will work.
String bckPath = "C://dev/server/tomcat6/webapps/sample-site/index_sdjf---sd.html";
I am working on Windows, not sure if that makes a difference.
The result of String bckPath = pathName+"\"+bckName;
is bckPath = C:\dev\server\tomcat6\webapps\sample-site\filename.html - this doesn't result in a new file.
Use File.pathSeparator, that way you dont need to worry what OS you are using.
Try to use File.getCanonicalPath() instead of plain getPath(). This helps if the orginal path is not fully specified.
Regarding slashes, / or \ or File.pathSeparator is not causing the problem, because they are all the same on Windows and Java. (And you do not define bckFile in your code, only bckPath. Also use getCanonicalPath() on the new created bckPath.)

Categories

Resources