I am working on java Application where I am dealing with read and
write file. But I want to do this process simultaneously. As my file
is log file from which I am reading contents by some time interval for
this I used java.util.Timer. And during this time interval I am trying
to writing some contents in the file, but this is not updating in my
log file.
My Timer class is
public class Timer extends java.util.Timer {
public void startTimer() {
Timer t = new Timer();
Task task = new Task();
t.schedule(task, 0, 10000);
}
}
My class form which file read write class is called
public class Task extends TimerTask {
#Override
public void run() {
System.out.println("In task ....");
try {
SMSQuestions smsQuestions = new SMSQuestions();
smsQuestions.sendSMSAnswer();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
My file read write class is
public void sendSMSAnswer()
{
long sender;
String question;
try {
BufferedReader br = new BufferedReader(new FileReader("C:/temp/NowSMS/TEST.log"));
String line = br.readLine();
while (line != null) {
sender = 0;
question = "";
System.out.println(line);
line = br.readLine();
}
//To delete all contents in file
BufferedWriter bw = new BufferedWriter(new FileWriter("C:/temp/NowSMS/TEST.log"));
bw.write("");
getDetails();
}catch(Exception exp)
{
exp.printStackTrace();
}
}
My problem is when i updated my log file by writing new contents it
can't be updated so my question is: is it possible in java to simultaneously read write file or not?
I would suggest you have a look at random access files (see http://docs.oracle.com/javase/tutorial/essential/io/rafs.html). This API is a little more complicated to work with since you'll be reading bytes, not lines, but it should give you what you need.
If you don't want to deal with NIO you can use http://docs.oracle.com/javase/7/docs/api/java/io/RandomAccessFile.html instead.
Try this topic. But the only answer you will get is, its only working with a few OSs.
I have two things to say about your code.
First:
I think that you are missing the finally block where you are supposed to close br and bw.
Try:
finally {
br.close();
bw.close();
}
after the catch block.
Second: It is not a good idea to write content to a file while it is opened. I mean, if you open a file with br maybe it is better to gives another file path to bw
Related
I want to save data with jackson to existing file (update it) but it won't work when I run my project from jar.
I need to use json as "database" (I know it's pretty stupid but that's for a school project) and to do it I load and save all the data when I do any of CRUD operations. It's working fine when I run it with IDE but when I tried as a jar it had a problem with reading file from ClassPathResource.
So I have this method to save changes to file:
private List<Item> items;
private ObjectMapper mapper;
private ObjectWriter writer;
public void saveData() {
mapper = new ObjectMapper();
writer = mapper.writer(new DefaultPrettyPrinter());
try {
writer.writeValue(new ClassPathResource("items.json").getFile(), items);
} catch (IOException e) {
e.printStackTrace();
}
}
And it works just fine when i run this through IntelliJ but it won't work when I run it as a jar.
I found a solution to loading the data by using InputStream from this question and method looks like this:
public void loadData() {
mapper = new ObjectMapper();
try {
ClassPathResource classPathResource = new ClassPathResource("items.json");
InputStream inputStream = classPathResource.getInputStream();
File tempFile = File.createTempFile("test", ".json");
FileUtils.copyInputStreamToFile(inputStream, tempFile);
System.out.println(tempFile);
System.out.println(ItemDao.class.getProtectionDomain().getCodeSource().getLocation().getPath().toString());
items = mapper.readValue(tempFile, new TypeReference<List<Item>>() {
});
} catch (IOException e) {
items = null;
e.printStackTrace();
}
}
But I still have no idea how to actually save changes. I was thinking about making use of FileOutputStreambut I achieved nothing.
So I want to get this working in jar file and be able to save changes to the same file, thanks for help in advance!
when you want to do read/write operations, it is better keep the file outside of the project. when running the jar, pass file name with path as an argument. like -DfileName=/Users/chappa/Documents/items.json etc. This way, you have absolute path, and you can perform read/write operations on it
if you are using java 1.7 or above, use below approach to write data.
To read data, you can use jackson api to load the json file as is.
Path wipPath = Paths.get("/Users/chappa/Documents/items.json");
try (BufferedWriter writer = Files.newBufferedWriter(wipPath)) {
for (String record : nosRecords) {
writer.write(record);
}
}
Just in case if you want to read json using IO streams, you can use below code
Path wipPath = Paths.get("/Users/chappa/Documents/items.json");
try (BufferedReader reader = Files.newBufferedReader(wipPath)) {
String line=null;
while((line = reader.readLine()) != null) {
System.out.println(line);
}
}
I'm creating a feature file programmatically using the following java code.
// This method will be invoked by 'constructFeatureFile()'
public static void createFeatureFile(String strFeatureFilePath, String strFeatureFileContent, String runnableFile)
{
try
{
if (strFeatureFilePath.trim().length() > 0 && strFeatureFileContent.trim().length() > 0)
{
// First time file creation
if (!Files.exists(Paths.get(strFeatureFilePath)))
{
FileWriter fw = new FileWriter(new File(strFeatureFilePath));
Writer wr = new BufferedWriter(fw);
wr.write(strFeatureFileContent);
wr.close();
} //If the exists, delete that file and create with fresh data
else if(Files.exists(Paths.get(strFeatureFilePath)))
{
Files.delete(Paths.get(strFeatureFilePath));
FileWriter fw = new FileWriter(new File(strFeatureFilePath));
Writer wr = new BufferedWriter(fw);
wr.write(strFeatureFileContent);
wr.close();
}
// Call Runner to run feature file
runner(runnableFile);
}
}
catch(Exception e)
{
System.out.print(e);
}
}
// Invoke feature file to execute
public static void runner(String runnableFile)
{
Map<String, Object> args = new HashMap<String,Object>();
args.put("name", "API Testing");
Map<String, Object> getResponse = CucumberRunner.runClasspathFeature(runnableFile, args, true);
getResponse = null;
}
The problem is, after creating the feature file, I'm calling Runner() method to execute the feature file. Its throwing the following exception.
java.lang.RuntimeException: file not found: country//getMembersDetails.feature
But, after refresing the folder (where the feature file was created), and re-run the same script, it's executing perfectly with the same feature file.
I don't understand why this is happening, what is the mistake I did here, anyone please provide suggestions.
Thanks!
It looks like createFeatureFile() is busy writing to strFeatureFilePath, but then calling runner(runnableFile). nothing was written to runnableFile?
I can't seem to find a way to store a simple scoring system for a user identifier and their score. I've tried storing it in a string and in a file, but I couldn't get it to work properly.
Here's the relevant code
public class ShiftGame extends JavaPlugin implements Listener {
public void onEnable() {
getServer().getPluginManager().registerEvents(this, this);
}
#EventHandler
public void onPlayerSneak(PlayerToggleSneakEvent e){
Player player = e.getPlayer();
String name = player.getDisplayName();
if(e.isSneaking() == false){
try {
PrintWriter out;
System.out.println("Writing to data file..");
out = new PrintWriter("PlayerShiftAmounts.txt");
out.println(name);
out.close();
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
}
}
}
Minecraft has some config file class: FileConfiguration and YamlConfiguration, so I think you don't need to use java.io.*, and realy needn't to worry about file writing.
FileConfiguration config = YamlConfiguration.loadConfiguration(file);
If you sure have to log something many times a second , I think you should try to use cache or just make a variable in Java , instead of writing into file or database every time.. I don't know why you need to log a list of which player are pressing shift?
I have a file with name foo.txt. This file contains some text. I want to achieve following functionality:
I launch program
write something to the file (for example add one row: new string in foo.txt)
I want to get ONLY NEW content of this file.
Can you clarify the best solution of this problem? Also I want resolve related issues: in case if I modify foo.txt I want to see diff.
The closest tool which I found in Java is WatchService but if I understood right this tool can only detect type of event happened on filesystem (create file or delete or modify).
Java Diff Utils is designed for that purpose.
final List<String> originalFileContents = new ArrayList<String>();
final String filePath = "C:/Users/BackSlash/Desktop/asd.txt";
FileListener fileListener = new FileListener() {
#Override
public void fileDeleted(FileChangeEvent paramFileChangeEvent)
throws Exception {
// use this to handle file deletion event
}
#Override
public void fileCreated(FileChangeEvent paramFileChangeEvent)
throws Exception {
// use this to handle file creation event
}
#Override
public void fileChanged(FileChangeEvent paramFileChangeEvent)
throws Exception {
System.out.println("File Changed");
//get new contents
List<String> newFileContents = new ArrayList<String> ();
getFileContents(filePath, newFileContents);
//get the diff between the two files
Patch patch = DiffUtils.diff(originalFileContents, newFileContents);
//get single changes in a list
List<Delta> deltas = patch.getDeltas();
//print the changes
for (Delta delta : deltas) {
System.out.println(delta);
}
}
};
DefaultFileMonitor monitor = new DefaultFileMonitor(fileListener);
try {
FileObject fileObject = VFS.getManager().resolveFile(filePath);
getFileContents(filePath, originalFileContents);
monitor.addFile(fileObject);
monitor.start();
} catch (InterruptedException ex) {
ex.printStackTrace();
} catch (FileNotFoundException e) {
//handle
e.printStackTrace();
} catch (IOException e) {
//handle
e.printStackTrace();
}
Where getFileContents is :
void getFileContents(String path, List<String> contents) throws FileNotFoundException, IOException {
contents.clear();
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(path), "UTF-8"));
String line = null;
while ((line = reader.readLine()) != null) {
contents.add(line);
}
}
What I did:
I loaded the original file contents in a List<String>.
I used Apache Commons VFS to listen for file changes, using FileMonitor. You may ask, why? Because WatchService is only available starting from Java 7, while FileMonitor works with at least Java 5 (personal preference, if you prefer WatchService you can use it). note: Apache Commons VFS depends on Apache Commons Logging, you'll have to add both to your build path in order to make it work.
I created a FileListener, then I implemented the fileChanged method.
That method load new contents form the file, and uses Patch.diff to retrieve all differences, then prints them
I created a DefaultFileMonitor, which basically listens for changes to a file, and I added my file to it.
I started the monitor.
After the monitor is started, it will begin listening for file changes.
Recently I was trying to implement the functionality of a normal terminal to a graphically designed Swing-based console project. I love how some people in here made this possible, but yet I stumbled upon another big kind of problem. Some people actually spoke about InpuStreamListener although I am not too fond of this. A sample code of my work (pretty much not exactly mine, but it is the source code of my app) would be the following:
// Making an executor
org.apache.commons.exec.DefaultExecutor exec = new org.apache.commons.exec.DefaultExecutor();
// Creating the streams (pretty much ignore this, I just include it as a general idea of the method)
consoleOutputStream = new ConsoleOutputStream();
consoleInputStream = new JTextFieldInputStream(gsc.mainWindow.getConsoleInput().getJTextField());
// Stream Handler with the customized streams I use for the process
org.apache.commons.exec.PumpStreamHandler streamHandler = new org.apache.commons.exec.PumpStreamHandler(consoleOutputStream, consoleOutputStream, consoleInputStream);
// Setting the handler and finally making command line and executing
exec.setStreamHandler(streamHandler);
org.apache.commons.exec.CommandLine commandline = org.apache.commons.exec.CommandLine.parse(String.valueOf(arg));
exec.execute(commandline);
Now the thing is I generally try to run java application through the java commands through this method. OutputStream works really fine, no flaws whatsoever and gives me all it shall, but applications with Input give me a lot of trouble. I beieve the problem resides in the hardcoding to System.in, the Scanner class, the Console class etc. So here's what I need some help with (finally):
I want to either be able to directly access the InputStream passed to my application or someone explaining a way to me of how to actually write an InputStreamListener that will occasionaly be used when I run external java applications (yes, I run them through my interface instead of cmd or terminal, I am trying to make a tool here). If this is too complicated, needs a lot of tweaking on my side or is generally quite impossible, can someone help me just to get the passed InputStream so I can actually write a class that will allow me to write applications specific to my interface?
Thanks in advance and thanks really even for putting the time to read this whole text! :)
Assuming these Apache libraries implement the InputStream and OutputStream interfaces, you can use PipedInputStream and PipedOutputStream to access information. Here's a quick example:
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
public class InputRedirection extends Box{
public InputRedirection() {
super(BoxLayout.X_AXIS);
//Remap input
//Create the input stream to be used as standard in
final PipedInputStream pisIN = new PipedInputStream();
//Create an end so we can put info into standard in
PipedOutputStream posIN = new PipedOutputStream();
//Wrap with a writer (for ease of use)
final BufferedWriter standardIn = new BufferedWriter(new OutputStreamWriter(posIN));
//Set standard in to use this stream
System.setIn(pisIN);
//Connect the pipes
try {
pisIN.connect(posIN);
} catch (IOException e2) {
e2.printStackTrace();
}
//UI element where we're entering standard in
final JTextField field = new JTextField(20);
ActionListener sendText = new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0) {
try {
//Transfering the text to the Standard Input stream
standardIn.append(field.getText());
standardIn.flush();
field.setText("");
field.requestFocus();
} catch (IOException e) {
e.printStackTrace();
}
}};
field.addActionListener(sendText);
add(field);
//Why not - now it looks like a real messaging system
JButton button = new JButton("Send");
button.addActionListener(sendText);
add(button);
//Something using standard in
//Prints everything from standard in to standard out.
Thread standardInReader = new Thread(new Runnable(){
#Override
public void run() {
boolean update = false;
final StringBuffer s = new StringBuffer();
while(true){
try {
BufferedInputStream stream = new BufferedInputStream(System.in);
while(stream.available() > 0){
int charCode = stream.read();
s.append(Character.toChars(charCode));
update = true;
}
if(update){
//Print whatever was retrieved from standard in to standard out.
System.out.println(s.toString());
s.delete(0, s.length());
update = false;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}});
standardInReader.start();
}
public static void main(String[] args){
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new InputRedirection());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
Oh - and one thing to think about when using PipedStreams: Only one thread can write to the Output and only one can read from the input. Otherwise you get some funky problems (see http://techtavern.wordpress.com/2008/07/16/whats-this-ioexception-write-end-dead/ for more details).