I'm reading data from the input stream where string in two different formats.
One is with a header that is:
Scale id,Rec.No,Date,Time,Bill No.,Item No.,Plu,Name,Qty,Rate,Amount,Void
0,142,17/01/21,17:50,053,3848,001,POTATO ,0.615,50.00,30.75,N
0,143,17/01/21,17:50,053,3849,002,POTATO P ,0.985,36.00,35.46,N
0,144,17/01/21,17:50,053,3850,003,ONION P ,1.550,15.00,23.25,N
Second format is without header:
001,1234560,POTATO ,0,000,K,50.00,15.258,#
002,1234561,POTATO P ,0,000,K,36.00,15.258,#,0.00
003,1234562,ONION P ,0,000,K,15.00,15.258,#,0.00
004,1234563,BR. CHU.CHU. ,0,000,K,28.00,15.258,#,0.00
005,1234564,BR. ROUND ,0,000,K,24.00,15.258,#,0.00
I want to parse these two different formats in two different methods.
Logic and the logic I have used:
public void getReportResponse()throws IOException {
BufferedReader br = null;
str = new StringBuffer();
int bytes = 0;
byte[] packetBytes = new byte[256];
try {
br = new BufferedReader(new InputStreamReader(mmInStream));
String line="";
while ((line = br.readLine()) != null) {
// line = line.trim();
//dataparse.Data(s);
Log.i("DATA in getReportResponse", line);
if (line.matches("Scale id,Rec.No,Date,Time,Bill No.,Item No.,Plu,Name,Qty,Rate,Amount,Void")) {
do {
bytes = mmInStream.read( packetBytes );//READING THE INPUT STREAM
line = new String( packetBytes, 0, bytes );
// append the string in string buffer
str.append( line );
Log.i( TAG,"Report"+str);
// dataparse.ReportData(str.toString());
line="";
} while (str.length()!=-1);
Log.i( TAG,"REPORT"+str);
dataparse.ReportData(str.toString());//this method is for parse value without header after condition
} else {
String data = line.trim();
dataparse.Data(data);//this is working yes//this one is for passing data without header
// Log.i("DATA",line);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
But 'if' the condition doesn't work please help me
I would check for the header only once and also only check the first header element
//... removed for brevity
br = new BufferedReader(new InputStreamReader(mmInStream));
String line = br.readLine();
if (line != null && line.startsWith("Scale id")) {
handleHeader(line);
line = br.readLine();
}
while (line != null) {
String data = line.trim();
dataparse.Data(data);
line = br.readLine();
}
//... removed for brevity
Note that all code that is for the if condition has been moved into handleHeader
Related
I have a problem with some java code.
I'm returning a text from a method, which is on a .txt file. Then, I'm storing this text to a variable "text" and writing this on another .txt file. But the problem is: this new .txt file gets a new blank line at the bottom. That's because inside my method read, the variable "text" is receiving a "\n". How can I solve this problem?
PS: I'm doing this with educational purposes.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.FileReader;
import java.io.FileWriter;
public class Arquivo {
public static void main(String[] args) {
String text = read("in.txt");
write(text, "out.txt");
System.out.println("Text created!");
}
public static String read(String arquivo) {
String text = "";
try (BufferedReader br = new BufferedReader(new FileReader(arquivo))) {
String line = br.readLine();
while (line != null) {
text += line + "\n";
line = br.readLine();
}
} catch (IOException e) {
System.err.println(e.getMessage());
}
return text;
}
public static void write(String text, String arquivo) {
try (BufferedWriter bw = new BufferedWriter(new FileWriter(arquivo))) {
bw.write(text);
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
}
My two created files "in.txt" and "out.txt".
this is
a text file.
this is
a text file.
(blank line)
please try this:
String line = br.readLine();
while (line != null) {
text += line;
line = br.readLine();
if (line!=null){
text += "\n";
}
}
you can try this variant:
String line;
while((line = br.readLine()) != null) {
text += line;
if (line!=null){
text += "\n";
}
}
A good solution to this type of problem is to add the newline before you write each additional line:
String line = br.readLine();
text += line;
while ((line = br.readLine()) != null) {
text = "\n" + line;
}
This way, you only add the newline for each additional line you write (no extraneous ones at the end). Notice the assignment (plus null check) in the while loop).
replace write(text, "out.txt"); with
write(text.substring(0,text.length()-1), "out.txt");
which will remove the last character, which is the /n before writing.
Store all the strings in a list, then join on the line feed
public static void main( String[] args ) {
String text = read( "in.txt" );
write( text, "out.txt" );
System.out.println( "Text created!" );
}
public static String read( String arquivo ) {
List<String> texts = new ArrayList<>();
try ( BufferedReader br = new BufferedReader( new FileReader( arquivo ) ) ) {
String line = br.readLine();
while ( line != null ) {
texts.add( line );
line = br.readLine();
}
} catch ( IOException e ) {
System.err.println( e.getMessage() );
}
return texts.stream().collect( Collectors.joining( "\n" ) );
}
public static void write( String text, String arquivo ) {
try ( BufferedWriter bw = new BufferedWriter( new FileWriter( arquivo ) ) ) {
bw.write( text );
} catch ( IOException e ) {
System.err.println( e.getMessage() );
}
}
String.trim()
public String trim()
Returns a copy of the string, with leading and
trailing whitespace omitted. If this String object represents an empty
character sequence, or the first and last characters of character
sequence represented by this String object both have codes greater
than '\u0020' (the space character), then a reference to this String
object is returned.
Otherwise, if there is no character with a code greater than '\u0020'
in the string, then a new String object representing an empty string
is created and returned.
Otherwise, let k be the index of the first character in the string
whose code is greater than '\u0020', and let m be the index of the
last character in the string whose code is greater than '\u0020'. A
new String object is created, representing the substring of this
string that begins with the character at index k and ends with the
character at index m-that is, the result of this.substring(k, m+1).
This method may be used to trim whitespace (as defined above) from the
beginning and end of a string.
Returns: A copy of this string with leading and trailing white space
removed, or this string if it has no leading or trailing white space.
https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#trim()
Simply trim the string before you return it from read.
public static String read(String arquivo) {
String text = "";
try (BufferedReader br = new BufferedReader(new FileReader(arquivo))) {
String line = br.readLine();
while (line != null) {
text += line + "\n";
line = br.readLine();
}
} catch (IOException e) {
System.err.println(e.getMessage());
}
return text.trim();
}
Just do not add \n before the last line:
String text = "";
...
String line = br.readLine();
boolean addNewLine = false;
while (line != null) {
if (addNewLine) {
text += "\n";
} else {
addNewLine = true;
}
text += line;
line = br.readLine();
}
Also, for performance improvement, consider using a StringBuilder instead of the string concatenation:
StringBuilder sb = new StringBuilder();
...
String line = br.readLine();
boolean addNewLine = false;
while (line != null) {
if (addNewLine) {
sb.append('\n');
} else {
addNewLine = true;
}
sb.append(line);
line = br.readLine();
}
...
String text = sb.toString();
try(BufferedReader br = new BufferedReader(new FileReader("MANIFEST.MF"))) {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
}
String everything = sb.toString();
System.out.println(everything);
This is what i use to read all text within the file, im curious how i can change this in order for me to read a certain line that contains for example: "Main-Class".
Thanks in advance!
Check to see whether your line variable contains the string you're looking for, then exit the while loop...or do whatever you want with the line. You may also want to change your code to this...a little more concise and readable.
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line);
sb.append(System.lineSeparator());
}
To find first line which contains "Main-Class":
try ( BufferedReader reader = new BufferedReader( new FileReader("MANIFEST.MF")) ) {
String line = null;
while ( ( line = reader.readLine() ) != null ) {
if ( line.contains("Main-Class") ) break;
}
if ( line != null ) {
// line was found
} else {
// line was not found
}
}
To find all lines which contain "Main-Class":
StringBuilder matchedLines = new StringBuilder();
try ( BufferedReader reader = new BufferedReader( new FileReader("MANIFEST.MF")) ) {
String line = null;
while ( ( line = reader.readLine() ) != null ) {
if ( line.contains("Main-Class") ) {
matchedLines.append(line);
matchedLines.append(System.lineSeparator());
}
}
}
// ...
System.out.println("Matched Lines:");
System.out.println(matchedLines.toString());
I'm writing a program in java to search for a list of words(transaction numbers) in a .txt file. The .txt file can have any number of lines.
List<String> transactionList = new ArrayList<String>(
Arrays.asList("JQ7P00049", "TM7P04797", "RT6P70037");
FileReader fileReader = new FileReader(filePath);
BufferedReader bufferedReader = new BufferedReader(fileReader);
try {
String readLine = bufferedReader.readLine();
for (String transactionIndex : transactionList) {
if (readLine != null) {
if (readLine.contains(transactionIndex)) {
System.out.println(transactionIndex + ": true");
readLine = bufferedReader.readLine();
} else {
readLine = bufferedReader.readLine();
}
}
}
}
The programs runs fine except if the word is split between two lines, for example:
-------- JQ7P0
0049----------
that's obviously because the bufferedReader reads line by line and does the comparison of search string with the content present in that line.
Is there any way to handle this scenario?
As durron597 mentioned, you weren't looping through the whole file, but here's a solution that assumes the file has at least 2 lines and that a transaction string doesn't span more than 2 lines.
It concatenates each line with the next, and searches for the strings in the concatenated lines. To prevent the same transaction from being printed twice, I added an additional check.
List<String> transactionList = new ArrayList<String>( Arrays.asList("JQ7P00049", "TM7P04797", "RT6P70037") );
FileReader fileReader = new FileReader(filePath);
BufferedReader bufferedReader = new BufferedReader(fileReader);
try {
// Search the first line
String lastLine = bufferedReader.readLine();
for (String transactionIndex : transactionList) {
if (lastLine.contains(transactionIndex)) {
System.out.println(transactionIndex + ": true");
}
}
String currentLine = null;
// Search the remaining lines
while((currentLine=bufferedReader.readLine()) != null) {
String combined = lastLine + currentLine;
for (String transactionIndex : transactionList) {
if (currentLine.contains(transactionIndex) || (!lastLine.contains(transactionIndex) && combined.contains(transactionIndex))) {
System.out.println(transactionIndex + ": true");
}
}
lastLine = currentLine;
}
} catch ( Exception e ) {
System.out.println( e.getClass().getSimpleName() + ": " + e.getMessage() );
} finally {
bufferedReader.close();
}
This program has a second problem: You aren't going to read all the lines in longer files, because you have no loop that will loop through all the lines in the file.
That said, you can do this by reading two lines at once, and merging them together.
Here's a complete program:
private static final List<String> transactionList = new ArrayList<String>(Arrays.asList(
"JQ7P00049", "TM7P04797", "RT6P70037"));
public static void main(String[] args) throws Exception {
String filePath = "test.txt";
FileReader fileReader = new FileReader(filePath);
BufferedReader bufferedReader = new BufferedReader(fileReader);
try {
String firstLine = bufferedReader.readLine();
String secondLine = bufferedReader.readLine();
if (secondLine == null) {
checkLine(firstLine);
}
do {
String combinedLine = firstLine + secondLine;
checkLine(combinedLine);
firstLine = secondLine;
} while ((secondLine = bufferedReader.readLine()) != null);
} finally {
}
}
private static void checkLine(String combinedLine) {
for (Iterator<String> iterator = transactionList.iterator(); iterator.hasNext();) {
String transactionIndex = iterator.next();
if (combinedLine.contains(transactionIndex)) {
System.out.println(transactionIndex + ": true");
iterator.remove();
}
}
}
Your code seems to not properly read the file, but rather reads as many lines as you have transaction numbers you're looking for. Assuming that this is not what you want, I have corrected it.
Also, I assume that an transaction number can span AT MOST two lines.
List<String> transactionList = new ArrayList<String>(
Arrays.asList("JQ7P00049", "TM7P04797", "RT6P70037"));
FileReader fileReader = new FileReader(filePath);
BufferedReader bufferedReader = new BufferedReader(fileReader);
String[] lastLines = {"",""};
try {
String readLine;
while((readLine = bufferedReader.readLine()) != null) {
lastLines[0] = lastLines[1];
lastLines[1] = readLine;
String combinedLastLines;
combinedLastLines = lastLines[0] + lastLines[1];
for (String transactionIndex : transactionList) {
if (combinedLastLines.contains(transactionIndex) && !lastLines[0].contains(transactionIndex)) {
System.out.println(transactionIndex + ": true");
}
}
}
}
The general idea is to always combine two lines, and look whether the transaction number is in there. Let's have a look at the code:
String[] lastLines = {"",""};
This line defines an array which we will use to store the two most recently read lines.
while((readLine = bufferedReader.readLine()) != null) {
This snippet reads as many lines as there are in your text file.
lastLines[0] = lastLines[1];
lastLines[1] = readLine;
String combinedLastLines;
combinedLastLines = lastLines[0] + lastLines[1];
This code is responsible for replacing the oldest line in the array, and push the currently readLine into the array. Those last two lines are then combined to one String!
if (combinedLastLines.contains(transactionIndex) && !lastLines[0].contains(transactionIndex)) {
Here we are searching the combined lines for the transaction numbers. But: when a transaction number is not spanning multiple lines, we might accidently find it twice. Therefore, the second check is for ensuring we did not find the transaction before.
Hope this is what you're looking for!
I am getting a really long string as the response of the web service I am collecting it in the using the StringBuilder but I am unable to obtain the full value I also used StringBuffer but had no success.
Here is the code I am using:
private static String read(InputStream in ) throws IOException {
//StringBuilder sb = new StringBuilder(1000);
StringBuffer sb = new StringBuffer();
String s = "";
BufferedReader r = new BufferedReader(new InputStreamReader( in ), 1000);
for (String line = r.readLine(); line != null; line = r.readLine()) {
sb.append(line);
s += line;
} in .close();
System.out.println("Response from Input Stream Reader >>>" + sb.toString());
System.out.println("Response from Input S >>>>>>>>>>>>" + s);
return sb.toString();
}
Any help is appreciated.
You can also split the string in array of strings in order to see all of them
String delimiter = "put a delimiter here e.g.: \n";
String[] datas=sb.toString().split(delimiter);
for(String string datas){
System.out.println("Response from Input S >>>>>>>>>>>>" + string);
}
The String may not print entirely to the console, but it is actually there. Save it to a file in order to see it.
I do not think that your input is too big for a String, but only not shown to the console because it doesn't accept too long lines. Anyways, here is the solution for a really huge input as characters:
private static String[] readHugeStream(InputStream in) throws IOException {
LinkedList<String> dataList = new LinkedList<>();
boolean finished = false;
//
BufferedReader r = new BufferedReader(new InputStreamReader(in), 0xFFFFFF);
String line = r.readLine();
while (!finished) {
int lengthRead = 0;
StringBuilder sb = new StringBuilder();
while (!finished) {
line = r.readLine();
if (line == null) {
finished = true;
} else {
lengthRead += line.length();
if (lengthRead == Integer.MAX_VALUE) {
break;
}
sb.append(line);
}
}
if (sb.length() != 0) {
dataList.add(sb.toString());
}
}
in.close();
String[] data = dataList.toArray(new String[]{});
///
return data;
}
public static void main(String[] args) {
try {
String[] data = readHugeStream(new FileInputStream("<big file>"));
} catch (IOException ex) {
Logger.getLogger(StackoverflowStringLong.class.getName()).log(Level.SEVERE, null, ex);
} catch (OutOfMemoryError ex) {
System.out.println("out of memory...");
}
}
System.out.println() does not print all the characters , it can display only limited number of characters in console. You can create a file in SD card and copy the string there as a text document to check your exact response.
try
{
File root = new File(Environment.getExternalStorageDirectory(), "Responsefromserver");
if (!root.exists())
{
root.mkdirs();
}
File gpxfile = new File(root, "response.txt");
FileWriter writer = new FileWriter(gpxfile);
writer.append(totalResponse);
writer.flush();
writer.close();
}
catch(IOException e)
{
System.out.println("Error:::::::::::::"+e.getMessage());
throw e;
}
I have a snippet of code that prints text from a file to a JTextArea called textArea.
Unfortunately the method I'm using goes line by line (not ideal) and so I have to append each line with a \n
This is fine for now but a new line is created at the end.
The code I have is as follows:
class menuOpen implements ActionListener {
public void actionPerformed(ActionEvent e)
{
try {
File filePath = new File("c:\\test.txt");
FileInputStream file = new FileInputStream(filePath);
BufferedReader br = new BufferedReader(new InputStreamReader(file));
String displayText;
while ((displayText = br.readLine()) != null) {
textArea.append(displayText + "\n");
}
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
Can anyone help me get rid of that last line?
how about:
text.substring(0,text.lastIndexOf('\n'));
(...)
FileReader r= new FileReader(filePath);
StringBuilder b=new StringBuilder();
int n=0;
char array[]=new char[1024];
while((n=r.read(array))!=-1) b.append(array,0,n);
r.close();
String content=b.toString();
textArea.setText(content.substring(0,content.lengt()-1);
(...)
Another idea:
boolean firstLine = true;
while ((displayText = br.readLine()) != null) {
if (firstLine) {
firstLine = false;
} else {
textArea.append("\n");
}
textArea.append(displayText);
}
The idea is to append a line break before the new line to display, except for the first line of the file.
The easiest way is to not use BufferedReader.readLine(). For example:
BufferedReader in = new BufferedReader(new FileReader(filePath));
char[] buf = new char[4096];
for (int count = in.read(buf); count != -1; count = in.read(buf)) {
textArea.append(new String(buf, 0, count));
}
EDIT
I should have seen this before, but a much better way is to let the JTextArea read the file:
BufferedReader in = new BufferedReader(new FileReader(filePath));
textArea.read(in, null);
This will still read in the newline at the end, but it will normalize all the line endings in your text (see the javadocs for DefaultEditorKit for an explanation of how line endings are handled). So you can get rid of the trailing newline with something like this:
// line endings are normalized, will always be "\n" regardless of platform
if (textArea.getText().endsWith("\n")) {
Document doc = ta.getDocument();
doc.remove(doc.getLength() - 1, 1);
}
How about
if (textArea.length > 0) textArea.Text = textArea.Text.Substring(0 ,textArea.Text.Length - 1)
Apparently you want a newline between two lines, not after each line. This means you should have at least two lines:
if (d = br.readLine()) != null ) {
textArea.append(displayText);
while (d = br.readLine()) != null ) {
textArea.append( "\n" + displayText);
}
}
Of course, it looks more complex. That's because 'between' is more complex than 'after'.
In your loop:
while ((displayText = br.readLine()) != null) {
if (textArea.length() > 0)
textArea.append("\n");
textArea.append(displayText);
}
i.e. if there is already some text in your textarea, insert a newline.
Its quite easy.. You just need to tweak your code a bit.
String displayText = br.readLine();
textArea.append(displayText);
while ((displayText = br.readLine()) != null) {
textArea.append("\n" + displayText);
}
I believe this code produce your desired function at minimum cost.