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/.
Related
I am very new to programming and I am attempting to modify a heap algorithm that I found online. From a previous question, I was able to get the code to work with a PrintWriter, but when attempting to use this function as a method in another class, I get an error because of the constructor. How can this code be modified to work the same, simply without a constructor?
I am not very familiar with programming, so I have tried looking at previous questions. Somehow, I thought of using a nested class (not sure how they work), but to no avail. The method worked when it was in its own class.
// Should be within a class
private PrintWriter _pw;
// This is the part that needs to go.
public HeapAlgo(PrintWriter pw) {
this._pw = pw;
}
public void heapPermutation(String a[], int size, int n) throws IOException {
// if size becomes 1 then prints the obtained
// permutation
if (size == 1)
for (int i=0; i<n; i++) {
System.out.println(a[i] + "");
this._pw.println(a[i] + "");
}
for (int i=0; i<size; i++) {
heapPermutation(a, size-1, n);
// if size is odd, swap first and last
// element
if (size % 2 == 1) {
String temp = a[0];
a[0] = a[size-1];
a[size-1] = temp;
}
// If size is even, swap ith and last
// element
else {
String temp = a[i];
a[i] = a[size-1];
a[size-1] = temp;
}
}
}
public void heap() throws IOException
{
FileWriter fw = new FileWriter("note.txt");
PrintWriter pw = new PrintWriter(fw);
File temp = new File("code.txt");
Scanner file = new Scanner(temp);
String substring = "";
String a[] = new String[4];
a[0] = "" + file.nextLine();
a[1] = "" + file.nextLine();
a[2] = "" + file.nextLine();
a[3] = "" + file.nextLine();
HeapAlgo obj = new HeapAlgo(pw); // Pass in a writer
obj.heapPermutation(a, a.length, a.length);
pw.close();
}
When I run the methods inside a large class I get an error saying \
"error: invalid method declaration; return type required".
Any Help would be greatly appreciated. Thanks.
Edit: I am trying to code this constructor:
public CodeRunner()
{
random();
HeapAlgo.heap(//not sure if anything should go here);
algorithm();
}
where random() creates random strings, and the algorithm function performs an algorithm on all possible iterations of the random string. I am trying to make objects for each set of random strings.
It seems like the following elements should be within a class called HeapAlgo:
The private variable declaration
private PrintWriter _pw;
The constructor itself
public HeapAlgo(PrintWriter pw)
The heapPermutation function
public void heapPermutation(String a[], int size, int n) throws IOException
The last remaining method, heap(), should be placed in some other class (possibly where your main() function is) and called from there.
Alternatively, you could indeed use an inner class. Wrap all the code you provided in a class (maybe called Heap) then wrap the aforementioned three elements in an inner class called HeapAlgo. Something like this (I very quickly typed this up, so there may be errors you need to fix):
public class HeapUtil {
public class HeapAlgo {
private PrintWriter _pw;
// This is the part that needs to go.
public HeapAlgo(PrintWriter pw) {
this._pw = pw;
}
public PrintWriter getPrintWriter(){
return _pw;
}
public void heapPermutation(String a[], int size, int n) throws IOException {
// if size becomes 1 then prints the obtained
// permutation
if (size == 1)
for (int i=0; i<n; i++) {
System.out.println(a[i] + "");
this._pw.println(a[i] + "");
}
for (int i=0; i<size; i++) {
heapPermutation(a, size-1, n);
// if size is odd, swap first and last
// element
if (size % 2 == 1) {
String temp = a[0];
a[0] = a[size-1];
a[size-1] = temp;
}
// If size is even, swap ith and last
// element
else {
String temp = a[i];
a[i] = a[size-1];
a[size-1] = temp;
}
}
}
}
public static HeapAlgo heap() throws IOException
{
FileWriter fw = new FileWriter("note.txt");
PrintWriter pw = new PrintWriter(fw);
File temp = new File("code.txt");
Scanner file = new Scanner(temp);
String substring = "";
String a[] = new String[4];
a[0] = "" + file.nextLine();
a[1] = "" + file.nextLine();
a[2] = "" + file.nextLine();
a[3] = "" + file.nextLine();
HeapAlgo obj = new HeapAlgo(pw); // Pass in a writer
obj.heapPermutation(a, a.length, a.length);
return obj;
}
}
Note that in this case, if you would like to use HeapAlgo outside of this class file, you will need to use Heap.HeapAlgo.
Edit: Try out the code above (I edited it). There may be a few errors since I didn't actually run it.
Usage is as follows:
public CodeRunner(){
random();
// heapAlgo is the heap object
HeapAlgo heapAlgo = HeapUtil.heap();
// this gives you access to the PrintWriter inside the HeapAlgo
PrintWriter printWriter = heapAlgo.getPrintWriter();
// do your other stuff
algorithm();
}
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 have the below insertion sort function below, previously I was working with strictly an integer array and called the function below as a means of sorting it. Now in the below function, what I want to do is sort this function based on a file of arbitrary data. AM not entirely sure how to approach this. I tried writing the function and including the file path within the function but am guessing that is not entirely correct. Any suggestions on how to approach this correctly?
public static void InsertionSort(int filename[], int size) {
int index, count;
int temp;
index = 1;
Scanner sca = null;
try {
sca = new Scanner(new File(
"C:/Users/Frank/Downloads/wb1913_samp1040.txt"));
while (sca.hasNextLine()) {
while (index < size) {
temp = filename[index];
count = index;
while (count >= 0 && temp <= filename[count - 1]) {
filename[count] = filename[count - 1];
--count;
}
filename[count] = temp;
index++;
}
}
} catch (FileNotFoundException exception) {
} finally {
sca.close();
}
Updated Code:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Scanner;
public class Driver {
public static void main(String[] args) {
Scanner scanner = null;
String file = "C:/Users/jdavis/Downloads/wb1913_samp1040.txt";
int count;
Word word = new Word();
LinkedList WordList = new LinkedList();
String[] f = {file};
try {
scanner = new Scanner(new File(
"C:/Users/jdavis/Downloads/wb1913_samp1040.txt"));
while (scanner.hasNextLine()) {
String[] Word = scanner.nextLine().split("\t");
word.setWord(Word[0]);
word.setPartsofSpeech(Word[1]);
word.setDefinition(Word[2]);
WordList.InsertAtBack(word);
WordList.Display();
System.out.println("Before sorting: " +Arrays.toString(f));
//sort array
InsertionSort(f);
System.out.println("After sorting: ");
printArray(f);
}
} catch (FileNotFoundException exception) {
} finally {
// scanner.close();
}
count = WordList.CountList();
System.out.println(count);
}
public static void InsertionSort(Comparable[] array) {
Comparable temp;
for(int i = 1; i < array.length; i++)
{
temp = array[i];
int j = 0;
for(j = i; j > 0; j--)
if(temp.compareTo(array[j - 1]) < 0)
array[j] = array[j - 1];
else
break;
array[j] = temp;
}
}
public static void printArray(String[] f){
System.out.println(Arrays.toString(f));
}
}
you can use the below sort method after you get your String
public static String[] dictionaryFormString(String[] s)
{
//
// Sort each individual string element by alphabetical order
//
for (int i = 0; i < s.length; i++)
{
String wordSt = s[i];
if(wordSt == null) continue;
char[] word = wordSt.toCharArray();
Arrays.sort(word);
s[i] = new String(word);
}
return s;
}
I'm assuming here that you are challenging yourself (or someone has challenged you) to write an insertion sort of your own, and that you want to insert each element as you read it from a file.
If you just want to read a file and end up with a sorted array, it would be simpler and more efficient to just slurp it into the array out-of-order, then use Arrays.sort(). Except as a learning exercise, programmers very seldom write sort algorithms nowadays.
You can make your programs much easier to understand by breaking them into more methods - each method does less, and so is easier to understand, but put together they are powerful.
So:
private void readIntoSortedArray(Scanner sca, String[] array) {
while (sca.hasNextLine()) {
insertInto(array, sca.nextLine());
}
}
private void insertInto(String[] array, String line) {
int index = findFirstElementGreaterThan(line);
shiftElementsByOne(array, index);
array[index] = line;
}
... and so on. Here I've given you the "middle" of your chain of methods. You will need to write a method higher in the stack, that prepares a Scanner and calls readIntoSortedArray. And you will need to write the methods called by insertInto(). Maybe those will call yet more methods.
This also means that you can write small programs to drive these sub-methods and check that they work as you expect, in isolation.
String[] testArray = new String[]{"Adam", "Brian", "Dave"};
int index = findFirstElementGreaterThan("Clive");
if(index != 2) {
throw new RuntimeException("Index should be 2 - was " + index);
}
This is a short step away from test-driven development, which is a good thing to adopt early in your studies, because it makes things much easier. (JUnit is a very popular tool that does essentially the same thing, nicer).
If, once you've done this, you feel your program has too many tiny methods, you can always "inline" your sub-methods -- but many feel that the right size for a method is absolutely tiny.
I guess you want an alphabetical sort. You can't compare strings with < and > -- you can use string1.compareTo(string2) (there are other, more flexible ways, but this is OK for now).
public static boolean doesKeyStringOccursEarlyInDict(String string,String key){
int i = Math.min(string.length(), key.length());
int j = 0;
while(j<i){
if(string.charAt(j) > key.charAt(j)){
return true;
}
j++;
}
//else return false as either both were equal or key does not come early in dictionary
return false;
}
public static void insertionSort(String[] s){
for(int i=1;i<s.length;i++){
String key = s[i];
int j = i-1;
while(j>=0 && doesKeyStringOccursEarlyInDict(s[j], key)){
s[j+1] = s[j];
j--;
}
s[j+1]=key;
}
}
public static void main(String[] args) {
//read the file each line
//split it and store it in an arraylist of string as it can grow..repeat it till u have read all the content
ArrayList<String> s = new ArrayList<>();
//get the complete string array
String[] stringarr = (String[]) s.toArray();
//example : String[] stringarr = {"def","xyz","abc","aaa"};
insertionSort(stringarr);
for(String words:stringarr)
System.out.println(words);
}
Above I have given the part that you are looking for.You are already able to read file.So just fill in the blanks in the above code.
Also I was not trying to challenge you rather was encouraging to think first then ask.
After incorporating the above I would encourage you to follow the approach mentioned by Slim and Nishanth.
If you have file that contains string and you want to sort it.
One approach could be to create a string array after reading file (assuming it isn't very big file) and then apply sorting.
// Read from file
String[] words = someFunctionThatReadFileAndReturnArrayOfString(file);
Arrays.sort(words); // or your sorting function
for (String word : words)
{
System.out.println(word);
}
If you want your insertionSort function to be more generic so that it will be independent of data type then you can ask for Comparable object from user as a additional parameter to your function and use it to compare objects in your code.
your method signature would be something like this-
public static void InsertionSort(Object list[],Comparator<Object> compare)
I'm trying to write a program that takes an array of 200 numbers (1-200), randomizes them, and then outputs those numbers to a text file.
I've been struggling for the whole day and I can't figure out why nothing is working.
Main method:
public static void main (String[] args)
{
int[] numbers= new int [201];
for (int i=0; i < numbers.length; i++)
{
numbers[i]=i;
}
}//end main method
Randomize method:
public static int[] randomizeArray(int[] numbers)
{
Random gen= new Random(10);
for (int i=0; i < numbers.length; i++)
{
int n= gen.nextInt(200);
numbers[i]=n;
}
return numbers;
}//end randomizeArray method
And the print method:
public static int[] outputArray(int[] numbers) throws IOException
{
FileOutputStream output;
output= new FileOutputStream("RandomOut.txt");
new PrintStream(output).println(randomizeArray(numbers));
output.close();
return numbers;
}//end method outputArray
Any help would be great, I know I'm overlooking something or doing something incorrectly.
Shouldn't you call outputArray at the end of your main method?
One of your problems is the line:
new PrintStream(output).println(randomizeArray(numbers));
This will probably print something like:
[I#10769dd
yes? You need to write a for loop to output the numbers, something like:
for (int i=0; i < numbers.length; i++) {
new PrintStream(output).println(numbers[i]);
}
except that you don't want to create the PrintStream each time in the loop.
Your main method initializes an array of 201 elements (instead of 200), and doesn't do anything with this array. So obviously, there is no randomization and now writing to any file. The main method should call randomizeArray and then outputArray.
The initialization of the array elements in main is useless, since the elements will be reinitialized by the randomizeArray method. This method, by the way, doesn't need to return anything.
Finally, the outputArray method should loop through the array and println each element. The stream should be closed in a finally block. It should not return anything either.
1) you need to use Arrays.toString(int[] arr) to print that array.
2) if you mean to reorder the array input, that requires code tht is very diferent.
otherwise, get rid of the input and use a new array.
3) call your helper methods!
EDIT: added this psuedocode:
boolean[] used=new boolean[200];
make old[] and new[]
for(i=0;i<200;i++){
int n=random number from 0 to 199;
while(used[n]) n=(n+1)%200;
new[i]=old[n];
used[n]=true;
}
return new;
Couldn't resist...
String filename = "random200.txt";
List<Integer> numbers = new ArrayList<Integer>();
for (int i = 1; i < 201; i++)
{
numbers.add(i);
}
StringBuilder sb = new StringBuilder();
while (!numbers.isEmpty())
{
int position = new SecureRandom().nextInt(numbers.size());
Integer randomNumber = numbers.remove(position);
sb.append(randomNumber + "\n");
}
try
{
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename), "UTF8"));
out.append(sb.toString());
out.close();
}
catch (Exception ex)
{
throw new RuntimeException(ex);
}
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.