Java get current line number when writing to a file - java

I am writing an application that writes to a text file.
In this text file, at the beginning of each line, is the line number
How do I get the current line number so that I can write it in my file?
I've thought of a simple counter, but when I terminate and restart my project the counter would reset back to 1.
I've tried LineNumberReader, but that keeps on giving me 0.
Is there any way to get the current line number when writing to a file?
Thanks
try {
FileWriter writer = new FileWriter("src\\book_store\\transaction.txt", true);
read = new FileReader("src\\book_store\\transaction.txt");
line = new LineNumberReader(read);
for(int i = 0; i < output.size(); i++) {
line.readLine();
temp = line.getLineNumber() + " " + timeStamp2 + " " + output.get(i) + " " + timeStamp + "\n";
output.set(i, temp);
writer.write(output.get(i));
}
writer.close();
read.close();
line.close();
} catch (IOException ex) {
System.out.println("File not found.");
}

The mistake you are making is that while you are writing to a file through FileWriter, you are trying to read the same file using FileReader.
This could potentially work if you fsynced the file after each line. However, this is not what you really want to do. As you see from the comments, people get confused as you are complicating the problem.
You already have the counter. It’s the i loop variable. You might add +1, if you want to start from 1.

Related

How to read/write a file in Java

I would like to replace some items in a file, based on some regular expressions. In order to do that:
I read the file line per line
For every line, I check for the regular expression and I perform the replacement
Every line gets written in an array of strings
When all this is finished, I try to delete the file (in order to recreate it again with the replaced lines).
For some reason this does not work: it seems that Java keeps a handle on that file, even after the BufferedReader has been closed.
Does anybody have a solution for this (newbie) question?
Code excerpt:
Pattern oDatePattern = Pattern.compile("at \\d{2}:\\d{2}:\\d{2} "); // meaning: "at xx:xx:xx"
Pattern oTimePattern = Pattern.compile("Kernel time [0-9]*\\.?[0-9]+ User time: [0-9]*\\.?[0-9]+"); // "[0-9]*\.?[0-9]+" stands for any floating point number
Pattern oMemoryPattern = Pattern.compile("\\([0-9,A-F]*\\)"); // "[0-9,A-F]*" stands for any hexadecimal number
Matcher oDateMatcher;
Matcher oTimeMatcher;
Matcher oMemoryMatcher;
List<String> sLog_Content = new ArrayList<String>();
BufferedReader br = new BufferedReader(new FileReader(sLp_LogFile));
try {
String sLine = br.readLine();
while (sLine != null) {
System.out.println("ORIG : " + sLine);
oDateMatcher = oDatePattern.matcher(sLine);
sLine = oDateMatcher.replaceAll("at <timestamp> ");
oTimeMatcher = oTimePattern.matcher(sLine);
sLine = oTimeMatcher.replaceAll("Kernel time <Kernel_Time_usage> User time: <User_Time_usage>");
oMemoryMatcher = oMemoryPattern.matcher(sLine);
sLine = oMemoryMatcher.replaceAll("<Memory_Address>");
System.out.println("REPL : " + sLine);
sLog_Content.add(sLine);
sLine = br.readLine();
}
} finally {
br.close();
}
System.out.println("All lines are read and regex replaced, try to delete the file");
File tst_File = new File(sLp_LogFile);
if (tst_File.exists()) {
System.out.println(sLp_LogFile + " exists");
} else {
System.out.println(sLp_LogFile + " does not exist");
}
if (tst_File.delete()) {
System.out.println(sLp_LogFile + " is deleted");
} else {
System.out.println(sLp_LogFile + " is not deleted");
}
Output logs:
ORIG : Reading buffer 1 (0000000002ED0070) at 15:40:44 (index 125999, size 4410000 lines 126000, total lines read 126000)
REPL : Reading buffer 1 <Memory_Address> at <timestamp> (index 125999, size 4410000 lines 126000, total lines read 126000)
...
ORIG : Sending buffer 1 (0000000002ED0070) at 15:40:44 (index 125999, size 4410000, lines 126000, total lines sent 126000)
REPL : Sending buffer 1 <Memory_Address> at <timestamp> (index 125999, size 4410000, lines 126000, total lines sent 126000)
...
ORIG : Kernel time 0.2808 User time: 0.312
REPL : Kernel time <Kernel_Time_usage> User time: <User_Time_usage>
...
All lines are read and regex replaced, try to delete the file
D:\Logfile_lp.log exists
D:\Logfile_lp.log is not deleted
One possible explanation is that your application has the file open somewhere else.
Or it could be another application that has the file open.
Or maybe the application / user has permission to read the file but not to delete it.
I concur with the suggestion of using Files.delete ..
I see no issues in your code.
Seemingly closing the BufferReader ensure the file is closed. (cf this response).
Maybe you can give a try to Files.delete cf this response.
It will give more information about the deletion fail by throwing different exceptions.
Good afternoon,
I would like to thank you all for having searched for a solution of this problem. Unfortunately the problem is not Java based: the file I'm trying to write to is created by a redirection cmd /c <program>.exe >> <output>.log, and it seems that Windows has not fully flushed the output buffer towards the output file, creating the problem.
I am currently using following (very dirty) work-around for this issue:
boolean bFile_can_be_opened = false;
while (!bFile_can_be_opened) {
try {
fwLog2 = new FileWriter(sLp_LogFile, true);
bFile_can_be_opened = true;
}
catch (Exception e)
{}
}
Further information on this issue can be found under the following new StackOverflow question: How to release a file, locked by the application, in Java
I'm a beginner, I do not know as much things as you. But if I am right you should save your changes first a temp file. Afterwards you will read again the temp file and later you'll write to your real file. I hope my comment will help you.

