Writing to file from within a servlet(Deployer:Tomcat) - java

I am using the following code to write to a file from a servlet in Tomcat container. I don't worry if the file gets overwritten during each deploy.
BufferedWriter xml_out = null;
try {
xml_out = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(getServletContext().getRealPath("/")
+ File.separator + "WEB-INF" + File.separator
+ "XML.xml"), "UTF8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
xml_out.write(xml);
xml_out.flush();
xml_out.close();
} catch (IOException e) {
e.printStackTrace();
}
However, the file writing is not successful (it doesn't get written in the hard disk). Also, there isn't any exception that gets caught! Is there some security thing in Tomcat that is preventing the file from being written ?

Your code has both "/" and the windows file separator at the start of the filename passed to getRealPath(), Java interprets slashes in filenames according to the current OS.
Not using the file separators might give a better result:
String filename = getServletContext().getRealPath("/WEB-INF/XML.xml");
log.debug("Using XML file: " + filename);
xml_out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename),"UTF8"));
Using a separate variable for the filename lets you log it so you can see unexpected results early in de development process.

I has the same issue.
this link helped me to understand where the file was in the hard disk.
Specifically for me, it put the file in the location that is returned by this line:
System.getProperty("user.dir");
In my case the location was: C:\Users\Myself\programming\eclipse for java

Related

Android Write file to a different application folder

