I am trying to rename an existing fileSrc(i.e. old_file.pdf) to another name (i.e. new_file.pdf). However the renameTo() method returns always false. I have read that its advised to check first if the original file is open (i.e. locked) and if the destination file does not exist. Here is my source code :
File fileSrc = new File("old_file.pdf");
FileOutputStream fos = null;
try {
fos = new FileOutputStream(fileSrc);
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} finally {
if(fos!=null)
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
File fileDst = new File("new_file.pdf");
if(fileDst.exists()) {
fileDst.delete();
}
boolean b = fileSrc.renameTo(fileDst);
System.out.println("check : "+b);//b is always set to false
P.S. I am using Windows 7 for my development environment and UNIX Debian for the production environment.
Related
I am making a save/load feature for the settings in my application. Upon launching the program, it tries to find the file. If it fails, it tries to create a file with default settings (code below)
try (FileWriter fileWriter = new FileWriter(absolutePath))
{
fileWriter.write("theme=light\n");
fileWriter.write("resolution=1280x720\n");
fileWriter.write("printfps=false\n");
System.out.println("Reset settings");
load();
}
catch (FileNotFoundException e)
{
System.out.println("Settings File not found.");
}
catch (IOException e)
{
e.printStackTrace();
}
After it has written this, it goes on to load the file. (calling load() method)
In the load method, the application reads the contents of the file (code below).
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(absolutePath)))
{
String line = bufferedReader.readLine();
System.out.println(line);
while(line != null)
{
if (line.contains("="))
{
String key = line;
String value = line;
while (key.contains("="))
{
key = key.substring(0, key.length() - 1);
}
while (value.contains("="))
{
value = value.substring(1);
}
settings.put(key, value);
}
System.out.println(line);
line = bufferedReader.readLine();
}
System.out.println(settings);
}
However, it returns that the file is empty. After messing with breakpoints, I can confirm that the file is indeed not updated at that point. The rather weird thing is that if I pause the application at a later time, the file seems to contain the text that was written to it, even though the file is not touched later in the program.
This makes me believe that it takes some time for the file to update, thus not updating in time for the load() method. Is this correct, or am I missing something? And is there a workaround?
All help is appreciated :)
You're calling load() before you actually saved the file.
To save the file, call fileWriter.close() or just move the load() call out of the try-with-resource block with the FileWriter:
try (FileWriter fileWriter = new FileWriter(absolutePath))
{
fileWriter.write("theme=light\n");
fileWriter.write("resolution=1280x720\n");
fileWriter.write("printfps=false\n");
}
catch (FileNotFoundException e)
{
System.out.println("Settings File not found.");
}
catch (IOException e)
{
e.printStackTrace();
}
// FileWriter closed now and the file contents saved
System.out.println("Reset settings");
load();
Using the following code, a text file that lives on Google Drive erases first as expected,leaving only the newly written content in the file. If the file lives on OneDrive the first x bytes are overwritten and the remaining original bytes left intact. Does anyone know of a work around for OneDrive files. I need the old contents erased and only the new content from the write to remain.
According to these docs
openAssetFileDescriptor and
openAssetFile
that is what should happen.
I have tried this using Java/Android Studio and C#/Xamarin, Android phone 9 api 28.
public void saveFile(View view)
{
try
{
AssetFileDescriptor pfd = getContentResolver().openAssetFileDescriptor(fileUri, "w");
FileOutputStream fileOutputStream = new FileOutputStream(pfd.getFileDescriptor());
fileOutputStream.write(("Overwritten again " + System.currentTimeMillis() + "\n").getBytes());
fileOutputStream.close();
pfd.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
Couldn't come up with a why it doesn't work as documented, but I have come up with a work around to simulate expected behavior. Wouldn't mind comments if anyone sees a better way.
public void saveFile(View view)
{
try
{
ParcelFileDescriptor pfd = getContentResolver().openFileDescriptor(fileUri, "w");
FileOutputStream fileOutputStream = new FileOutputStream(pfd.getFileDescriptor());
//Added if-block to simulate automatic truncate when file located on onedrive.
if( (fileUri.toString()).contains("skydrive"))
{
FileChannel fileChannel = fileOutputStream.getChannel();
fileChannel.truncate(0);
}
fileOutputStream.write(("Overwritten again " + System.currentTimeMillis() + "\n").getBytes());
fileOutputStream.close();
pfd.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
try to use following, just replace "w" with "rwt" to truncate the original file.
getContentResolver().openAssetFileDescriptor(fileUri, "rwt")
I've read this Reading a resource file from within jar however I couldn't figure out how to get a file instead of a inputstream, which is what I need. This is the code:
private void duplicateDocument() {
FileOutputStream fos = null;
File file;
try {
try {
doc = new File(getClass().getResource("1.docx").toURI());
//doc = new File(getClass().getResourceAsStream("1.docx"));
} catch (URISyntaxException ex) {
Logger.getLogger(ForensicExpertWitnessReportConfigPanel.class.getName()).log(Level.SEVERE, "Failed ...", ex);
}
file = new File("C:\\Users\\student\\Documents\\myfile.docx");
fos = new FileOutputStream(file);
/* This logic will check whether the file
* exists or not. If the file is not found
* at the specified location it would create
* a new file
*/
if (!file.exists()) {
file.createNewFile();
}
/*String content cannot be directly written into
* a file. It needs to be converted into bytes
*/
byte[] bytesArray = FileUtils.readFileToByteArray(doc);
fos.write(bytesArray);
fos.flush();
System.out.println("File Written Successfully");
}
catch (IOException ioe) {
ioe.printStackTrace();
}
finally {
try {
if (fos != null)
{
fos.close();
}
}
catch (IOException ioe) {
System.out.println("Error in closing the Stream");
}
}
}
FileUtils.readFileToByteArray is the only thing I've been able to get working so far, which is why I need the value a a file rather than an inputstream.
Currently, the code above gives "A java.lang.IllegalArgumentException" which is why I saw a suggestion online to use getResourceAsStream() instead - however haven't been able to return it as a file.
My next option is to try Reading a resource file from within jar - buffered reader instead.
Can someone help?
I recommend Files with its many useful functions:
Path out = Paths.get("C:\\Users\\student\\Documents\\myfile.docx");
InputStream in = getClass().getResourceAsStream("1.docx");
Files.copy(in, out, StandardCopyOption.REPLACE_EXISTING);
A resource in principle is a read-only file, possibly zipped in a jar.
Hence one cannot write back to it, and it can only serve as template for a real file, as is done here.
I got it working, using this:
InputStream in = getClass().getResourceAsStream("1.docx");
byte[] bytesArray = IOUtils.toByteArray(in);
I'm using the following references, since this is the first time I've used Java Properties.
http://docs.oracle.com/javase/tutorial/essential/environment/properties.html
http://www.mkyong.com/java/java-properties-file-examples/
I'm attempting to run the following at the beginning of my program start, so the user only has to select the database file path once. After selecting it once, every subsequent program run should automatically use the config.properties file and get the database path.
Unfortunately, input == null is continually firing on every program run, even after selecting the correct database path in the previous program run and confirming the properties file contains the database path information.
Am I doing something wrong below?
Properties prop = new Properties();
InputStream input = null;
String filename = "config.properties";
input = this.getClass().getClassLoader().getResourceAsStream(filename);
if (input == null)
{
fileChooser.setDialogTitle("Choose the database file");
fileChooser.setAcceptAllFileFilterUsed(false);
FileFilter filter = new FileNameExtensionFilter("S3DB Files", "S3DB");
fileChooser.addChoosableFileFilter(filter);
int ret = fileChooser.showDialog(null, "Select File");
File file = null;
if (ret == JFileChooser.APPROVE_OPTION) {
file = fileChooser.getSelectedFile();
dbc = new DBConnect(file.getAbsolutePath());
}
OutputStream output = null;
try
{
output = new FileOutputStream("config.properties");
// set the properties value
prop.setProperty("database", file.getAbsolutePath());
// save properties to project root folder
prop.store(output, null);
}
catch (IOException io)
{
io.printStackTrace();
}
finally
{
if (output != null)
{
try
{
output.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
else
{
try
{
prop.load(input);
dbc = new DBConnect(prop.getProperty("database"));
}
catch(Exception e)
{
JOptionPane.showMessageDialog(null, e.toString(), "Properties Read/Write Exception Occured (PRGRYADDView())", JOptionPane.ERROR_MESSAGE);
}
}
Check your the properties file path.
Create a 'config.properties' file, and put it in your project classpath.
Replace this line:
input = this.getClass().getClassLoader().getResourceAsStream(filename);
with this:
try
{
input = new FileInputStream(filename);
}
catch(Exception e){}
I was attempting to load from the classpath rather than from the properties file itself relative to the executable JAR. The above solved my problem.
Be sure to add in your own exception handling as well.
I get this exception:
java.io.FileNotFoundException: C:\...\filename.xml (The system cannot find the path specified)
using this code:
FileWriter fileWriter = new FileWriter(new File(path + date + time "filename.xml"));
BufferedWriter writer = new BufferedWriter(fileWriter);
writer.write("data");
Path exists but directories for 'date' and 'time' need to be created. Application has full permissions on the directory.
Any ideas?
The problem is because I'm creating a subdirectory in which to write the files. So I currently have C:\example\ and want to write my files in C:\example\<date>\<time>\<files>
You need to call File#mkdirs() before writing.
File file = new File("C:/example/newdir/newdir/filename.ext");
file.mkdirs();
// ...
Do assume that the computer is right and you are wrong.
And, in that scenario, the directory to which you want to write does not exit (or does not have permissions to do so).
check the current working dir System.getProperty("user.dir")
debug from there
Code works for me. (Need to add a writer.close() for text to show up in the file.)
What worked for me: The folder where my project was present had a space in the name. I replacedthe space with a hyphen(-). Now, the relative path of the file does not have a space (%20). This change worked for me. Hope it helps someone.
You also need to convert newly created file and folder paths to string.
File folder = new File("src\\main\\json\\", idNumber);
folder.mkdir();
if (!folder.exists()) {
try {
folder.createNewFile();
} catch (IOException ex) {
Logger.getLogger(JsonGeneration.class.getName()).log(Level.SEVERE, null, ex);
}
}
...
...
FileOutputStream output = null;
File file;
String content = data.toString();
try {
String folder_location = folder.toString() + "\\";
String filename = "CurrentInfo";
file = new File(folder_location + filename.toString() + ".json");
output = new FileOutputStream(file);
if (!file.exists()) {
file.createNewFile();
}
byte[] content_in_bytes = content.getBytes();
output.write(content_in_bytes);
output.flush();
output.close();
} catch (IOException ex) {
Logger.getLogger(JsonGeneration.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
if (output != null) {
output.close();
}
} catch (IOException e) {
Logger.getLogger(JsonGeneration.class.getName()).log(Level.SEVERE, null, e);
}
}
}