I created Simple program for File update throgh java Program
public class AppendToFileExample {
private static final String FILENAME = "TestFile.txt";
public static void main(String[] args) {
BufferedWriter bw = null;
FileWriter fw = null;
try {
String data = " This is new content after edit";
File file = new File(FILENAME);
fw = new FileWriter(file, true);
bw = new BufferedWriter(fw);
bw.write(data);
System.out.println("Done");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bw != null)
bw.close();
if (fw != null)
fw.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
Which is working successfully
But Then i tried to do same thing with the help of ServletContextListener but with servlet everything working fine except I have to put Full file path like this
String FILENAME = "C:\\Users\\admin\\workspacetasks\\UpdateText\\TestFile.txt";
With this full path its working fine but its not updating file when i try to pass only file name like this
String FILENAME = "test.txt";
So my question is how to pass file without full path of file..Is there any other way or anything?or any link for reference?
Thank You.
Below is mine ServletContextListener
public class StartupListener implements ServletContextListener {
private static Logger log = Logger.getLogger(StartupListener.class);
#Override
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("contextInitialized");
UpdateTextFile updateTextFile = new UpdateTextFile();
System.out.println("Before");
updateTextFile.exec();
System.out.println("after");
}
#Override
public void contextDestroyed(ServletContextEvent arg0) {
// TODO Auto-generated method stub
}
}
and then this will call method in java program that program is here
public class UpdateTextFile
{
private static Logger log = Logger.getLogger(UpdateTextFile.class);
public void exec() {
// String FILENAME = "C:\\Users\\admin\\workspacetasks\\UpdateText\\TestFile.txt";
String FILENAME = "TestFile.txt";
System.out.println("Inside exce ");
BufferedWriter bw = null;
FileWriter fw = null;
try {
String data = "Aloha after edit \n";
System.out.println(data);
File file = new File(FILENAME);
System.out.println(FILENAME);
System.out.println("Before FileWriter");
fw = new FileWriter(file, true);
System.out.println("After FileWriter");
System.out.println("Before BufferedWriter");
bw = new BufferedWriter(fw);
System.out.println("After BufferedWriter");
System.out.println("Before Write Data");
bw.write(data);
System.out.println("After Write Data");
System.out.println("Done");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bw != null)
bw.close();
if (fw != null)
fw.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
If your code doesn't throw any exceptions, the file is definitely being created, just not where you think. A file with a relative path will be created relative to the current working directory of your application, whatever that may be. In the case of a servlet container it certainly won't be anywhere inside the webapp's own directory. For example in Tomcat it might be Tomcat's bin directory.
NB:
Contrary to the now-deleted answer by #SilvanBregy, the CWD of an application doesn't necessarily have anything to do with where its own JAR file is located, and contrary to the comment by #soufrk it has exactly nothing to do with the classpath.
The exists() test and createNewFile() calls are both complete wastes of time. new FileOutputStream() already does that, so you're forcing the system to do it all twice, as well as deleting the file you just created.
You don't need to call getAbsoluteFile() either: the File alone is sufficient.
You do however need to close the BufferedWriter.
Yes its SOLVED.If any one in future have same problem then
just click right on program Run As > Run Configuration > Tomcat 8 on left panel > Arguments and then set Other working directory as you want...
Dont know its correct approach to do but thats what i got..if any one get any other way without changing working directory then please share else if i get any i will post it
Related
I want to create a file (outside of the workspace) so that everyone who opens my program has his own Textfile.
Currently I have to following Code:
private static final File m_dataFile = new File("C:\\temp\\MainPlayersLoginData.txt");
private static FileWriter writer;
private static Scanner reader;
public static void setMainPlayersLoginData(String name, String password) {
try {
if (!m_dataFile.exists()) {
createDirectory();
}
writer = new FileWriter(m_dataFile);
writer.write(name + "\n" + password);
writer.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (writer != null)
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static void createDirectory() {
System.out.println("creating directory: " + m_dataFile.getName());
boolean result = false;
try {
m_dataFile.mkdirs();
result = true;
} catch (SecurityException se) {
}
if (result) {
System.out.println("DIR created");
}
}
With this code, the program creates a folder temp as planned, but creates a folder named "MainPlayersLoginData.txt" in it instead of a textfile. In addition I get a FileNotFoundException with the message "Access denied" when initialising the FileWriter.
I tried using m_datafile.mkdir() instead of m_datafile.mkdirs() but this time I get a FileNotFoundException with the message "The system cannot find the specified path" and the folder temp isnt created.
Edit: If i create the folder and the Textfile on my own, everything works fine.
I've found answers to various questions on here before, but this is my first time asking one. I'm kicking around an idea for my final project in my computer programming class, and I'm working on a few proof of concept programs in Java, working in Eclipse. I don't need anything more than to get the filepaths of the contents of a directory and write them to a .txt file. Thanks in advance!
Edit: I am posting my code below. I found a snippet of code to use for getting the contents and print them to the screen, but the print command is a placeholder that I'll replace with a write to folder command when I can.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
public class ScanFolder {
public static void main(String[] args) throws IOException {
Files.walk(Paths.get("C:/Users/Joe/Desktop/test")).forEach(filePath -> {
if (Files.isRegularFile(filePath)) {
System.out.println(filePath);
}
});
}
}
EDIT: I've enclosed the OutputStreamWriter in a BufferedWriter
public static void main(String[] args) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream("txt.txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
return;
}
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(fos));
writeContentsOfFileToAFile(new File("."), out, true); // change true to
// false if you
// don't want to
// recursively
// list the
// files
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
static void writeContentsOfFileToAFile(File parent, BufferedWriter out, boolean enterIntoDirectory) {
for (File file : parent.listFiles()) {
try {
out.write(file.toString() + "\r\n");
} catch (IOException e) {
e.printStackTrace();
}
if (enterIntoDirectory && file.isDirectory())
writeContentsOfFileToAFile(file, out, enterIntoDirectory);
}
}
Is this what you need?
I am trying write to a csv file. After the execution of the code bellow the csv file is still empty.
File is in folder .../webapp/resources/.
This is my dao class:
public class UserDaoImpl implements UserDao {
private Resource cvsFile;
public void setCvsFile(Resource cvsFile) {
this.cvsFile = cvsFile;
}
#Override
public void createUser(User user) {
String userPropertiesAsString = user.getId() + "," + user.getName()
+ "," + user.getSurname() +"\n";;
System.out.println(cvsFile.getFilename());
FileWriter outputStream = null;
try {
outputStream = new FileWriter(cvsFile.getFile());
outputStream.append(userPropertiesAsString);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
#Override
public List<User> getAll() {
return null;
}
}
This is a part of beans.xml.
<bean id="userDao" class="pl.project.dao.UserDaoImpl"
p:cvsFile="/resources/users.cvs"/>
Program compiles and doesn't throw any exceptions but CSV file is empty.
If you're running your app in IDE, the /webapp/resources used for running app will differ from the /webapp/resources in your IDE. Try to log full path to file and check there.
try using outputStream.flush() as the final statement in the first of the try block.
I think you're looking at the wrong file. If you specify an absolute path /resources/users.cvs, then it probably won't be written into the a folder relative to the webapp. Instead, it will be written to /resources/users.cvs
So the first step is to always log an absolute path to make sure the file is where you expect it.
Try with this code, it will at least tell you where the problem lies (Java 7+):
// Why doesn't this method throw an IOException?
#Override
public void createUser(final User user)
{
final String s = String.format("%s,%s,%s",
Objects.requireNonNull(user).getId(),
user.getName(), user.getSurname()
);
// Note: supposes that .getFile() returns a File object
final Path path = csvFile.getFile().toPath().toAbsolutePath();
final Path csv;
// Note: this supposes that the CSV is supposed to exist!
try {
csv = path.toRealPath();
} catch (IOException e) {
throw new RuntimeException("cannot locate CSV " + path, e);
}
try (
// Note: default is to TRUNCATE the destination.
// If you want to append, add StandardOpenOption.APPEND.
// See javadoc for more details.
final BufferedWriter writer = Files.newBufferedWriter(csv,
StandardCharsets.UTF_8);
) {
writer.write(s);
writer.newLine();
writer.flush();
} catch (IOException e) {
throw new RuntimeException("write failure", e);
}
}
I don't know if my mind just fools me or this is really not working.
I need different type of Logging-classes so I created a abstract-class, the only definition that all classes will have the same is the way the writeToLog is handled:
public abstract class LoggerTemplate {
protected String filename ="log/";
protected File logfile;
protected FileWriter fw;
public void writeToLog(String message) {
if(fw != null) {
try {
message = new SimpleDateFormat("dd-MM-hh:mm").format(new Date()) + " " + message;
fw.write(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
The concrete sub-classes will implement rest of the logic in their constructor, ie one of them:
public class JitterBufferLogger extends LoggerTemplate {
public JitterBufferLogger() {
super();
filename += new SimpleDateFormat("yyyyddMMhhmm'.log'").format(new Date());
if(!new File("log/").exists())
new File("log").mkdir();
logfile = new File(filename);
try {
logfile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
try {
fw = new FileWriter(logfile);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
But when I debug I can see that when calling the writeToLog for a specific logger, it jumps into the LoggerTemplate method, and therefore fw and logfile are null. So it's not working.
Isn't it supposed to work or do I just mess something a bit up and should go into weekend ;-)
It should work, it is normal, that the debugger stepped into the LoggerTemplate class upon entering the writeToLog() method. What is strange that the attributes in the base class have null values.
I have tested your code with the following short test program:
public class Test {
public static void main(String[] args) {
LoggerTemplate lt = new JitterBufferLogger();
lt.writeToLog("Hello");
}
}
After adding fw.flush() to the LoggerTemplate.writeToLog() method just after the fw.write() call, it worked for me, the log file had been created and it contained the log message.
Maybe the new File("log").mkdir() or some other calls throw an exception which you cannot see, because stderr had been redirected somewhere.
So what may be missing?
- filewriter flushing could have helped.
- I can't reproduce the null values with the original code, don't know what happened.
- but as everybody, including me, said: it should work and it does.
Why was nothing in the logfile?
- maybe the flush of fw was missing..
anyhow I wrapped it with a Printwriter:
public abstract class LoggerTemplate {
protected String filename ="log/";
protected File logfile;
protected PrintWriter pw;
public void writeToLog(String message) {
try {
pw = new PrintWriter(new FileWriter(logfile,true));
message = new SimpleDateFormat("dd-MM-hh:mm").format(new Date()) + " " + message + "\n";
pw.write(message);
pw.flush();
pw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
and now it's working like it should and was expected to be.
Note that the fw instantiation in the concrete sub-classes is not needed anymore.
I created a file and add some contents into it. Then, I want to delete it with java api. Before this operation, the write out stream is closed, but still failed, so could someone help me to resolve it?
Code snippets:
private static void _saveLogFile(String logContent, String urlPathName) throws Exception {
try {
StringBuilder sb = new StringBuilder("");
sb.append(logContent + "\r\n");
String a = sb.toString();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(urlPathName, true)));
bw.write(a);
bw.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
private static void _deleteLogFile(String urlPathName) throws Exception {
File file = new File(urlPathName);
if (!file.exists()) {
throw new IllegalArgumentException("Delete: no such file or directory: " + urlPathName);
}
if (file.isDirectory()) {
String[] files = file.list();
if (files.length > 0) {
throw new IllegalArgumentException("Delete: directory is not empty: " + urlPathName);
}
}
boolean success = file.delete();
if (!success) {
throw new IllegalArgumentException("Delete:deletion failed.");
}
}
Your code is correct, but only prone to resource leaking. As long as bw.write(a) doesn't throw an exception, bw.close() will succeed. You should rather do the close in finally block to ensure that it will take place regardless of exceptions.
BufferedWriter bw = null;
try {
bw = new BufferedWriter(...);
bw.write(...);
} finally {
if (bw != null) try { bw.close(); } catch (IOException logOrIgnore) {}
}
Back to the actual problem, the symptoms suggests that something else is still holding the file open. Are you able to delete it from inside the platform's shell (Windows Explorer, etc) while the program is still running? For Windows, there are several tools to check if the file is still locked and if so, by what process.
Process Explorer
OpenedFilesView
WhoLockMe
Here's an SSCCE. Just copy'n'paste'n'run it unchanged. It works fine at my machine. Please run it at yours and alter where necessary so that it matches the actual coding at a minimum which still reproduces/exhibits your problem.
package mypackage;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class Test {
public static void main(String args[]) throws Exception {
File file = new File("/test.txt");
for (int i = 0; i < 1000; i++) {
write("line" + i, file); // Write "many" lines.
}
System.out.println("File exist before delete? " + file.exists());
System.out.println("File deleted? " + file.delete());
System.out.println("File exist after delete? " + file.exists());
}
public static void write(String line, File file) throws IOException {
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true)));
writer.write(line);
} finally {
if (writer != null) try {
writer.close();
} catch (IOException e) {
System.err.println("Close failed!");
e.printStackTrace();
}
}
}
}
Output (as expected):
File exist before delete? true
File deleted? true
File exist after delete? false
Using JDK 1.6.0_21 on Windows XP.
Finally, fix it. These snippets are right definitely. The cause is that another thread opens the generated log file and does not close this stream. So could not delete the generated file.
It is a bug of my team player.
Thanks.