My device is rooted
The target audience (if app is shared) will be rooted devices only
I'm trying to customize another app slightly by modifying some image files. So objective is to simply overwrite tiny jpg files (one at a time as required)
/data/data/com.otherapp/files/somefile.jpg for example needs to be overwritten
p = Runtime.getRuntime().exec("su"); is already run before I tried the write method.
I also added Runtime.getRuntime().exec("chmod 077 " +myFile.getAbsolutePath()); before the write code as suggested on a similar question
I'm getting permission denied.
java.io.FileNotFoundException: /data/data/com......jpg: open failed: EACCES (Permission denied)
The write code I have is:
//myDir is /data/data/com.......
File myFile = new File (myDir.getAbsolutePath(), fname);
try {
//myFile.createNewFile();//tried with and without this
FileOutputStream out = new FileOutputStream(myFile);
btbmp.compress(Bitmap.CompressFormat.JPEG, 60, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
How can I do this?
Okay it's taken all day but I've achieved the desired result thus:
Create file on SD card
Then copy file to root destination
src_file = "somefile/on/sdcard.jpg"
dest_file = "/data/data/com.anotherapp/files/abcde.jpg" got path using context
try {
Process process = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(process.getOutputStream());
os.writeBytes("rm "+dest_file + "\n"); //removes destination file -might not be required - haven't tested
os.flush();
os.writeBytes("cat "+src_file+" > "+dest_file + "\n");
os.flush();
os.writeBytes("exit\n");
os.flush();
// Waits for the command to finish.
process.waitFor();
}
catch (IOException e) {
e.printStackTrace();
}
catch (InterruptedException e) {
e.printStackTrace();
}
Note In some cases I had to chmod the root folder 777 for it to work. I'm sure this isn't good practice and doing so will mean the app that uses that folder might not be able to access it. In my case that's what happened until I rectified it using ES Explorer

filewriter not writing to file even though no error

I have some code that I have been using for a long time to write to a .txt file in the csv format, but for some reason it will no longer actually produce a new file. The file writing function is executing normally and flushing and closing without any error, but then no file is created. Below is a simplified example that is still not working.
`
import java.io.FileWriter;
public class test {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
String filename = "SO example";
FileWriter writer=null;
try{
writer = new FileWriter(filename);
}
catch(Exception e){
System.out.println("exception: " + e.getMessage());
}
try{
writer.append("some text\n");
System.out.println("after append");
} catch (Exception e){
System.out.println("exception: " + e.getMessage());
}
try{
writer.flush();
writer.close();
System.out.println("finished writing file "+ filename);
}catch (Exception e){
System.out.println("exception 3: "+e.getMessage());
}
}
}
`
This should create a file called "SO example, but when I search for that file on my computer, it doesn't show up. I am using Netbeans btw. Does anyone know what might be the problem?
Thanks,
Paul
I just ran your code on my computer and everything seems to work fine. I am running Ubuntu and eclipse, however.
I would recommend checking where NetBeans stores your project directory and check in there. Don't forget to refresh the directory if you are looking for the file from the directory hierarchy manager within NetBeans.

Attempting to overwrite files results in blank files

In the app I am working on right now, part of the functionality is to write data saved on the device to a flash drive connected via a USB-OTG adapter. Specifically, the device is a rooted Motorola Xoom running 4.2.2. I can successfully write files to the drive and read them on my computer. That part works fine. However, when I try to replace existing files with new information, the resulting files come out empty. I even delete the existing files before writing new data. What's weird is that after copying the contents of my internal file to the flash drive, I log the length of the resulting file. It always matches the input file and is always a non-0 number, yet the file still shows up as blank on my computer. Can anyone help with this problem? Relevant code from the AsyncTask that I have doing this work is below.
#Override
protected Void doInBackground(Void... params) {
File[] files = context.getFilesDir().listFiles();
for (File file : files) {
if (file.isFile()) {
List<String> nameSegments = Arrays.asList(file.getName().split(
"_"));
Log.d("source file", "size: " + file.length());
String destinationPath = "/storage/usbdisk0/"
+ nameSegments.get(0) + "/" + nameSegments.get(1) + "/";
File destinationPathFile = new File(destinationPath);
if (!destinationPathFile.mkdirs()) {
destinationPathFile.mkdirs();
}
File destinationFile = new File(destinationPathFile,
nameSegments.get(2));
FileReader fr = null;
FileWriter fw = null;
try {
fr = new FileReader(file);
fw = new FileWriter(destinationFile, false);
int c = fr.read();
while (c != -1) {
fw.write(c);
c = fr.read();
}
fw.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fr.close();
fw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Log.d("destination file", "size: " + new File(destinationFile.getPath()).length());
}
}
return null;
}
EDIT:
Per #Simon's suggestion, I added output.flush() to my code. This does not change the result.
EDIT #2:
I did some further testing with this and found something interesting. If I go to Settings->Storage->Unmount USB Storage after writing to the flash drive but before removing it from the OTG adapter, everything works perfectly. However, failing to eject the drive after writing results in the data not being written. What's strange is that the folder structure and file itself are created on the drive, but the file is always empty. One more thing: if I go to a file manager application and open up the file prior to removing the drive, the files all exist as they should. However, even removing the device, plugging it straight back in to the tablet and opening any of the files results in the file looking empty. I can't make heads or tails of this, and this is incredibly frustrating. Can anyone help with this?
EDIT #3:
I also changed to using FileReaders and FileWriters just to wee what would happen. I don't care about efficiency at this point, I simply want file writing to work reliably. This change did not affect the issue. Updated code is posted above.
Try using FileReader.ready() method before your FileReader.read() call,
and ensure if your FileReader really has some bytes in it.
Try this , Used buffered reader for writing
try
{
fw = new FileWriter(destinationFile);
BufferedWriter writer=new BufferedWriter(fw);
writer.append(yourText); // Append can be changed to write or something if you want to overwrite
writer.close();
}
catch (Exception e) {
throw new RuntimeException(e);
}
finally {
if (fw != null) {
try {
fw.flush();
fw.close();
}
catch (IOException e) {
}
I found the solution to my problem. It appears that the Android system buffers some files off of the SD card/flash drive, and then writes them to the flash drive upon eject. The following code after my file operations synchronizes the buffer with the filesystem and allows the flash drive to be immediately removed from the device without data loss. It's worth noting that this DOES require root access; it will not work on a non-rooted device.
try {
Process p = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(p.getOutputStream());
os.writeBytes("sync; sync\n");
os.writeBytes("exit\n");
os.flush();
} catch (Exception e) {
e.printStackTrace();
}
Source of my solution: Android 2.1 programatically unmount SDCard
It sounds like the filesystem is caching your changes, but not actually writing them to the flash drive until you eject it. I don't think there's a way to flush the filesystem cache, so the best solution seems to be just to unmount and then remount the flash drive.

Read and Write files to package in project on Windows and Mac in Java

I am so sorry if this has been posted before.
What I am trying to do is write and read a simple string to a file located in one of the packages in my project. Inside Source Packages I have a package called "resources". Here i want to read a file called myfile.txt, do some stuff with it and save it again as newmyfile.txt. Just simple reading and storing of CSV data.
I have created a reader, which looks like this:
public BufferedReader getFileReader(String fileNameWithExtension, String sourcePackage) {
try {
String file = "/" + sourcePackage + "/" + fileNameWithExtension;
BufferedReader br = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream(file)));
return br;
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
return null;
}
}
This works fine on my Mac. Reading up on this i find out that i have to use File.separator in order to get it to work on all operating systems. So i change this, and still it don´t work. Somewhere it is said that a relative path always starts with / regardless of operating system when using relative paths, and other places ../. As a complete newbie on file storage on Java, I am confused.
There is also a lot of ways to read and write files, and I don´t know what method to choose, and why.
What is the best way for me to read and create files where all I want to do is save one long string, or an array of strings?
I have busy with other things but have now, with help from you, found a solution that works on mac and windows.
For some weird reason, String file = "/" + sourcePackage + "/" + fileNameWithExtension;is the only thing that works for reading on my mac. Suddenly (no code changes done) it started to work on windows as well. I do not know why. So working code for getting a reader is now:
public BufferedReader getFileReader(String fileNameWithExtension, String sourcePackage) {
try {
String file = "/" + sourcePackage + "/" + fileNameWithExtension;
BufferedReader br = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream(file)));
return br;
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
return null;
}
}
For writing to files in the resourses folder, i used:
public BufferedWriter getFileWriter(String fileNameWithExtension, String sourcePackage) {
Writer output = null;
File file = new File("src" + File.separator + sourcePackage + File.separator + fileNameWithExtension);
try {
output = new BufferedWriter(new FileWriter(file));
return (BufferedWriter) output;
} catch (IOException ex) {
Logger.getLogger(FileHelper.class.getName()).log(Level.SEVERE, null, ex);
return null;
}
}
Sadly, not the same way of getting the Readeras the Writer, but it works.
The key thing is that absolute paths always begin with a '/'.
Relative paths must not begin with a '/'. That's at least part of what's causing problems for you.
For the rest, you say "it doesn't work". But what doesn't work?

FileNotFoundException (The system cannot find the path specified)

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);
}
}
}

Categories