Java BufferedReader readline calculate values from file - java

I am new to Java and at the moment lost.
I have this code:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
/**
*
* #author Darwish
*/
public class M3UReader {
/**
* #param args the command line arguments
*/
public static boolean isValidHeader(String playList)
{
boolean returnValue = false;
BufferedReader br;
try
{
br = new BufferedReader(new FileReader(new File(playList)));
String s = br.readLine(); // declares the variable "s"
if(s.startsWith("#EXTM3U")) { // checks the line for this keyword
returnValue = true; // if its found, return true
}
br.close();
}
catch (Exception e)
{
System.err.println("isValidHeader:: error with file "+ playList + ": " + e.getMessage());
}
return returnValue;
}
public static int getNumberOfTracks(String playList)
{
int numberOfTracks = 0; // sets the default value to zero "0"
try
{
BufferedReader br = new BufferedReader(new FileReader(new File(playList)));
String s;
while((s = br.readLine())!=null) // if "s" first line is not null
{
if(s.startsWith("#")==false) { // if the first line starts with "#" equals to false.
numberOfTracks++; // increments
}
}
br.close();
}
catch (Exception e)
{
numberOfTracks = -1; // chek if the file doesnt exist
System.err.println("could not open/read line from/close filename "+ playList);
}
return numberOfTracks;
}
public static int getTotalMinutes(String playList)
{
// code needed here
}
public static void main(String[] args) {
// TODO code application logic here
String filename = "files\\playlist.m3u"; // finds the file to read (filename <- variable declaration.)
boolean isHeaderValid = M3UReader.isValidHeader(filename); // declares the variabe isHeaderValid and links it with the class isValidHeader
System.out.println(filename + "header tested as "+ isHeaderValid); // outputs the results
if(isHeaderValid)
{
int numOfTracks = M3UReader.getNumberOfTracks(filename);
System.out.println(filename + " has "+ numOfTracks + " tracks ");
}
}
}
On the method getTotalMinutes, I have to find a way to calculate the totals of the int values that was read from the file. The File has this data:
#EXTM3U
#EXTINF:537,Banco De Gaia - Drippy F:\SortedMusic\Electronic\Banco De Gaia\Big Men Cry\01 Drippy.mp3
#EXTINF:757,Banco De Gaia - Celestine F:\SortedMusic\Electronic\Banco De Gaia\Big Men Cry\02 Celestine.mp3
#EXTINF:565,Banco De Gaia - Drunk As A Monk F:\SortedMusic\Electronic\Banco De Gaia\Big Men Cry\03 Drunk As A Monk.mp3
#EXTINF:369,Banco De Gaia - Big Men Cry F:\SortedMusic\Electronic\Banco De Gaia\Big Men Cry\04 Big Men Cry.mp3
The number after the #EXTINF: is the length of the music which from the data above is in seconds.
I don't know what code to write on the getTotalMinutes method to get the program to read the minutes from the file and then calculate all of them to get the total of minutes. I searched the web on how to do this unfortunately I can't find any. So any help is appreciated.

You can use this, its just copy of your getNumberTracks method but it is parsing the file the way you need to get total minutes :
public static final String beginning = "#EXTINF:";
public static final String afterNumber = ",";
public static int getTotalMinutes(String playList) {
int value = 0;
try {
BufferedReader br = new BufferedReader(new FileReader(new File(playList)));
String s;
while ((s = br.readLine()) != null) // if "s" first line is not null
{
if (s.contains(beginning)) {
String numberInString = s.substring(beginning.length(), s.indexOf(afterNumber));
value += Integer.valueOf(numberInString);
}
}
br.close();
} catch (Exception e) {
}
return value;
}

So, based on the description provided from here, the numeric value is the number of seconds.
So, given a String in the format of #EXTINF:{d},{t} you should be able to use simple String manipulation to get the value out...
String text = "#EXTINF:537,Banco De Gaia - Drippy F:\\SortedMusic\\Electronic\\Banco De Gaia\\Big Men Cry\\01 Drippy.mp3";
String durationText = text.substring(text.indexOf(":") + 1, text.indexOf(","));
int durationSeconds = Integer.parseInt(durationText);
System.out.println(durationSeconds);
Which will print 537...
Next we just need to do some simple time arithmetic...
double seconds = durationSeconds;
int hours = (int)(seconds / (60 * 60));
seconds = seconds % (60 * 60);
int minutes = (int)(seconds / 60);
seconds = seconds % (60);
System.out.println(hours + ":" + minutes + ":" + NumberFormat.getNumberInstance().format(seconds));
Which prints 0:8:57 (or 8 minutes and 57 seconds)

To read M3U files you'll want to search for information about M3U parsers. There are already many efficient open source parsers available, but you will need to pay close attention to their licenses if you are planning on selling or distributing this.
M3u Parser looks like promising if you just want something quick and efficient.
M3u Parser