Writing to a text file within a loop - JAVA

I've got a loop that reads through a text file and outputs it, now I'm trying to get it to loop through, and write what's printed out into a text file as I want it to display as HTML. This is what I've got so far for this method:
public void hChoice()
{
File fbScores = new File ("P:/SD/Assignment1/fbScores.txt");
String line = "";
try {
Scanner scanScores = new Scanner(fbScores);
while(scanScores.hasNext())
{
line = scanScores.nextLine();
stringArr = line.split(":");
if(stringArr.length == 4)
{
System.out.println("<h1>" + stringArr[0]+" [" +stringArr[2]+"] |" + stringArr[1]+" ["+ stringArr[3]+" ]<br></h1> ");
PrintWriter out = new PrintWriter("P:/SD/Assignment1/HTMLscores.txt");
out.close();
}
}
}
catch (FileNotFoundException e)
{
System.out.println("problem " +e.getMessage());
}
}
I've added the HTML tags in the print out and it prints it out fine, but I've tried several different methods to get it to print to a text file but none have worked. Pretty new to Java so any help would be much appreciated. Thankyou. :)
You've gotten your syntax and code wrong for writing to files.
Please Google and check the right syntax for writing to files using java. Plenty of resources available. You'll learn better if you try it yourself.
FYR, here is one: http://www.tutorialspoint.com/java/java_files_io.htm

No output in Eclipse console, though rest of method works

I am getting nothing out in my console from my System.out.println() in the following code:
LinkedList<Element> ls = count(list);
File outFile = new File(args[1]);
FileWriter fw = new FileWriter(outFile);
BufferedWriter bw = new BufferedWriter(fw);
for(int i = 0; i < ls.size(); i++) {
bw.write((int) ls.get(i).data);
System.out.println("Written out " + ls.get(i).data);
}
bw.flush();
bw.close();
Element object is only a class with an int key; and an Object data;
The BufferedWriter is writing out to the file as it should, but my Console in Eclipse doesn't get the System.out.println(); calls. When I run it in debug mode with breakpoint at bw.write() I keep pressing F8 (hotkey to resume), until the BufferedWriter is done, but nothing gets into the Console. Any ideas of why?
First, please don't use the System console for your logging. Second, add a call to flush(). Finally, make sure you add the same cast you used before (or just save it to a variable).
int payload = (int) ls.get(i).data;
bw.write(payload);
System.out.println("Written out " + payload);
// Or,
// System.out.println("Written out " + ((int) ls.get(i).data));
System.out.flush();
Try outputting the variables for the for loop such as the ls.size(), if nothing is being output there then your code isn't being called at all but if it is then you should be able to figure out what is wrong.
since we don't know what is in ls we don't know if it may even be empty
so to help us try putting
System.out.println("List: " + ls);
System.out.println("List size: " + ls.size());
just before the for loop and tell us the outputs.

Java: No input from Process object until the program closes

