I have the following Text:
1
(some text)
/
2
(some text)
/
.
.
/
8519
(some text)
and I want to split this text into several text-files where each file has the name of the number before the text i.e. (1.txt, 2.txt) and so on, and the content of this file will be the text.
I tried this code
BufferedReader br = new BufferedReader(new FileReader("(Path)\\doc.txt"));
try {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
// sb.append(System.lineSeparator());
line = br.readLine();
}
String str = sb.toString();
String[] arrOfStr = str.split("/");
for (int i = 0; i < arrOfStr.length; i++) {
PrintWriter writer = new PrintWriter("(Path)" + arrOfStr[i].charAt(0) + ".txt", "UTF-8");
writer.println(arrOfStr[i].substring(1));
writer.close();
}
System.out.println("Done");
} finally {
br.close();
}
this code works for files 1-9. However, things go wrong for files 10-8519 since I took the first number in the string (arrOfStr [i].charAt(0)) I know my solution is insufficient any suggestions?
In addition to my comment, considering there isn't a space between the leading integer and the first word, the substring at the first space doesn't work.
This question/answer has a few options that should help, the one using regex (\d+) being the simplest one imo, and copied below.
Matcher matcher = Pattern.compile("\\d+").matcher(arrOfStr[i]);
matcher.find();
int yourNumber = Integer.valueOf(matcher.group());
Given a string find the first embedded occurrence of an integer
As you mentioned, the problem is that you only take the first digit. You could enumerate the first characters until you find a non digit character ( arrOfStr[i].charAt(j) <'0' || arrOfStr[i].charAt(j) > '9' ) but it shoud be easier to user a Scanner and an appropriate regexp.
int index = new Scanner(arrOfStr[i]).useDelimiter("\\D+").nextInt();
The delimiter is precisely any group of non-digit character
Here is a quick solution for the given problem. You can test and do proper exception handling.
package practice;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.List;
public class FileNioTest {
public static void main(String[] args) {
Path path = Paths.get("C:/Temp/readme.txt");
try {
List<String> contents = Files.readAllLines(path);
StringBuffer sb = new StringBuffer();
String folderName = "C:/Temp/";
String fileName = null;
String previousFileName = null;
// Read from the stream
for (String content : contents) {// for each line of content in contents
if (content.matches("-?\\d+")) { // check if it is a number (based on your requirement)
fileName = folderName + content + ".txt"; // create a file name with path
if (sb != null && sb.length() > 0) { // this means if content present to write in the file
writeToFile(previousFileName, sb); // write to file
sb.setLength(0); // clearing buffer
}
createFile(fileName); // create a new file if number found in the line
previousFileName = fileName; // store the name to write content in previous opened file.
} else {
sb.append(content); // keep storing the content to write in the file.
}
System.out.println(content);// print the line
}
if (sb != null && sb.length() > 0) {
writeToFile(fileName, sb);
sb.setLength(0);
}
} catch (IOException ex) {
ex.printStackTrace();// handle exception here
}
}
private static void createFile (String fileName) {
Path newFilePath = Paths.get(fileName);
if (!Files.exists(newFilePath)) {
try {
Files.createFile(newFilePath);
} catch (IOException e) {
System.err.println(e);
}
}
}
private static void writeToFile (String fileName, StringBuffer sb) {
try {
Files.write(Paths.get(fileName), sb.toString().getBytes(), StandardOpenOption.APPEND);
}catch (IOException e) {
System.err.println(e);
}
}
}
Related
Hi I'm reading file (please, use the link to see the file) that contains this rows:
U+0000
U+0001
U+0002
U+0003
U+0004
U+0005
using this code
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
public class fgenerator {
public static void main(String[] args) {
try(BufferedReader br = new BufferedReader(new FileReader(new File("C:\\UNCDUNCD.txt")))){
String line;
String[] splited;
while ((line = br.readLine()) != null){
splited = line.split(" ");
System.out.println(splited[0]);
}
}catch(Exception e) {
e.printStackTrace();
}
}
}
but output is
U+D01C
U+D01D
U+D01E
U+D01F
U+D020
U+D021
why does this happen?
how to get the char of its code
change line datatype to char, if doesnt work then String.getBytes()
I am assuming that you want to take the Unicode representation that is on each line of the file and output the actual Unicode character which the code represents.
If we start with your loop that reads each line from the file...
while ((line = br.readLine()) != null){
System.out.println( line );
}
... then what we want to do is convert the input line to the character, and print that ...
while ((line = br.readLine()) != null){
System.out.println( convert(line) ); <- I just put a method call to "convert()"
}
So, how do you convert(line) into a character before printing it?
As my earlier comment suggested, you want to take the numeric string that follows the U+ and convert it to an actual numeric value. That, then, is the character value you want to print.
The following is a complete program — essentially like yours but I take the filename as an argument rather than hard-coding it. I've also added skipping blank lines, and rejecting invalid strings -- printing a blank space instead.
Reject the line if it does not match the U+nnnn form of a Unicode representation — match against "(?i)U\\+[0-9A-F]{4}", which means:
(?i) - ignore case
U\\+ - match U+, where the + has to be escaped to be a literal plus
[0-9A-F] - match any character 0-9 or A-F (ignoring case)
{4} - exactly 4 times
With your update that includes a linked sample file, which includes # comments, I have modified my original program (below) so it will now strip comments and then convert the remaining representation.
This is a complete program that can be run as:
javac Reader2.java
java Reader2 inputfile.txt
I tested it with a subset of your file, starting inputfile.txt at line 1 with U+0000 and ending at line 312 with U+0138
import java.io.*;
public class Reader2
{
public static void main(String... args)
{
final String filename = args[0];
try (BufferedReader br = new BufferedReader(
new FileReader(new File( filename ))
)
)
{
String line;
while ((line = br.readLine()) != null) {
if (line.trim().length() > 0) { // skip blank lines
//System.out.println( convert(line) );
final Character c = convert(line);
if (Character.isValidCodePoint(c)) {
System.out.print ( c );
}
}
}
System.out.println();
}
catch(Exception e) {
e.printStackTrace();
}
}
private static char convert(final String input)
{
//System.out.println("Working on line: " + input);
if (! input.matches("(?i)U\\+[0-9A-F]{4}(\\s+#.*)")) {
System.err.println("Rejecting line: " + input);
return ' ';
}
else {
//System.out.println("Accepting line: " + input);
}
// else
final String stripped = input.replaceFirst("\\s+#.*$", "");
final Integer cval = Integer.parseInt(stripped.substring(2), 16);
//System.out.println("cval = " + cval);
return (char) cval.intValue();
}
}
Original program that assumed a line consisted only of U+nnnn is here.
You would run this as:
javac Reader.java
java Reader input.txt
import java.io.*;
public class Reader
{
public static void main(String... args)
{
final String filename = args[0];
try (BufferedReader br = new BufferedReader(
new FileReader(new File( filename ))
)
)
{
String line;
while ((line = br.readLine()) != null) {
if (line.trim().length() > 0) { // skip blank lines
//System.out.println( line );
// Write all chars on one line rather than one char per line
System.out.print ( convert(line) );
}
}
System.out.println(); // Print a newline after all chars are printed
}
catch(Exception e) { // don't catch plain `Exception` IRL
e.printStackTrace(); // don't just print a stack trace IRL
}
}
private static char convert(final String input)
{
// Reject any line that doesn't match U+nnnn
if (! input.matches("(?i)U\\+[0-9A-F]{4}")) {
System.err.println("Rejecting line: " + input);
return ' ';
}
// else convert the line to the character
final Integer cval = Integer.parseInt(input.substring(2), 16);
//System.out.println("cval = " + cval);
return (char) cval.intValue();
}
}
Try it using this as your input file:
U+0041
bad line
U+2718
U+00E9
u+0073
Redirect standard error when you run it java Reader input.txt 2> /dev/null or comment out the line System.err.println...
You should get this output: A ✘és
I have a java program that can read multiple files and replace values accordingly. However, I am struggling to apply a condition to it and apply the changes only when a certain condition is met. For example, if the file contains this specific character ':20:' then apply the changes otherwise leave the text file as it is.
The problem here is, since I don't have fields to look for to apply the condition accordingly I don't know how these can be applied to such a text file which contains just data like : (12345555555) 233344 100 :20:aaa.
I also looked at using the contains() method to look into the file to find the value I want then apply the changes but couldn't make it work.
public class TextFm
{
public static void main(String[] args)
{
File folder = new File("C:\\tmp");
File[] listOfFiles = folder.listFiles();
for(File file : listOfFiles)
{
replaceText(file);
}
}
public static void replaceText(File file)
{
try
{
BufferedReader reader = new BufferedReader(new FileReader(file));
String line = "", oldtext = "";
while ((line = reader.readLine()) != null)
{
oldtext = oldtext + line + System.lineSeparator();
}
reader.close();
String replacedtext = oldtext.replaceAll("100", "200");
FileWriter writer = new FileWriter(file);
writer.write(replacedtext);
writer.close();
System.out.println("Done");
} catch (IOException ioe)
{
ioe.printStackTrace();
}
}
}
Using contains() method will work fine in this case. You can do that like this:
String line = "", oldtext = "";
while ((line = reader.readLine()) != null)
{
oldtext = oldtext + line + System.lineSeparator();
}
reader.close();
if(oldtext.contains(":20:")) {
String replacedtext = oldtext.replaceAll("100", "200");
FileWriter writer = new FileWriter(file);
writer.write(replacedtext);
writer.close();
System.out.println("Done");
}
public static void replaceText(File file)
{
try
{
Charset charset = Charsets.defaulCharset();
String oldText = new String(Files.readAllBytes(file.toPath()),
charset);
if (!oldText.contains(":20")) {
return;
}
if (!oldText.matches("(?s).*you (idiot|unspeakable).*")) {
return;
}
String replacedtext = oldtext.replace("100", "200");
replacedtext = replacedtext .replaceAll("\\d", "X"); // Digit X-ed out
if (!replacedText.equals(oldText)) {
Files.write(file.toPath(), replacedText.getBytes(charset));
}
System.out.println("Done");
} catch (IOException ioe)
{
ioe.printStackTrace();
}
}
For speed one should not collect the file contents with a String and +. Better use a StringBuilder, or the very nice Files class.
Finding text goes either by contains or by a regular expression match.
Replacement can be done by either too.
The replace, replaceFirst and replaceAll methods return the original string when nothing could be replaced.
Regex (?s) lets . (=any char) also match line breaks.
I have a text file named "message.txt" which is read using Buffer Reader. Each line of the text file contains both "word" and "meaning" as given in this example:
"PS:Primary school"
where PS - word, Primary school - meaning
When the file is being read, each line is tokenized to "word" and "meaning" from ":".
If the "meaning" is equal to the given input string called "f_msg3", "f_msg3" is displayed on the text view called "txtView". Otherwise, it displays "f_msg" on the text view.
But the "if condition" is not working properly in this code. For example if "f_msg3" is equal to "Primary school", the output on the text view must be "Primary school". But it gives the output as "f_msg" but not "f_msg3". ("f_msg3" does not contain any unnecessary strings.)
Can someone explain where I have gone wrong?
try {
BufferedReader file = new BufferedReader(new InputStreamReader(getAssets().open("message.txt")));
String line = "";
while ((line = file.readLine()) != null) {
try {
/*separate the line into two strings at the ":" */
StringTokenizer tokens = new StringTokenizer(line, ":");
String word = tokens.nextToken();
String meaning = tokens.nextToken();
/*compare the given input with the meaning of the read line */
if(meaning.equalsIgnoreCase(f_msg3)) {
txtView.setText(f_msg3);
} else {
txtView.setText(f_msg);
}
} catch (Exception e) {
txtView.setText("Cannot break");
}
}
} catch (IOException e) {
txtView.setText("File not found");
}
Try this
............
meaning = meaning.replaceAll("\\s+", " ");
/*compare the given input with the meaning of the read line */
if(meaning.equalsIgnoreCase(f_msg3)) {
txtView.setText(f_msg3);
} else {
txtView.setText(f_msg);
}
............
Otherwise comment the else part, then it will work.
I don't see any obvious error in your code, maybe it is just a matter
of cleaning the string (i.e. removing heading and trailing spaces, newlines and so on) before comparing it.
Try trimming meaning, e.g. like this :
...
String meaning = tokens.nextToken();
if(meaning != null) {
meaning = meaning.trim();
}
if(f_msg3.equalsIgnoreCase(meaning)) {
txtView.setText(f_msg3);
} else {
txtView.setText(f_msg);
}
...
A StringTokenizer takes care of numbers (the cause for your error) and other "tokens" - so might be considered to invoke too much complexity.
String[] pair = line.split("\\s*\\:\\s*", 2);
if (pair.length == 2) {
String word = pair[0];
String meaning = pair[1];
...
}
This splits the line into at most 2 parts (second optional parameter) using a regular expression. \s* stands for any whitespace: tabs and spaces.
You could also load all in a Properties. In a properties file the format key=value is convention, but also key:value is allowed. However then some escaping might be needed.
ArrayList vals = new ArrayList();
String jmeno = "Adam";
vals.add("Honza");
vals.add("Petr");
vals.add("Jan");
if(!(vals.contains(jmeno))){
vals.add(jmeno);
}else{
System.out.println("Adam je už v seznamu");
}
for (String jmena : vals){
System.out.println(jmena);
}
try (BufferedReader br = new BufferedReader(new FileReader("dokument.txt")))
{
String aktualni = br.readLine();
int pocetPruchodu = 0;
while (aktualni != null)
{
String[] znak = aktualni.split(";");
System.out.println(znak[pocetPruchodu] + " " +znak[pocetPruchodu + 1]);
aktualni = br.readLine();
}
br.close();
}
catch (IOException e)
{
System.out.println("Nezdařilo se");
}
try (BufferedWriter bw = new BufferedWriter(new FileWriter("dokument2.txt")))
{
int pocetpr = 0;
while (pocetpr < vals.size())
{
bw.write(vals.get(pocetpr));
bw.append(" ");
pocetpr++;
}
bw.close();
}
catch (IOException e)
{
System.out.println("Nezdařilo se");
}
I have a file with the following format.
.I 1
.T
experimental investigation of the aerodynamics of a
wing in a slipstream . 1989
.A
brenckman,m.
.B
experimental investigation of the aerodynamics of a
wing in a slipstream .
.I 2
.T
simple shear flow past a flat plate in an incompressible fluid of small
viscosity .
.A
ting-yili
.B
some texts...
some more text....
.I 3
...
".I 1" indicate the beginning of chunk of text corresponding to doc ID1 and ".I 2" indicates the beginning of chunk of text corresponding to doc ID2.
what I need is read the text between ".I 1" and ".I 2" and save it as a separate file like "DOC_ID_1.txt" and then read the text between ".I 2" and ".I 3"
and save it as a separate file like "DOC_ID_2.txt" and so on. lets assume that the number of .I # is not known.
I have tried this but cannot finish it. any help will be appreciated
String inputDocFile="C:\\Dropbox\\Data\\cran.all.1400";
try {
File inputFile = new File(inputDocFile);
FileReader fileReader = new FileReader(inputFile);
BufferedReader bufferedReader = new BufferedReader(fileReader);
String line=null;
String outputDocFileSeperatedByID="DOC_ID_";
//Pattern docHeaderPattern = Pattern.compile(".I ", Pattern.MULTILINE | Pattern.COMMENTS);
ArrayList<ArrayList<String>> result = new ArrayList<> ();
int docID =0;
try {
StringBuilder sb = new StringBuilder();
line = bufferedReader.readLine();
while (line != null) {
if (line.startsWith(".I"))
{
result.add(new ArrayList<String>());
result.get(docID).add(".I");
line = bufferedReader.readLine();
while(line != null && !line.startsWith(".I")){
line = bufferedReader.readLine();
}
++docID;
}
else line = bufferedReader.readLine();
}
} finally {
bufferedReader.close();
}
} catch (IOException ex) {
Logger.getLogger(ReadFile.class.getName()).log(Level.SEVERE, null, ex);
}
You want to find the lines which match "I n".
The regex you need is : ^.I \d$
^ indicates the beginning of the line. Hence, if there are some whitespaces or text before I, the line will not match the regex.
\d indicates any digit. For the sake of simplicty, I allow only one digit in this regex.
$ indicates the end of the line. Hence, if there are some characters after the digit, the line will not match the expression.
Now, you need to read the file line by line and keep a reference to the file in which you write the current line.
Reading a file line by line is much easier in Java 8 with Files.lines();
private String currentFile = "root.txt";
public static final String REGEX = "^.I \\d$";
public void foo() throws Exception{
Path path = Paths.get("path/to/your/input/file.txt");
Files.lines(path).forEach(line -> {
if(line.matches(REGEX)) {
//Extract the digit and update currentFile
currentFile = "File DOC_ID_"+line.substring(3, line.length())+".txt";
System.out.println("Current file is now : currentFile);
} else {
System.out.println("Writing this line to "+currentFile + " :" + line);
//Files.write(...);
}
});
Note : In order to extract the digit, I use a raw "".substring() which I consider as evil but it is easier to understand. You can do it in a better way with a Pattern and a Matcher :
With this regex : ".I (\\d)". (The same as before but with parenthesis which indicates what you will want to capture). Then :
Pattern pattern = Pattern.compile(".I (\\d)");
Matcher matcher = pattern.matcher(".I 3");
if(matcher.find()) {
System.out.println(matcher.group(1));//display "3"
}
Look up regex, Java has inbuilt libraries for this.
https://docs.oracle.com/javase/tutorial/essential/regex/
http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html
These links will give you a starting point, effectively you can use counter to perform a pattern match against the string and store anything between the first pattern match and the second pattern match. This information can be output to a separate file using the Formatter class.
Found here:-
http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
public class Test {
/**
* #param args
* #throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
String inputFile="C:\\logs\\test.txt";
BufferedReader br = new BufferedReader(new FileReader(new File(inputFile)));
String line=null;
StringBuilder sb = new StringBuilder();
int count=1;
try {
while((line = br.readLine()) != null){
if(line.startsWith(".I")){
if(sb.length()!=0){
File file = new File("C:\\logs\\DOC_ID_"+count+".txt");
PrintWriter writer = new PrintWriter(file, "UTF-8");
writer.println(sb.toString());
writer.close();
sb.delete(0, sb.length());
count++;
}
continue;
}
sb.append(line);
}
} catch (Exception ex) {
ex.printStackTrace();
}
finally {
br.close();
}
}
}
I am implementing a RPN calculator in Java and need help creating a class to parse the equations into separate tokens.
My input file will have an unknown number of equations similar to the ones shown below:
49+62*61-36
4/64
(53+26)
0*72
21-85+75-85
90*76-50+67
46*89-15
34/83-38
20/76/14+92-15
I have already implemented my own generic stack class to be used in the program, but I am now trying to figure out how to read data from the input file. Any help appreciated.
I've posted the source code for my stack class at PasteBin, in case it may help.
I have also uploaded the Calculator with no filereading to PasteBin to show what I have done already.
I have now managed to get the file read in and the tokens broken up thanks for the help. I am getting an error when it reaches the end of the file and was wondering how to solve that?
Here is the code:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.StringTokenizer;
public class TestClass {
static public void main(String[] args) throws IOException {
File file = new File("testEquations.txt");
String[] lines = new String[10];
try {
FileReader reader = new FileReader(file);
BufferedReader buffReader = new BufferedReader(reader);
int x = 0;
String s;
while((s = buffReader.readLine()) != null){
lines[x] = s;
x++;
}
}
catch(IOException e){
System.exit(0);
}
String OPERATORS = "+-*/()";
for (String st : lines) {
StringTokenizer tokens = new StringTokenizer(st, OPERATORS, true);
while (tokens.hasMoreTokens()) {
String token = tokens.nextToken();
if (OPERATORS.contains(token))
handleOperator(token);
else
handleNumber(token);
}
}
}
private static void handleNumber(String token) {
System.out.println(""+token);
}
private static void handleOperator(String token) {
System.out.println(""+token);
}
}
Also How would I make sure the RPN works line by line? I am getting quite confused by the algorithms I am trying to follow.
Because all of the operators are single characters, you can instruct StringTokenizer to return them along with the numeric tokens.
String OPERATORS = "+-*/()";
String[] lines = ...
for (String line : lines) {
StringTokenizer tokens = new StringTokenizer(line, OPERATORS, true);
while (tokens.hasMoreTOkens()) {
String token = tokens.nextToken();
if (OPERATORS.contains(token))
handleOperator(token);
else
handleNumber(token);
}
}
As your question has now changed completely from it's original version - this is in response to your original one, which was how to use FileReader to get the values from your file.
This will put each line into a separate element of a String array. You should probably use an ArrayList instead, as it's far more flexible, but I have just done this as a quick demo - you can clean it up as you wish, although I notice the code you are using expects a String array as it's input. Perhaps you could read the values initially into an ArrayList, then copy that to an array once you have all the lines - that way you can put as many lines in as you wish and keep your code flexible for changes in the number of lines in your input file.
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class TestClass {
static public void main(String[] args) {
File file = new File("myfile.txt");
String[] lines = new String[10];
try {
FileReader reader = new FileReader(file);
BufferedReader buffReader = new BufferedReader(reader);
int x = 0;
String s;
while((s = buffReader.readLine()) != null){
lines[x] = s;
x++;
}
}
catch(IOException e){
//handle exception
}
// And just to prove we have the lines right where we want them..
for(String st: lines)
System.out.println(st);
}
}
You mentioned before that you were using the code on this link:
http://www.technical-recipes.com/2011/a-mathematical-expression-parser-in-java/#more-1658
This appears to already deal with operator precedence doesn't it? And with parsing each String from the array and sorting them into numbers or operators? From my quick look it at least it appears to do that.
So it looks like all you need is for your lines to be in a String array, which you then pass to the code you already have. From what I can see anyway.
Obviously this doesn't address the issue of numbers greater than 9, but hopefully it helps with the first half.
:-)
public void actionPerformed(ActionEvent e) {
double sum=0;
int count = 0 ;
try {
String nomFichier = "Fichier.txt";
FileReader fr = new FileReader(nomFichier);
BufferedReader br = new BufferedReader(fr);
String ligneLue;
do {
ligneLue = br.readLine();
if(ligneLue != null) {
StringTokenizer st = new StringTokenizer(ligneLue, ";");
String nom = st.nextToken();
String prenom = st.nextToken();
String age = st.nextToken();
String tele = st.nextToken();
String adress = st.nextToken();
String codePostal = st.nextToken();
String ville = st.nextToken();
String paye = st.nextToken();
double note = Double.parseDouble(st.nextToken());
count++;
}
}
while(ligneLue != null);
br.close();
double mediane = count / 2;
if(mediane % 2 == 0) {
JOptionPane.showMessageDialog(null, "Le mediane dans le fichier est " + mediane);
}
else {
mediane +=1;
JOptionPane.showMessageDialog(null, "Le mediane dans le fichier est " + mediane);
}
}//fin try
catch(FileNotFoundException ex) {
System.out.println(ex.getMessage());
}
catch(IOException ex) {
System.out.println(ex.getMessage());
}
}