I'm trying to write a function that grabs a certain part of a file, sends that to another function, then continue to do the same thing from where the BufferedReader left off until the end of the file but can't seem to figure out how to make it work.
Here is what I have:
String str = "";
int count = 0;
try {
while(//condition so it loops through the entire file. I've tried fileReader.ready() and fileReader.read != -1 but both just run into infinite loops){
while ((count < 4)){
str += fileReader.read();
count++;
fileReader.mark(1000);
}
fileReader.reset();
DoSomething(str) // send str to another function and do something with it;
}
} catch (IOException e) {
// TODO Auto-generated catch block
}
Can someone help me with this and explain what I'm doing wrong? Much would be appreciated
If you know the number of characters, use the BufferedReader's .skip(long) method, which tells it to skip the first long characters (where long is a 64-bit whole number).
The call to skip will return a long with the number of characters actually skipped.
The mark() method marks position in the file and you can specify how many bytes you want to read before calling reset(), which would reposition stream to the marked point. So, normally you need to call mark() at the beginning of your data and then call reset before next iteration.
while (count < 4){
if(count>0) {
fileReader.reset();
}
fileReader.mark(1000);
str += fileReader.read();
count++;
}
The following works for me. Edited after comment.
import java.io.*;
public class Test {
public static void main(String[] args) {
String str = "";
int count = 0;
try {
Reader fileReader = new BufferedReader(new FileReader("testfile"));
fileReader.mark(5);
while(fileReader.ready()){
count = 0;
str ="";
fileReader.reset();
while (count < 4 && fileReader.ready()){
if (count == 1){
fileReader.mark(5);
}
str += (char)fileReader.read() ;
count++;
}
System.out.println(str); // send str to another function and do something with it;
}
} catch (IOException e) {
// TODO Auto-generated catch block
}
}
}
Note that you need to cast fileReader.read(); to a char or you'll get wrong output, you have to reset the count otherwise count<4 won't be true ever after the first run (and since you don't do fileReader.read(), you'll get in an infitite loop), and you have to test for ready on each read (or you might block)
EDIT: Obviously, this is an example. You should never do the straight str += something in a loop, but use a StringBuffer, and catch and handle the possible exception.
Note on the second edit: if this is an intensive procedure, this is doing it wrong. I'll see if I can do it right (without backtracking)
YET ANOTHER EDIT:
import java.io.*;
public class Test {
public static void main(String[] args) {
StringBuffer buffer = new StringBuffer();
int length = 4;
try {
Reader fileReader = new BufferedReader(new FileReader("teststring"));
for (int i = 0; i < length && fileReader.ready(); i++) {
buffer.append((char) fileReader.read());
}
while (fileReader.ready()) {
System.out.println(buffer); // send str to another function and do
// something with it;
buffer.deleteCharAt(0);
buffer.append((char) fileReader.read());
}
System.out.println(buffer); // send str to another function and do
// something with it;
}
catch (IOException e) {
// TODO Auto-generated catch block
}
}
}
The repeated call to the method that does something still isn't pretty, but this is a lot closer.
I think you just need to reset count = 0 after DoSomething(Str). Right now you're never resetting your count variable and it's preventing you from entering the file read loop.
Why mark and reset at all? Just read 4 bytes, process them, and repeat until EOF.
Based on Martijns answer I made the code a little simpler.
package so4168937;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
public class SecondTry {
static void consume(Reader rd, int length) throws IOException {
StringBuilder sb = new StringBuilder();
int c;
for (int i = 0; i < length - 1; i++) {
if ((c = rd.read()) == -1)
return;
sb.append((char) c);
}
while ((c = rd.read()) != -1) {
sb.append((char) c);
System.out.println("<" + sb + ">");
sb.deleteCharAt(0);
}
}
public static void main(String[] args) throws IOException {
consume(new StringReader("hi my name is joe"), 4);
}
}
You don't need to use mark or reset, and using ready only adds complexity and unwanted behavior.
i see that most of you prefer to use the FileReader, as the question asked for, but i just prefer to use the Scanner instead because i find it easier to use.
so here is my example:
import java.util.Scanner;
import java.io.File;
private void fileReader(){
String str;
try {
input = new Scanner(new File("FILENAME"));
} catch (Exception e) {
System.out.println("Scanner load failed.");
}
while(input.hasNext()){
str+=input.next()+" ";
}
input.close();
int j=0;
for(int i=3;i<str.length();i++){
DoSomething(str.substring(j,i));
j++;
}
}
this reads each line and adds it to the string, and then it sends the string in bites of 4 to the DoSomething method.
i hope it helps.
Edit1:
removed this edit.
Edit2:
did just read that you wanted in the comments.. and that can be done easily with any code actually i will change my code at the top to reflect this change.
hmm .. yeah.. that should work .. :)
My idea is to define a CharConsumer that defines what it means to consume a bunch of characters. Then I wrote a method that takes an arbitrary Reader and reads it until the end. If you want another terminating condition, replace the while (true) with it.
If you need the input to the consume method to be buffered, be sure that you create exactly one BufferedReader and don't use the other reader anymore after that. Otherwise some characters may get lost while reading.
package so4168937;
import java.io.EOFException;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
public class Main {
// unused, since the question was initially unclear
public static void consumeFourInARow(Reader rd, CharConsumer consumer) throws IOException {
char[] chars = new char[4];
while (true) {
for (int i = 0; i < chars.length; i++) {
int c = rd.read();
if (c == -1) {
if (i == 0)
return;
throw new EOFException("Incomplete read after " + i + " characters.");
}
chars[i] = (char) c;
}
consumer.consume(chars);
}
}
public static void consume(Reader rd, CharConsumer consumer) throws IOException {
char[] chars = new char[4];
int c;
for (int i = 0; i < chars.length; i++) {
if ((c = rd.read()) == -1) {
return;
}
chars[i] = (char) c;
}
consumer.consume(chars);
while ((c = rd.read()) != -1) {
System.arraycopy(chars, 1, chars, 0, chars.length - 1);
chars[chars.length - 1] = (char) c;
consumer.consume(chars);
}
}
interface CharConsumer {
void consume(char[] chars);
}
public static void main(String[] args) throws IOException {
final StringBuilder sb = new StringBuilder();
consume(new StringReader("hi my name is joe..."), new CharConsumer() {
#Override
public void consume(char[] chars) {
sb.append('<');
sb.append(chars);
sb.append('>');
}
});
System.out.println(sb.toString());
}
}
Update [2010-11-15]: Replaced the old code with code that implements a simple cyclic buffer, which is apparently what was wanted in the original question.
Related
The problem with my code is, sometimes it reads and compares the string without any issue but again it also throws errors when comparing other strings. I think my comparing function isn't performing enough to the mark, where do I need to set the code efficiently so that my comparison function works efficiently?
can someone please suggest to me something? so far I have tried comparing two files using bufferedreader. my code works to some extent but at the same time encounters an error
"Exception in thread "main"
java.lang.StringIndexOutOfBoundsException:"
I have a few pictures which describe my problem intuitively. I think my findtarget function isn't accurate enough which is why it keeps throwing these exceptions
ERROR : click here to view the image.
NO-ERROR : click here to view the image.
and here is my two files which contains positive and negative keywords.
NEGITIVE : file extention is negi.txt
POSITIVE : file extention is posi.txt
here is the findtarget function which is used to compare the strings.
public static int findTarget(String target, String source)
{
int target_len = target.length();
int source_len = source.length();
int add = 0;
// this function check the character whether it is present.
for (int i = 0; i < source_len; ++i) // i is a varialbe used to count upto source_len.
{
int j = 0; // take another variable to count loops
//int[] k = new int[100];
while (add == 0)
{
if (j >= target_len) // count upto target length
{
break;
}
else if (target.charAt(j) != source.charAt(i + j))
{
break;
}
else
{
++j;
if (j == target_len)
{
add++; // this will return 1: true
}
}
}
}
return add;
//System.out.println(""+add);
}
here is my entire code just incase if you wanna run them.
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
import java.io.FileWriter;
public class test {
public static int findTarget(String target, String source)
{
int target_len = target.length();
int source_len = source.length();
int add = 0;
// this function check the character whether it is present.
for (int i = 0; i < source_len; ++i) // i is a varialbe used to count upto source_len.
{
int j = 0; // take another variable to count loops
//int[] k = new int[100];
while (add == 0)
{
if (j >= target_len) // count upto target length
{
break;
}
else if (target.charAt(j) != source.charAt(i + j))
{
break;
}
else
{
++j;
if (j == target_len)
{
add++; // this will return 1: true
}
}
}
}
return add;
//System.out.println(""+add);
}
public static void main(String... args)
{
// function 1
//this variable can be called from any place inside this main function.
int testing1 = 0;
int testing2 = 0;
try {
//reads user review and store them inside source1
Scanner sc = new Scanner(System.in);
System.out.println("Enter your review: ");
String source1 = sc.nextLine();
//establising a file object
File file = new File("posi.txt");
BufferedReader br1 = new BufferedReader(new FileReader(file));
//establising a file object
File file2 = new File("negi.txt");
BufferedReader br2 = new BufferedReader(new FileReader(file2));
String target1; // using a string variable to read the content of the file posi.txt
while ((target1 = br1.readLine()) != null) //as long the condition is not null it will keep printing.
{
testing1 += test.findTarget(target1, source1); // supplying two arguments to findtarget function.
}
String target2; // using a string variable to read the content of the file negi.txt
while ((target2 = br2.readLine()) != null) //as long the condition is not null it will keep printing.
{
testing2 += test.findTarget(target2, source1); // supplying two arguments to findtarget function.
}
br1.close(); br2.close();
System.out.println("positive is:"+testing1 +"\nnegative is :"+testing2); //-not going to print now! :D-
System.out.println("\nthank you for your feedback! :)");
}
catch (IOException e)
{
System.out.println("file error!");
}
// this function is an area where it stores the return value inside a file called pos.txt
try
{
FileWriter myWriter = new FileWriter("pos.txt",true);
// using the true condition makes the line move to the next line.
myWriter.write(" "+testing1);
myWriter.close();
}
catch (IOException e)
{
System.out.println("An error occurred.");
}
// writing neg inside a file called neg.txt
try
{
FileWriter myWriter = new FileWriter("neg.txt",true);
// using the true condition makes the line move to the next line.
myWriter.write(" "+testing2);
myWriter.close();
}
catch (IOException e)
{
System.out.println("An error occurred.");
}
// to evaluate an output based on highest count.
if(testing1 > testing2)
System.out.println("it is positive");
else if (testing1 == testing2)
System.out.println("it is neutral");
else
System.out.println("it is negative");
}
}
finally, I was able to solve the problem by using one of string method known as "regionmatches". Note: make sure your positive and negative files are arranged in an alphabetical sequence. This will give you an accurate increment.
Github : use my link to download the positive and negative keywords.
public static int findTarget(String target, String source) //method/function
{
String sourcee = source;
String targett = target;
int source_len = sourcee.length();
int target_len = targett.length();
/*
**this function check the character whether it is present using one of string methond called "regionmatch"
**regionMatches(int toffset, String other, int ooffset,int len)
*/
int add = 0;
boolean foundIt = false;
for (int i = 0;i <= source_len - 1;i++)
{
if (sourcee.regionMatches(i, targett, 0, target_len))
{
foundIt = true;
break;
}
}
//checking
if(!foundIt)
{
// do nothing.
}
else
{
add++;
}
return add; //returns incrementation
}
You increment i to the lenght of source but you call
.
.
.
else if (target.charAt(j) != source.charAt(i + j))
.
.
.
which exceeds the lenght of source at some point.
Lets say i == source.length, then source.charAt(i + j) throws an exception as soon as j > 0.
I'm having some issues with arduino. In class, we are learning arduino/java communication. Thus, we are asked to interpret bytes sent from the arduino and write it out in the console of eclipse as whatever type the "key" of the message tells us to write it in.
As of now, I'm just testing input streams, but I can't seem to get a complete message ever. This is what I'm doing:
public void run() throws SerialPortException {
while (true) {
if (port.available()) { //code written in another class, referenced below
byte byteArray[] = port.readByte(); //also code written in another class, referenced below
char magicNum = (char) byteArray[0];
String outputString = null;
for (int i = 0; i < byteArray.length; ++i) {
char nextChar = (char) byteArray[i];
outputString += Character.toString(nextChar);
}
System.out.println(outputString);
}
}
}
below is the code from the other class that is used in the above code
public boolean available() throws SerialPortException {
if (port.getInputBufferBytesCount() == 0) {
return false;
}
return true;
}
public byte[] readByte() throws SerialPortException {
boolean debug= true;
byte bytesRead[] = port.readBytes();
if (debug) {
System.out.println("[0x" + String.format("%02x", bytesRead[0]) + "]");
}
return bytesRead;
}
It is not possible to know when data is going to be available, nor whether input data is going to be available all at once rather than in several chunks.
This is a quick and dirty fix:
public void run() throws SerialPortException {
String outputString = "";
while (true) {
if (port.available()) {
byte byteArray[] = port.readByte();
for (int i = 0; i < byteArray.length; ++i) {
char nextChar = (char) byteArray[i];
if (nextChar == '\n') {
System.out.println(outputString);
outputString = "";
}
outputString += Character.toString(nextChar);
}
}
}
}
The declaration of outputString is moved out, and it is assigned "" so to get rid of that ugly null on standard output.
Each time \n is encountered in the serial input data, the content of outputString is printed on standard output first and cleared afterwards.
I have been trying to find the total number of tabs and single space characters with using the code below. So if i use this
if (c[i] == '\t') {
++tabcount;
}
it gives tabCount = 0, also if i want to get number of single space characters using this
if (c[i] == ' ') {
++singlescpacecount;
}
it gives total number of white spaces in the whole file.
Code for tabCount is
public static void TabCount(String filename) throws IOException{
int tabcount = 0;
InputStream is = new BufferedInputStream(new FileInputStream(filename));
try {
byte[] c = new byte[1024];
int readChars = 0;
while ((readChars = is.read(c)) != -1) {
for (int i = 0; i < readChars; ++i) {
if (c[i] == '\t') {
++tabcount;
}
}
}
System.out.println("The total number of tabcounts are :" + tabcount);
} finally {
is.close();
}
}
Thanks in advance.
At least part of the issue must be that the OP's input file does not contain tabs as expected. As noted by #Andreas, the basic code structure does count tabs. However, I had suggested ensuring the file is not iterated multiple times for counting various characters. Here is one implementation on how to do that. It is not optimal, but suggestive.
/**
* A class to accumulate results
*/
static class Results
{
private int tabs = 0;
private int spaces = 0;
public void incTabCount()
{
++tabs;
}
public void incSpaceCount()
{
++spaces;
}
public int getTabCount()
{
return tabs;
}
public int getSpaceCount()
{
return spaces;
}
#Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("tabs: ");
sb.append(tabs);
sb.append("\nspaces: ");
sb.append(spaces);
return sb.toString();
}
}
/**
* Iterate the file once, checking for all desired characters,
* and store in the Results object
*/
public static Results countInFile(String filename) throws IOException
{
// create results
Results res = new Results();
InputStream is = new BufferedInputStream(new FileInputStream(filename));
try {
byte[] c = new byte[1024];
int readChars = 0;
while ((readChars = is.read(c)) != -1) {
for (int i = 0; i < readChars; ++i) {
// see if we have a tab
if (c[i] == '\t') {
res.incTabCount();
}
// see if we have a space
if (c[i] == ' ') {
res.incSpaceCount();
}
}
}
} finally {
is.close();
}
return res;
}
public static void main(String[] args)
{
Results res;
try {
res = countInFile("f:/tmp/test.txt");
System.out.println(res);
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Input file (the tab is after the word "has" in the first line):
This line has\ta tab.
And there are 7 spaces?
Based upon an input file, the results are as expected:
tabs: 1
spaces: 7
Edit: as an aside, there is a modification that would be ultimately more testable. If one were to separate the File handling from the counting in an input stream, then one could more easily feed a known input to the system. For example, modifying the above slightly:
/**
* Counts in a stream the number of tabs and spaces, and returns
* the Results
*/
private static Results countInStream(InputStream is) throws IOException
{
// create results
Results res = new Results();
try {
byte[] c = new byte[1024];
int readChars = 0;
while ((readChars = is.read(c)) != -1) {
for (int i = 0; i < readChars; ++i) {
// see if we have a tab
if (c[i] == '\t') {
res.incTabCount();
}
// see if we have a space
if (c[i] == ' ') {
res.incSpaceCount();
}
}
}
}
finally {
}
return res;
}
This method may have a String passed to it:
String s = "This\thas\ttabs.\nAs well as spaces";
InputStream is = new ByteArrayInputStream(s.getBytes("UTF8"));
res = countInStream(is);
System.out.println(res);
Since it is now much easier to test the main logic, one can clearly see the base counting operates as expected. The countInFile method suggest above may be modified to open the InputStream from the file, and then call the countInStream(). Such an approach would reduce the debate about whether the logic of the method is at issue, or the contents sent to the method.
So far, I have this code, which, in summary, takes two text files and a specified block size in cmd and standardises the txt files, and then puts them into blocks based on the specified block size.
import java.io.*;
import java.util.*;
public class Plagiarism {
public static void main(String[] args) throws Exception {
//you are not using 'myPlag' anywhere, you can safely remove it
// Plagiarism myPlag = new Plagiarism();
if (args.length == 0) {
System.out.println("Error: No files input");
System.exit(0);
}
String foo = null;
for (int i = 0; i < 2; i++) {
BufferedReader reader = new BufferedReader(new FileReader(args[i]));
foo = simplify(reader);
// System.out.print(foo);
int blockSize = Integer.valueOf(args[2]);
List<String> list = new ArrayList<String>();
for (int k = 0; k < foo.length() - blockSize + 1; k++) {
list.add(foo.substring(k, k + blockSize));
}
// System.out.print(list);
}
}
public static String simplify(BufferedReader input)
throws IOException {
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = input.readLine()) != null) {
sb.append(line.replaceAll("[^a-zA-Z]", "").toLowerCase());
}
return sb.toString();
}
}
The next thing I would like to do is use Horner's polynomial accumulation method (with set value x = 33) to convert each of these blocks into a hash code. I am completely stumped on this and would appreciate some help from you guys!
Thanks for reading, and thanks in advance for any advice given!
Horner's method for hash generation is as simple as
int hash=0;
for(int i=0;i<str.length();i++)
hash = x*hash + str.charAt(i);
I want to sort a input.txt file and save it in output.txt for instance. I use the insertion sort algorithm. Now my problem: the compareTo method seems to work incorrectly (or at least not how I want to to work). It returns integer greater than 1 thus the algorithm does not really especially for negative numbers. I hope you guys can help me with that problem, thanks!
Thats my code:
import java.util.ArrayList;
import java.io.*;
class Isort
{
public static void main(String[] args)
{
if(args[0].equals("int"))
{
ArrayList<Integer> array = new ArrayList<Integer>();
sort(array, args[1], args[2]);
}
else if(args[0].equals("float"))
{
ArrayList<Float> array = new ArrayList<Float>();
sort(array, args[1], args[2]);
}
else if(args[0].equals("String"))
{
ArrayList<String> array = new ArrayList<String>();
sort(array, args[1], args[2]);
}
else
{
//do nothing
}
}
public static <T extends Comparable<T>> void sort(ArrayList<T> array, String input, String output)
{
try
{
File file = new File(input);
BufferedReader reader = new BufferedReader(new FileReader(file));
reader.mark((int)file.length() + 1);
int count = 0;
while(reader.readLine() != null)
{
count++;
}
reader.reset();
for(int i = 0; i<count; i++)
{
array.add((T)(reader.readLine()));
}
reader.close();
int j;
T temp;
for(int i = 1; i < array.size(); i++)
{
j = i;
while(j > 0 && array.get(j-1).compareTo(array.get(j)) > 0)
{
temp = array.get(j);
array.set(j,array.get(j-1));
array.set(j-1,temp);
j -= 1;
System.out.println(array);
}
}
PrintWriter writer = new PrintWriter(output);
for(int i = 0; i<array.size(); i++)
{
writer.write(String.valueOf(array.get(i)));
writer.write(System.getProperty ("line.separator"));
}
writer.flush();
writer.close();
}
catch(FileNotFoundException e)
{
}
catch(IOException e)
{
e.printStackTrace();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
I believe you are confused by the use of generics. You are making generic ArrayLists of Integer, Long and String. You are then reading a line of text and attempting to cast it to T.
This will not do anything at runtime due to type-erasure. In all of the cases above (int, long and string) you will be passing an ArrayList<Object> and adding String to the list. When you read the String from the file the cast doesn't do anything except cast it to an Object which String already is. So unless the compareTo of String matches your requirements for int and long this will not work.
In reply to comment...
That's the point. Casting to T or really using generics at all in this case don't do what you need. In all cases you are reading and comparing String. Instead you need to have three methods readInt, readLong and readString and call the appropriate one based on what you are expecting. One option would be to use an interface of readNextValue and pass in an appropriate implementation depending on the situation.
I suggest you to using a "Comparator" class in "Collections.sort(...)" method. You can find an example here-> http://www.vogella.com/blog/2009/08/04/collections-sort-java/.