I'm trying to get input from the console of a .exe process started by a Java script. Nothing appears in the console window, and nothing is read by the program until the process is terminated.
blServ = new ProcessBuilder(blPath + "Blockland.exe", "ptlaaxobimwroe", "-dedicated", "-port " + port, "-profilepath " + blPath.substring(0, blPath.length() - 1)).start();
System.out.println("Attempting to start server...\n" + blPath);
consoleIn = new BufferedReader(new InputStreamReader(blServ.getInputStream()));
'blServ' is a Process object. And yes, the program is starting successfully.
public void blStreamConsole() //called once every 500 milliseconds
{
String lineStr = "";
String line = "";
int lines = 0;
try
{
if (consoleIn != null)
{
while ((line = consoleIn.readLine()) != null)
{
//if (!line.equals("%"));
//{
lineStr += line + wordSym;
lines++;
//}
}
}
}
catch (IOException e)
{
netOut.println("notify" + wordSym + "ERROR: An I/O exception occured when trying to get data from the remote console. Some lines may not be displayed.");
}
if (!lineStr.equals("") && !(lineStr == null))
netOut.println("streamconsole" + wordSym + lines + wordSym + lineStr);
}
Basically, this method sees if there is more input waiting in the consoleIn object, and if there is, it appends every line it has to another string, and that other string is sent to a client. Unfortunately, it is all sent in one big chunk right when Blockland.exe is closed. Sorry about the indenting issues. The Stackoverflow editor re-arranged all of the code.
It seems to me that there are two possibilities here:
readLine blocks, waiting for input (and doesn't return null as you expect). You may be able to fix it by not using BufferedReader and instead using the InputStream
The output stream doesn't flush until all the input has been written. Try putting a flush there:
Also note that if lineStr is null, you'll get a NullPointerException as your code currently is (you need to swap your conditions), but it can't even be null.
if (!lineStr.isEmpty())
{
netOut.println("streamconsole" + wordSym + lines + wordSym + lineStr);
netOut.flush();
}
while ((line = consoleIn.readLine()) != null){
lineStr += line + wordSym;
lines++;
}
The problem with this piece of code is that it will keep running until the program exits. It will append every single line to lineStr until the program exits (when console.readLine() is null). The whole lineStr is then printed afterwards, containing the whole console.
If you want to continuously print the output, you will need to print it immediatly:
while ((line = consoleIn.readLine()) != null){
netOut.println(line);
}
You can run this in one separate thread, and it will keep outputting the console to the output stream until the program exits.

Best way to call terminal command repeatedly

I'm using mencoder to split files and I'd like to turn this into an Object Oriented approach, if possible, using Java or similar, for example. But I'm not sure the best way, so I leave it in the open. Here is what I need:
I have an excel file with start times and end times, and I need to extract out the appropriate clips from a video file. In the terminal (I'm on Mac OS X) I've had success using, for example:
mencoder -ss 0 -endpos 10 MyVideo.avi -oac copy -ovc copy -o Output.avi
Which creates the video Output.avi by clipping the first 10 seconds of the video MyVideo.avi.
But, like I said, I want to make it so that a program reads in from an excel file, and calls this mencoder command multiple times (over 100) for each of the start times and end times.
I know how to read in the excel file in Java, but I'm not sure it is best to call this command from Java. Plus, I'd like to be able to see the output of mencoder (because it prints out a nice percentage so you know about how much longer a single command will take). Is this type of thing feasible to do in a shell script? I would really like to use Java if possible, since I have many years of experience in Java and no experience in shell scripting.
UPDATE
Here is what I've tried in Java, but it freezes at in.readLine()
File wd = new File("/bin");
System.out.println(wd);
Process proc = null;
try {
proc = Runtime.getRuntime().exec("/bin/bash", null, wd);
}
catch (IOException e) {
e.printStackTrace();
}
if (proc != null) {
BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())), true);
out.println("cd ..");
out.println("pwd");
String video = "/Users/MyFolder/MyFile.avi";
String output = "/Users/MyFolder/output.avi";
int start = 0;
int end = 6;
String cmd = "mencoder -ss " + start +
" -endpos " + end +
" " + video + " -oac copy -ovc copy -o " + output;
out.println(cmd);
try {
String line;
System.out.println("top");
while ((line = in.readLine()) != null) {
System.out.println(line);
}
System.out.println("end");
proc.waitFor();
in.close();
out.close();
proc.destroy();
}
catch (Exception e) {
e.printStackTrace();
}
}
I'm not quite sure about mencoders multicore-capabilities, but I think with Java you can use Multiple Threads to get the maximal power of all cpu-cores.
You shouldn't use Runtime like your using it.
When using Runtime, you should not run bash and send commands via inputstream like when you are typing commands on a terminal.
Runtime.getRuntime().exec("mencoder -ss " + start +
" -endpos " + end +
" " + video + " -oac copy -ovc copy -o " + output);
To get the Output, you can use the inputStream
http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Runtime.html#exec%28java.lang.String,%20java.lang.String[],%20java.io.File%29
With this command you can also set the Workingdirectory where your command is executed.
I also prefer the version with the String[] as parameters. It's much more readable, than the a concatenated String.

Categories