I am writing a class that will read lines from a log file when it is updated.
I am using Apache VFS2 to get a method called when a file is updated. My main issue is I don't want to read the line from the file if the line is not complete yet, as in it does have a "\n" or "\r" line separator type character at the end. I think i have looked at all the Java libraries i can to read lines but they all discard the EOF and line termination information so I don't think I can use them.
Instead I am looking at reading it in byte by byte and then checking the result to then discard all stuff that comes after the last line separator. I was wondering what you folks thoughts on the best method for doing this is.
So for example:
2013-Jul-01_14:07:17.875 - Connection to Message Bus is reestablished<LF>
2013-Jul-01_14:07:17.875 - Connection to Message Bus is reestablished<LF>
2013-Jul-01_14:15:08.205 - No connection to Message Bus - reestablish before we can publish<LF>
2013-Jul-01_14:15:08.205 - NOT A REAL LINE PLEASE DONT READ
I want to read in the first 3 but not the fourth as it doesn't have a line feed or carriage return character ().
I have looked at Apache commons-io Tailer stuff but I cant tell if that will give me "incomplete" lines (and I realize I will have to ditch the VFS2 stuff to use it).
So psudo-code:
private void ingestFileObject(FileObject file) {
BufferedInputStream bs = new BufferedInputStream(file.getContent().getInputStream());
StringBuilder result = new StringBuilder();
while (bs.available() > 0) {
result.append((char) bs.read());
}
bs.close();
String resultString = result.toString();
//determine what part of resultString is after last carriage return/line seperate (using regex [\\r\\n]+?
//remove the offending part of String.
}
Or any other solutions completely ignoring my psudo-code are welcome at this point too...
Thanks
Is using Scanner help you?
Scanner scanner = new Scanner(file);
//block till there is some thing with a new line
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
//do processing.
}
This is what I ended up doing:
BufferedReader bufReader = new BufferedReader(new InputStreamReader(file.getContent().getInputStream()));
StringBuilder result = new StringBuilder();
int readInInt = -1;
String charsSinceLastLineSep = "";
if (bufReader.ready()) {
while (-1 != (readInInt = bufReader.read())) {
char readInChar = (char) readInInt;
// if new line reset line buffer, otherwise add to buffer
if (readInChar == '\n' || readInChar == '\r') {
charsSinceLastLineSep = "";
} else {
charsSinceLastLineSep += readInChar;
}
result.append(readInChar);
}
bufReader.close();
// remove all characters added since last Carriage Return or NewLine was found indicating
// that line was not a complete log line
String resultString = (result.subSequence(0, (result.length() - charsSinceLastLineSep.length())).toString());
Related
I'm trying to read text inside a .txt document using console command java program < doc.txt. The program should look for words inside a file, and the file CAN contain empty new lines, so I've tried changing the while condition from:
while((s = in.nextLine()) != null)
to:
while((s = in.nextLine()) != "-1")
making it stop when it would have found -1 (I've also tried with .equals()), but it does not work. How can I tell my program to stop searching for words when there's no more text to examine? Otherwise it keeps stopping when it finds an empty string (newline alone or sequence of new lines).
I've only found solutions using BufferedReader, but I don't know how to use it in this situation where the file is being read by the console command java program < doc.txt.
I post the code inside the while, if it can be necessary:
while((s = in.nextLine()) != null) {
s = s.toLowerCase();
Scanner line = new Scanner(s);
a = line.next();
if(a.equals("word")) {
k++;
}
}
Proper way of figuring out when Scanner runs out of input is checking hasNextLine() condition. Use this loop to read a sequence of strings that includes empty lines:
Scanner in = new Scanner(System.in);
while(in.hasNextLine()) {
String s = in.nextLine();
System.out.println(s);
}
Demo.
I'm trying to read in a file and modify the text, but I need to keep new lines when doing so. For example, if I were to read in a file that contained:
This is some text.
This is some more text.
It would just read in as
This is some text.This is some more text.
How do I keep that space? I think it has something to do with the /n escape character. I've seen using BufferReader and FileReader, but we haven't learned that in my class yet, so is there another way? What I've tried is something like this:
if (ch == 10)
{
ch = '\n';
fileOut.print(ch);
}
10 is the ASCII table code for a new line, so I thought Java could recognize it as that, but it doesn't.
In Java 8:
You can read lines using:
List<String> yourFileLines = Files.readAllLines(Paths.get("your_file"));
Then collect strings:
String collect = yourFileLines.stream().filter(StringUtils::isNotBlank).collect(Collectors.joining(" "));
The problem is that you (possibly) want to read your file a line at a time, and then you want to write it back a line at a time (keeping empty lines).
The following source does that, it reads the input file one line at a time, and writes it back one line at a time (keeping empty lines).
The only problem is ... it possibly changes the new line, maybe you are reading a unix file and write a dos file or vice-versa depending on the system you are running in and the source type of the file you a reading.
Keeping the original newline can introduce a lot complexity, read BufferedReader and PrintWriter api docs for more information.
public void process(File input , File output){
try(InputStream in = new FileInputStream(input);
OutputStream out = new FileOutputStream(output)){
BufferedReader reader = new BufferedReader(new InputStreamReader(in, "utf-8"),true);
PrintWriter writer = new PrintWriter( new OutputStreamWriter(out,"utf-8"));
String line=null;
while((line=reader.readLine())!=null){
String processed = proces(line);
writer.println(processed);
}
} catch (IOException e) {
// Some exception management
}
}
public String proces(String line){
return line;
}
/n should be \n
if (ch == 10)
{
ch = '\n';
fileOut.print(ch);
}
Is that a typo?
ch = '/n';
otherwise use
ch = '\n';
i have a question. I have a text file with some names and numbers arranged like this :
Cheese;10;12
Borat;99;55
I want to read the chars and integers from the file until the ";" symbol, println them, then continue, read the next one, println etc. Like this :
Cheese -> println , 10-> println, 99 -> println , and on to the next line and continue.
I tried using :
BufferedReader flux_in = new BufferedReader (
new InputStreamReader (
new FileInputStream ("D:\\test.txt")));
while ((line = flux_in.readLine())!=null &&
line.contains(terminator)==true)
{
text = line;
System.out.println(String.valueOf(text));
}
But it reads the entire line, doesn`t stop at the ";" symbol. Setting the 'contains' condition to false does not read the line at all.
EDIT : Partially solved, i managed to write this code :
StringBuilder sb = new StringBuilder();
// while ((line = flux_in.readLine())!=null)
int c;
String terminator_char = ";";
while((c = flux_in.read()) != -1) {
{
char character = (char) c;
if (String.valueOf(character).contains(terminator_char)==false)
{
// System.out.println(String.valueOf(character) + " : Char");
sb.append(character);
}
else
{
continue;
}
}
}
System.out.println(String.valueOf(sb) );
Which returns a new string formed out of the characters from the read one, but without the ";". Still need a way to make it stop on the first ";", println the string and continue.
This simple code does the trick, thanks to Stefan Vasilica for the ideea :
Scanner scan = new Scanner(new File("D:\\testfile.txt"));
// Printing the delimiter used
scan.useDelimiter(";");
System.out.println("Delimiter:" + scan.delimiter());
// Printing the tokenized Strings
while (scan.hasNext()) {
System.out.println(scan.next());
}
// closing the scanner stream
scan.close();
Read the characters from file 1 by 1
Delete the 'contains' condition
Use a stringBuilder() to build yourself the strings 1 by 1
Each stringBuilder stops when facing a ';' (say you use an if clause)
I didn't test it because I'm on my phone. Hope this helps
I am using a buffered reader to read in a file filled with lines of information. Some of the longer lines of text extend to be more than one line so the buffered views them as a new line. Each line ends with ';' symbol. So I was wondering if there was a way to make the buffered reader read a line until it reaches the ';' then return the whole line as a string. Here a how I am using the buffered reader so far.
String currentLine;
while((currentLine = reader.readLine()) != null) {
// trim newline when comparing with lineToRemove
String[] line = currentLine.split(" ");
String fir = line[1];
String las = line[2];
for(int c = 0; c < players.size(); c++){
if(players.get(c).getFirst().equals(fir) && players.get(c).getLast().equals(las) ){
System.out.println(fir + " " + las);
String text2 = currentLine.replaceAll("[.*?]", ".150");
writer.write(text2 + System.getProperty("line.separator"));
}
}
}
It would be much easier to do with a Scanner, where you can just set the delimiter:
Scanner scan = new Scanner(new File("/path/to/file.txt"));
scan.useDelimiter(Pattern.compile(";"));
while (scan.hasNext()) {
String logicalLine = scan.next();
// rest of your logic
}
To answer your question directly, it is not possible. Buffered Reader cannot scan stream in advance to find this character and then return everything before target character.
When you read from stream with Buffered Reader you are consuming characters and you cannot really know character without reading.
You could use inherited method read() to read only single character and then stop when you detect desired character. Granted, this is not good thing to do because it contradicts the purpose of BufferedReader.
I am writing a small java app which will scan a text file for any instances of particular word and need to have a feature whereby it can report that an instance of the word was found to be the 14th word in the file, on the third line, for example.
For this i tried to use the following code which i thought would check to see whether or not the input was a newline (\n) character and then incerement a line variable that i created:
FileInputStream fileStream = new FileInputStream("src/file.txt");
DataInputStream dataStream = new DataInputStream(fileStream);
BufferedReader buffRead = new BufferedReader(new InputStreamReader(dataStream));
String strLine;
String Sysnewline = System.getProperty("line.separator");
CharSequence newLines = Sysnewline;
int lines = 1;
while ((strLine = buffRead.readLine()) != null)
{
if(strLine.contains(newLines))
{
System.out.println("Line Found");
lines++;
}
}
System.out.println("Total Number Of Lines In File: " + lines);
This does not work for, it simply display 0 at the end of this file. I know the data is being placed into strLine during the while loop as if i change the code slightly to output the line, it is successfully getting each line from the file.
Would anyone happen to know the reason why the above code does not work?
Read the javadocs for readLine.
Returns:
A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached
readLine() strips newlines. Just increment every iteration of the loop. Also, you're overcomplicating your file reading code. Just do new BufferedReader(new FileReader("src/file.txt"))