public static int getTotalMinutes(String filename) {
int totalSeconds = 0;
if (isValidHeader(filename)) {
try (BufferedReader br = new BufferedReader(new FileReader(new File(filename)));) {
String nextLine;
while ((nextLine = br.readLine()) != null) {
//If the next line is metadata it should be possible to extract the length of the song
if (nextLine.startsWith(M3U_METADATA)) {
int i1 = nextLine.indexOf(":");
int i2 = nextLine.indexOf(",");
String substr = nextLine.substring(i1 + 1, i2);
totalSeconds += Integer.parseInt(substr);
}
}
} catch (IOException | NumberFormatException e) {
//Exception caught - set totalSeconds to 0
System.err.println("getTotalSeconds:: error with file " + filename + ": " + e.getMessage());
totalSeconds = 0;
}
}
return totalSeconds;
}

Related

Unable to write to a file till some specific line

I am trying to split files from one file to 4 different files. So I am dividing the file by some "x" value and wanna write the file till that value and from there to next file continues till the file contents ends.
I am checking some x value in the file using buffer reader and checking with the content is equal to the x value and do the splitting.
Splitting is coming but in some another way, like it's reading the file and writing till the line number which is "x". But I need all the lines till that "x" value is present in the file.
I have a time in the file like start time hh:mm:ss and I am checking this with the hh:mm:ss with my x value and do the splitting like below
// inputs to the below method
// filePath = "//somepath";
// splitlen = 30;
// name ="somename"; */
public void split(String FilePath, long splitlen, String name) {
long leninfile = 0, leng = 0;
int count = 1, data;
try {
File filename = new File(FilePath);
InputStream infile = new BufferedInputStream(new FileInputStream(filename));
data = infile.read();
BufferedReader br = new BufferedReader(new InputStreamReader(infile));
while (data != -1) {
filename = new File("/Users//Documents/mysrt/" + count + ".srt");
OutputStream outfile = new BufferedOutputStream(new FileOutputStream(filename));
String strLine = br.readLine();
String[] atoms = strLine.split(" --> ");
if (atoms.length == 1) {
// outfile.write(Integer.parseInt(strLine + "\n"));
}
else {
String startTS = atoms[0];
String endTS = atoms[1];
System.out.println(startTS + "\n");
System.out.println(endTS + "\n");
String startTime = startTS.replace(",", ".");
String endTime = endTS.replace(",", ".");
System.out.println("startTime" + "\n" + startTime);
System.out.println("endTime" + "\n" + endTime);
String [] arrOfStr = endTime.split(":");
System.out.println("=====arrOfStr=====");
int x = Integer.parseInt(arrOfStr[1]);
System.out.println(arrOfStr[1]);
System.out.println("===x repeat==");
System.out.println(x);
System.out.println("===splitlen repeat==");
System.out.println(splitlen);
System.out.println(data);
System.out.println(br.readLine());
System.out.println(br.read());
while (data != -1 && x < splitlen) {
outfile.write(br.readLine().getBytes());
data = infile.read();
x++;
}
System.out.println("===== out of while x =====");
System.out.println(br.readLine());
System.out.println(x);
leninfile += leng;
leng = 0;
outfile.close();
firstPage = false;
firstPage = true;
count++;
splitlen = splitlen + 30;
System.out.println("=====splitlen after=====" +splitlen);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
I am incrementing the time with some number to read the next lines in file and with into another file.
Here splitlen is 30 , so it's writing the data till 30 lines in a new file. Then it's incrementing splitlen+30 i.e 60. But, it's reading next 60 lines and writing into next file.
But I need to check this splitlen with the time provided in the content of file and I should split that line.
Please suggest me where I am doing wrong. If you provide snippet it will be appreciated.
Thanks.
I think this is what you want
public void split(String filePath, long splitLen, String name) {
File fileSource = new File(filePath);
int count = 0;
boolean endOfFile = false;
String lineSeparator = System.getProperty("line.separator");
int hour = 0; // an accumulator for hours
int min = 0; // an accumulator for minutes
int sec = (int) splitLen; // an accumulator for seconds
int _hour = 0; // hours from the file
int _min = 0; // minutes from the file
int _sec = 0; // seconds from the file
try ( // try with resources to close files automatically
FileReader frSource = new FileReader(fileSource);
BufferedReader buffSource = new BufferedReader(frSource);
) {
String strIn = null;
while(!endOfFile) {
File fileOut = new File("f:\\test\\mysrt\\" + count + ".srt");
try ( // try with resources to close files automatically
FileWriter fwOut = new FileWriter(fileOut);
) {
if (strIn != null) {
// write out the last line read to the new file
fwOut.write(strIn + lineSeparator);
}
for (int i = 0; i < splitLen; i++) {
strIn = buffSource.readLine();
if (strIn == null) {
endOfFile = true; // stop the while loop
break; // exit the for loop
}
if (strIn.indexOf("-->") > 0) {
String endTime = strIn.split("-->")[1];
_hour = extractHours(endTime); // get the hours from the file
_min = extractMinutes(endTime); // get the minutes from the file
_sec = extractSeconds(endTime); // get the seconds from the file
if (_hour >= hour && _min >= min && _sec >= sec) { // if the file time is greater than our accumulators
sec += splitLen; // increment our accumulator seconds
if (sec >= 60) { // if accumulator seconds is greater than 59, we need to convert it to minutes and seconds
min += sec / 60;
sec = sec % 60;
}
if (min >= 60) { if accumulator minutes is greater than 59, we need to convert it to hours and minutes
hour += min / 60;
min = min % 60;
}
break; // break out of the for loop, which cause the file to be completed and a new file started.
}
}
fwOut.write(strIn + lineSeparator); // write out to the new file
}
fwOut.flush();
}
count++;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private int extractMinutes(String time) {
// You need to implement this, I don't know the format of your time
return 0;
}
private int extractSeconds(String time) {
// You need to implement this, I don't know the format of your time
return 0;
}
The problem with your code is that the timestamp you're looking at is in HH:MM:ss but with the splitlen and x variables you are only working with minutes.
So you need to keep track of both hours and minutes, maybe this could be done with some DateTime class but here is a simple int solution
//somewhere at the top
int hour = 0;
int minutes = 30;
//where you today increase splitlen
minutes += 30;
if (minutes == 60) {
hour++;
minutes = 0;
}
//parse also hours
int y = Integer.parseInt(arrOfStr[0]);
int x = Integer.parseInt(arrOfStr[1]);
//you need to rewrite this to compare x and y against hour and minutes
while (data != -1 && x < splitlen) {
So now you will not be looking for 30, 60, 90,... minutes but instead 00:30, 01:00, 01:30 and so on. Of course you must also be prepared to handle the situation where there is no entry for a whole minute unless of course you already do so.
checkTime is of course a a key method here and it might be a good idea to make the last hour and minute when the file was split into class members but they could of course also be sent as parameters from split().
Update
Here is a simplified version of the split method to give an example on how to solve this, it is not complete but should be a good starting point for solving the issue. I try to make use of how a .str file is constructed and make use of the logic explained above for determining when to open a new output file.
public void split(String filepath, long splitlen, String name) {
int count = 1;
try {
File filename = new File(filepath);
InputStream infile = new BufferedInputStream(new FileInputStream(filename));
BufferedReader br = new BufferedReader(new InputStreamReader(infile));
FileWriter outfile = createOutputFile(count);
boolean isEndOfFile = false;
while (!isEndOfFile) {
String line = null;
int i = 1;
while ((line = br.readLine()) != null) {
outfile.write(line);
if (line.trim().isEmpty()) { //last line of group
i = 1;
continue;
}
if (i == 2) { //Timestamp row
String[] split = line.split("-->");
if (checkTime(split)) {
count++;
outfile.flush();
outfile.close();
outfile = createOutputFile(count);
}
}
i++;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private FileWriter createOutputFile(int index) {
//Create new outputfile and writer
return null;
}
private boolean checkTime(String[] arr) {
//use start or end time in arr to check if an even half or full hour has been passed
return true;
}

Reading and modifying the text from the text file in Java

I am have a project that need to modify some text in the text file.
Like BB,BO,BR,BZ,CL,VE-BR
I need make it become BB,BO,BZ,CL,VE.
and HU, LT, LV, UA, PT-PT/AR become HU, LT, LV, UA,/AR.
I have tried to type some code, however the code fail to loop and also,in this case.
IN/CI, GH, KE, NA, NG, SH, ZW /EE, HU, LT, LV, UA,/AR, BB
"AR, BB,BO,BR,BZ,CL, CO, CR, CW, DM, DO,VE-AR-BR-MX"
I want to delete the AR in second row, but it just delete the AR in first row.
I got no idea and seeking for helps.
Please
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.util.Scanner;
public class tomy {
static StringBuffer stringBufferOfData = new StringBuffer();
static StringBuffer stringBufferOfData1 = stringBufferOfData;
static String filename = null;
static String input = null;
static String s = "-";
static Scanner sc = new Scanner(s);
public static void main(String[] args) {
boolean fileRead = readFile();
if (fileRead) {
replacement();
writeToFile();
}
System.exit(0);
}
private static boolean readFile() {
System.out.println("Please enter your files name and path i.e C:\\test.txt: ");
filename = "C:\\test.txt";
Scanner fileToRead = null;
try {
fileToRead = new Scanner(new File(filename));
for (String line; fileToRead.hasNextLine()
&& (line = fileToRead.nextLine()) != null;) {
System.out.println(line);
stringBufferOfData.append(line).append("\r\n");
}
fileToRead.close();
return true;
} catch (FileNotFoundException ex) {
System.out.println("The file " + filename + " could not be found! "+ ex.getMessage());
return false;
} finally {
fileToRead.close();
return true;
}
}
private static void writeToFile() {
try {
BufferedWriter bufwriter = new BufferedWriter(new FileWriter(
filename));
bufwriter.write(stringBufferOfData.toString());
bufwriter.close();
} catch (Exception e) {// if an exception occurs
System.out.println("Error occured while attempting to write to file: "+ e.getMessage());
}
}
private static void replacement() {
System.out.println("Please enter the contents of a line you would like to edit: ");
String lineToEdit = sc.nextLine();
int startIndex = stringBufferOfData.indexOf(lineToEdit);
int endIndex = startIndex + lineToEdit.length() + 2;
String getdata = stringBufferOfData.substring(startIndex + 1, endIndex);
String data = " ";
Scanner sc1 = new Scanner(getdata);
Scanner sc2 = new Scanner(data);
String lineToEdit1 = sc1.nextLine();
String replacementText1 = sc2.nextLine();
int startIndex1 = stringBufferOfData.indexOf(lineToEdit1);
int endIndex1 = startIndex1 + lineToEdit1.length() + 3;
boolean test = lineToEdit.contains(getdata);
boolean testh = lineToEdit.contains("-");
System.out.println(startIndex);
if (testh = true) {
stringBufferOfData.replace(startIndex, endIndex, replacementText1);
stringBufferOfData.replace(startIndex1, endIndex1 - 2,
replacementText1);
System.out.println("Here is the new edited text:\n"
+ stringBufferOfData);
} else {
System.out.println("nth" + stringBufferOfData);
System.out.println(getdata);
}
}
}
I wrote a quick method for you that I think does what you want, i.e. remove all occurrences of a token in a line, where that token is embedded in the line and is identified by a leading dash.
The method reads the file and writes it straight out to a file after editing for the token. This would allow you to process a huge file without worrying about about memory constraints.
You can simply rename the output file after a successful edit. I'll leave it up to you to work that out.
If you feel you really must use string buffers to do in memory management, then grab the logic for the line editing from my method and modify it to work with string buffers.
static void onePassReadEditWrite(final String inputFilePath, final String outputPath)
{
// the input file
Scanner inputScanner = null;
// output file
FileWriter outputWriter = null;
try
{
// open the input file
inputScanner = new Scanner(new File(inputFilePath));
// open output file
File outputFile = new File(outputPath);
outputFile.createNewFile();
outputWriter = new FileWriter(outputFile);
try
{
for (
String lineToEdit = inputScanner.nextLine();
/*
* NOTE: when this loop attempts to read beyond EOF it will throw the
* java.util.NoSuchElementException exception which is caught in the
* containing try/catch block.
*
* As such there is NO predicate required for this loop.
*/;
lineToEdit = inputScanner.nextLine()
)
// scan all lines from input file
{
System.out.println("START LINE [" + lineToEdit + "]");
// get position of dash in line
int dashInLinePosition = lineToEdit.indexOf('-');
while (dashInLinePosition != -1)
// this line has needs editing
{
// split line on dash
String halfLeft = lineToEdit.substring(0, dashInLinePosition);
String halfRight = lineToEdit.substring(dashInLinePosition + 1);
// get token after dash that is to be removed from whole line
String tokenToRemove = halfRight.substring(0, 2);
// reconstruct line from the 2 halves without the dash
StringBuilder sb = new StringBuilder(halfLeft);
sb.append(halfRight.substring(0));
lineToEdit = sb.toString();
// get position of first token in line
int tokenInLinePosition = lineToEdit.indexOf(tokenToRemove);
while (tokenInLinePosition != -1)
// do for all tokens in line
{
// split line around token to be removed
String partLeft = lineToEdit.substring(0, tokenInLinePosition);
String partRight = lineToEdit.substring(tokenInLinePosition + tokenToRemove.length());
if ((!partRight.isEmpty()) && (partRight.charAt(0) == ','))
// remove prefix comma from right part
{
partRight = partRight.substring(1);
}
// reconstruct line from the left and right parts
sb.setLength(0);
sb = new StringBuilder(partLeft);
sb.append(partRight);
lineToEdit = sb.toString();
// find next token to be removed from line
tokenInLinePosition = lineToEdit.indexOf(tokenToRemove);
}
// handle additional dashes in line
dashInLinePosition = lineToEdit.indexOf('-');
}
System.out.println("FINAL LINE [" + lineToEdit + "]");
// write line to output file
outputWriter.write(lineToEdit);
outputWriter.write("\r\n");
}
}
catch (java.util.NoSuchElementException e)
// end of scan
{
}
finally
// housekeeping
{
outputWriter.close();
inputScanner.close();
}
}
catch(FileNotFoundException e)
{
e.printStackTrace();
}
catch(IOException e)
{
inputScanner.close();
e.printStackTrace();
}
}

program that uses input file and creates a new one

I'm writing a code that uses an input file called InvetoryReport.txt in a program I am supposed to create that is supposed to take this file, and then multiply two pieces of data within the file and then create a new file with this data. Also at the beginning of the program it is supposed to ask you for the name of the input file. You get three chances then it is to inform you that it cannot find it and will now exit, then stop executing.
My input file is this
Bill 40.95 10
Hammer 1.99 6
Screw 2.88 2
Milk .03 988
(The program is supposed to multiply the two numbers in the column and create a new column with the sum, and then under print another line like this
" Inventory Report
Bill 40.95 10 409.5
Hammer 1.99 6 11.94
Screw 2.88 2 5.76
Milk .03 988 29.64
Total INVENTORY value $ 456.84"
and my program I have so far is this
package textfiles;
import java.util.Scanner;
import java.io.PrintWriter;
import java.io.IOException;
public class LookOut{
double total = 0.0;
String getFileName(){
System.out.printIn("Type in file name here.");
try {
int count =1;
FileReader fr = new FileReader("InventoryReport.txt");
BufferedReader br = new BufferedReader(fr);
String str;
while ((str = br.readLine()) != null) {
out.println(str + "\n");
}
br.close();
} catch (IOException e) {
if(count == 3) {
System.out.printIn("The program will now stop executing.");
System.exit(0);
count++;
}
}
return str;
}
void updateTotal(double d){
total = total + d;
}
double getLineNumber(int String_line){
String [] invRep = line.split(" ");
Double x = double.parseDouble(invRep[1]);
Double y = double.parseDouble(invRep[2]);
return x * y;
}
void printNewData(String = newData) {
PrintWriter pW = new PrintWriter ("newData");
pw.print(newData);
pw.close;
}
public static void main(String[] args){
String str = ("Get file name");
String str = NewData("InventoryReport/n");
File file = new File(str);
Scanner s = new Scanner(file);
while(s.hasNextLine()) {
String line = s.nextLine();
double data = getLineNumber(line);
update total(data);
NewData += line + " " + data + "/n";
Print NewData(NewData);
}
}
}
I'm getting multiple error codes that I just cant seem to figure out.
try {
int count =1;
FileReader fr = new FileReader("InventoryReport.txt");
BufferedReader br = new BufferedReader(fr);
String str;
while ((str = br.readLine()) != null) {
br.close();
} catch (IOException e) {
if(count == 3) {
System.out.printIn("The program will now stop executing.");
System.exit(0);
count++;
}
}
Despite your best intentions you are in fact missing a '}'. Note that you haven't escaped the Try block before the catch. I imagine this is because you confused the closing } for the while statement as the closing } for the try block. Do this instead:
try {
int count =1;
FileReader fr = new FileReader("InventoryReport.txt");
BufferedReader br = new BufferedReader(fr);
String str;
while ((str = br.readLine()) != null) {
br.close();
}
}
catch (IOException e) {
if(count == 3) {
System.out.printIn("The program will now stop executing.");
System.exit(0);
count++;
}
}
Also, your indentation is ALL OVER THE PLACE. This should be a lesson to you in why you should format your code properly! It is so easy to miss simple syntax errors like that if you're not formatting properly. It's also hard for others to read your code and figure out what's wrong with it.

Replacing text from a file in Java

I've been trying to create a simple program, in java, that replaces some words into a file. To change the text into the file I created, I create a String and set it to the file text:
Path path = Paths.get("somePath/someFile.someExtension");
Charset charset = StandardCharsets.UTF_8;
String s = new String(Files.readAllBytes(path), charset);
EDIT: To save to the file with s, I used Files.write(path, s.getBytes(charset));.
Then I change the String with commands like s.replaceAll("A", "B"). But now, I'm stuck. I want to make a more complicated then just replacing "A" with "B". I'll try to explain has best I can:
I need to find at the file if wall someNumber someNumer someNumber is in there, and if there are three arguments (someNumber someNumber someNumber), then get the value of "someNumber" at the center. For example:
If the commands are:
wall 200 500 100
wall 200 500 100
Then I want to get the argument from the center (in the first case 500 and in the second 500), and store it into a variable, then delete it from the String. After that, on the top of these commands (in the example wall 200 500 100 wall 200 500 100), I want to write:
usemtl texture
ceil (someNumber that we stored, in the case, 500)
Note that if the arguments wall wall don't have any kind of separation (for example #other wall), then the someNumber at the center will be equal (500 and 500 are equal). So, the command below will just appear per group (if wall wall wall... isn't separed with #other wall, for example).
Other example, this would be the file before / after:
Before:
wall 100 300 50
wall 100 300 100
wall 100 300 400
After:
usemtl texture
ceil 300
wall 100 50
wall 100 100
wall 100 400
So, how can I make this replace?
Please answer! I have no idea how!
EDIT: question to #Roan, owner of most of this code:
Now, after the answers #Roan code transformed into:
package com.fileConverter.main;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import javax.swing.JFileChooser;
public class FileReplace extends JFileChooser {
private static final long serialVersionUID = -254322941935132675L;
private static FileReplace chooser = new FileReplace();
public static void main(String[] args) {
chooser.showDialog(chooser, "Open");
}
public void cancelSelection() {
System.exit(0);
}
public void approveSelection() {
super.approveSelection();
System.out.println("starting...");
// The path were your file is
String path = chooser.getSelectedFile().getAbsolutePath();
File file = new File(path);
// try to create an inputstream from the file
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
} catch (FileNotFoundException e) {
// If we are here the file is not found
e.printStackTrace();
}
// make it a buffered reader
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(fis));
// to store the current line
String line;
// array to store the different words
String[] words;
// create a second temporally file that will replace the original file
File file2 = new File(chooser.getSelectedFile().getParentFile()
+ "$$$$$$$$$$$$$$$.tmp");
try {
file.createNewFile();
} catch (IOException e1) {
e1.printStackTrace();
}
// and create the streams
FileOutputStream file2Os = null;
try {
file2Os = new FileOutputStream(file2);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
PrintWriter writer = new PrintWriter(file2Os);
try {
System.out.println("replacing code...");
writer.println("mtllib textures.mtl");
// loop through all lines and
while ((line = bufferedReader.readLine()) != null) {
line = line
.replace("//", "#")
.replace("(", "wall")
.replace(")", "\n")
.replace("{", "")
.replace("}", "")
.replace("# brush from cube",
"room cube" + countWords(line, "cube"))
.replace(" NULL 0 0 0 1 1 0 0 0", "")
.replace("\"classname\"", "")
.replace("\"worldspawn\"", "");
// get all the diffent terms
words = line.split(" ");
// see if there are 4 terms in there: wall x x x
// and if the first term equals wall28
// and if the middle number is the number you want to delete
// if not just copy the line over
if (words.length == 4 && words[0].contains("wall")) {
double doubleVal = Double.parseDouble(words[2]);
int val = (int) doubleVal;
// now modify the line by removing the middel number
String newLine = words[0] + " " + words[1] + " " + words[3];
String valInsert = null;
if (val >= 0)
valInsert = "\n" + "usemtl texture" + "\n" + "ceil "
+ val;
else if (val < 0)
valInsert = "\n" + "usemtl texture" + "\n" + "floor "
+ val;
// write this to the new file
writer.println(valInsert);
writer.println(newLine);
} else {
// copy the old line
writer.println(line);
}
}
} catch (IOException e) {
e.printStackTrace();
}
// close our resources
writer.close();
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
// now we rename the temp file and replace the old file
// with the new file with the new content
file.delete();
file2.renameTo(file);
System.out.println("done!");
}
public int countWords(String string, String word) {
int lastIndex = 0;
int count = 0;
while (lastIndex != -1) {
lastIndex = string.indexOf(word, lastIndex);
if (lastIndex != -1) {
count++;
lastIndex += word.length();
}
}
return count;
}
}
The problem is that this part doesn't make any replaces:
if (words.length == 4 && words[0].contains("wall")) {
double doubleVal = Double.parseDouble(words[2]);
int val = (int) doubleVal;
// now modify the line by removing the middel number
String newLine = words[0] + " " + words[1] + " " + words[3];
String valInsert = null;
if (val >= 0)
valInsert = "\n" + "usemtl texture" + "\n" + "ceil "
+ val;
else if (val < 0)
valInsert = "\n" + "usemtl texture" + "\n" + "floor "
+ val;
// write this to the new file
writer.println(valInsert);
writer.println(newLine);
}
How can I fix it? Other thing, this part is suppose to create a number that grows after checking how many times cube is wrote, but it doesn't works too :(
.replace("# brush from cube", "room cube" + countWords(line, "cube"))
The countWords method:
public int countWords(String string, String word) {
int lastIndex = 0;
int count = 0;
while (lastIndex != -1) {
lastIndex = string.indexOf(word, lastIndex);
if (lastIndex != -1) {
count++;
lastIndex += word.length();
}
}
return count;
}
Many Thanks
Ok I'm very unsure if I understood this correctly.
This is my interpretation of wat your question is:
You have a file with lines that say: wall [number] [number] [number]
Now you want to check if there there are 3 numbers and then delete the middle number if it's the number you're searching for.
So I would do this like this:
Befor you run the programm you'll need a folder on your C: drive with the name "text" and inside that folder you'll need a file called text.txt with you format in it so: for example:
wall 123 300 320
If you change the value of number you can specify wich number the middle number has to be in oder for it to be deleted.
public class FileReplace {
public static void main(String[] args){
//The path were your file is
String path = "C:\\text\\text.txt";
File file = new File(path);
//The number you want to delete
int number = 300;
//try to create an inputstream from the file
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
} catch (FileNotFoundException e) {
//If we are here the file is not found
e.printStackTrace();
}
//make it a buffered reader
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fis));
//to store the current line
String line;
//array to store the different words
String[] words;
//create a second temporally file that will replace the original file
File file2 = new File("C:\\text\\$$$$$$$$$$.tmp");
try {
file.createNewFile();
} catch (IOException e1) {
e1.printStackTrace();
}
//and create the streams
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file2);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
PrintWriter writer = new PrintWriter(fos);
try {
//loop through all lines and
while((line = bufferedReader.readLine()) != null){
//get all the diffent terms
words = line.split(" ");
//see if there are 4 terms in there: wall x x x
//and if the first term equals wall
//and if the middle number is the number you want to delete
//if not just copy the line over
if(words.length == 4 && words[0].equals("wall") && words[2].equals(String.valueOf(number))){
//now modify the line by removing the middel number
String newLine = words[0] + " " + words[1] + " " + words[3];
//write this to the new file
writer.println(newLine);
}else{
//copy the old line
writer.println(line);
}
}
} catch (IOException e) {
e.printStackTrace();
}
//close our resources
writer.close();
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
//now we rename the temp file and replace the old file
//with the new file with the new content
file.delete();
file2.renameTo(file);
}
}
If you have ay questions about this code feel free to ask them.
Oh and also you might need to run this with administrator right as it uses files.
Hope this helps.
To analyse a string and see if it matches ("wall" number number number), you can use a REGEX expression: see the doc here.
To use the regex expression, just apply .matches() on your String variable and it'll return true or false depending on if the format is verified.
If the format is verified, then just use the SubString function, specify the start and end index so you get the middle number.
To take it out, you could do the opposite. SubString the start (everything until middle number), then SubString the end (everything after the middle number), and then create a new string using those 2.
A simple solution without using (explicitly) regex is to split the String using token (in your case it's a white space.
line = "wall 100 300 50";
String[] words = line.split("\\s+");
You can then get the words[2] convert to an int etc. Then you can write back to a new file (or the same if you have read all file contents).
Regex are more powerful but to me a bit more intimidating so you can pick whatever matches your needs.
You could use this to count the number of occurances of a word in a string:Try 1:
public static int countWords(String string, String word) {
//get all individual words
String[] terms = string.split(" ");
//this variable counts how many times word occurs
int count = 0;
//a count variable for the loop
int counter = 0;
//loop through all the words and if we see a word that equals word we add one to the count variable
while(counter < terms.length){
//check if the term equals the word
if(terms[counter].equals(word)){
//the term matched add one to the count variable
count++;
}
counter++;
}
//return the number of occurrences
return count;
}
Try 2:
public static String countWords(String string, String word) {
//get all individual words
String[] terms = string.split(" ");
//this variable counts how many times word occurs
int count = 0;
//a count variable for the loop
int counter = 0;
StringBuffer sb = new StringBuffer();
sb.append("1");
//loop trough all the words and if we see a word that equals word we add one to the count variable
while(counter < terms.length){
//check if the term equals the word
if(terms[counter].equals(word)){
//the term matched add one to the count variable
count++;
sb.append(" " + word + (count + 1));
}
counter++;
}
//return the number of occurrences
return sb.toString();
}<br><br>
Try 3: you need to have a static variable in your code called lastVar:
static int lastVar = 0;
public static String countWords(String string, String word) {
//get all individual words
String[] terms = string.split(" ");
//this variable counts how many times word occurs
int count = 0;
//a count variable for the loop
int counter = 0;
StringBuffer sb = new StringBuffer();
sb.append("1");
//loop trough all the words and if we see a word that equals word we add one to the count variable
while(counter < terms.length){
//check if the term equals the word
if(terms[counter].equals(word)){
//the term matched add one to the count variable
count++;
sb.append(" " + word + (count + 1 + lastVar));
}
counter++;
}
lastVar += count + 1;
//return the number of occurrences
return sb.toString();
}
That should work.
Hope this helps :D.
To reformat your cube lines you could use:
Try 1:
// loop through all lines and
while ((line = bufferedReader.readLine()) != null) {
if(line.contains("// brush from cube")){
line = line.replace("// brush from cube ", "").replace("(", "").replace(")", "");
String[] arguments = line.split("\\s+");
line = "cube" + Cube + " usemtl texture ceil " + arguments[2] + " wall " + arguments[1] + " " + arguments[3] + " usemtl texture floor " + arguments[5] + " wall " + arguments[4] + " " + arguments[6];
Cube++;
}
line = line
.replace("//", "#")
.replace("(", "wall")
.replace(")", "\n")
.replace("{", "")
.replace("}", "")
.replace(" NULL 0 0 0 1 1 0 0 0", "")
.replace("\"classname\"", "")
.replace("\"worldspawn\"", "");
try 2:
// loop through all lines and
while ((line = bufferedReader.readLine()) != null) {
if(line.contains("// brush from cube")){
line = line + bufferedReader.readLine() + " " + bufferedReader.readLine();
line = line.replace("// brush from cube ", "").replace("(", "").replace(")", "");
String[] arguments = line.split("\\s+");
line = "cube" + Cube + " usemtl texture ceil " + arguments[2] + " wall " + arguments[1] + " " + arguments[3] + " usemtl texture floor " + arguments[5] + " wall " + arguments[4] + " " + arguments[6];
Cube++;
}
line = line
.replace("//", "#")
.replace("(", "wall")
.replace(")", "\n")
.replace("{", "")
.replace("}", "")
.replace(" NULL 0 0 0 1 1 0 0 0", "")
.replace("\"classname\"", "")
.replace("\"worldspawn\"", "");
P.S. I've only posted the important part. You should be able to see where in the code this goes. Also you need to have a static int called cube somewhere in you code like:
static int Cube = 1;
That should be it if it doesn't work let me know! :D

Find file with the most update information

I have a list of log files, and I need to find which one has a latest edition of a specific line, and all or none could have this line.
The lines in the files look like this:
2013/01/06 16:01:00:283 INFO ag.doLog: xxxx xxxx xxxx xxxx
And I need a line lets say
xx/xx/xx xx:xx:xx:xxx INFO ag.doLog: the line i need
I know how to get an array of files, and if I scan backwards I could find the latest latest line in each file (if it exists).
Biggest problem is that the file could be big (2k lines?) and I want to find the line in a relative fast way (a few seconds), so I am open for suggestion.
Personal ideas:
If a file has the line at X time, then any file that has not found the line before X time should not be scan anymore. This will require to search all files at the same time, which i dont know how.
Atm the code breaks, and I suppose if lack of memory.
Code:
if(files.length>0) { //in case no log files exist
System.out.println("files.length: " + files.length);
for(int i = 0; i < files.length; i++) { ///for each log file look for string
System.out.println("Reading file: " + i + " " + files[i].getName());
RandomAccessFile raf = new RandomAccessFile(files[i].getAbsoluteFile(), "r"); //open log file
long lastSegment = raf.length(); //Finds how long is the files
lastSegment = raf.length()-5; //Sets a point to start looking
String leido = "";
byte array[] = new byte[1024];
/*
* Going back until we find line or file is empty.
*/
while(!leido.contains(lineToSearch)||lastSegment>0) {
System.out.println("leido: " + leido);
raf.seek(lastSegment); //move the to that point
raf.read(array); //Reads 1024 bytes and saves in array
leido = new String(array); //Saves what is read as a string
lastSegment = lastSegment-15; //move the point a little further back
}
if(lastSegment<0) {
raf.seek(leido.indexOf(lineToSearch) - 23); //to make sure we get the date (23 characters long) NOTE: it wont be negative.
raf.read(array); //Reads 1024 bytes and saves in array
leido = new String(array); //make the array into a string
Date date = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH).parse(leido.substring(0, leido.indexOf(" INFO "))); //get only the date part
System.out.println(date);
//if date is bigger than the other save file name
}
}
}
I find the code difficult to verify. One could split the task in a backwards reader, which reads lines from file end to start. And use that for parsing dates line wise.
Mind, I am not going for nice code, but something like this:
public class BackwardsReader implements Closeable {
private static final int BUFFER_SIZE = 4096;
private String charset;
private RandomAccessFile raf;
private long position;
private int readIndex;
private byte[] buffer = new byte[BUFFER_SIZE];
/**
* #param file a text file.
* #param charset with bytes '\r' and '\n' (no wide chars).
*/
public BackwardsReader(File file, String charset) throws IOException {
this.charset = charset;
raf = new RandomAccessFile(file, "r");
position = raf.length();
}
public String readLine() throws IOException {
if (position + readIndex == 0) {
raf.close();
raf = null;
return null;
}
String line = "";
for (;;) { // Loop adding blocks without newline '\n'.
// Search line start:
boolean lineStartFound = false;
int lineStartIndex = readIndex;
while (lineStartIndex > 0) {
if (buffer[lineStartIndex - 1] == (byte)'\n') {
lineStartFound = true;
break;
}
--lineStartIndex;
}
String line2;
try {
line2 = new String(buffer, lineStartIndex, readIndex - lineStartIndex,
charset).replaceFirst("\r?\n?", "");
readIndex = lineStartIndex;
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(BackwardsReader.class.getName())
.log(Level.SEVERE, null, ex);
return null;
}
line = line2 + line;
if (lineStartFound) {
--readIndex;
break;
}
// Read a prior block:
int toRead = BUFFER_SIZE;
if (position - toRead < 0) {
toRead = (int) position;
}
if (toRead == 0) {
break;
}
position -= toRead;
raf.seek(position);
raf.readFully(buffer, 0, toRead);
readIndex = toRead;
if (buffer[readIndex - 1] == (byte)'\r') {
--readIndex;
}
}
return line;
}
#Override
public void close() throws IOException {
if (raf != null) {
raf.close();
}
}
}
And a usage example:
public static void main(String[] args) {
try {
File file = new File(args[0]);
BackwardsReader reader = new BackwardsReader(file, "UTF-8");
int lineCount = 0;
for (;;) {
String line = reader.readLine();
if (line == null) {
break;
}
++lineCount;
System.out.println(line);
}
reader.close();
System.out.println("Lines: " + lineCount);
} catch (IOException ex) {
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
}
}

Categories

Resources