This question already has answers here:
Read file contents into an ArrayList
(2 answers)
Closed 6 years ago.
I am attempting to read the flat file and transfer its contents to ArrayList.By the code is not working
flat file
BEG
SN:M7254168
VER:1.10
HC 00002 4077 215
D 4080006441610001
D 8475190354020001
END
public class BigFlatFileProcess {
private static Logger logger = Logger.getLogger(BigFlatFileProcess.class);
public ArrayList<Item> process(String sile) {
ArrayList<Item> huge = new ArrayList<Item>();
ArrayList<Integer> nlist = getLineNo(sile);
try{
for(int i=0; i<=nlist.size();i++){
System.out.println(nlist.get(i)+" "+nlist.get(i+1));
logger.info("File contents are ");
ArrayList<Item> pcom = showLines(sile, nlist.get(i)-1,nlist.get(i+1)-2);
System.out.println(" Number of items in this bin "+pcom.size());
for(int j=0;j<pcom.size();j++){
logger.info("from bigflatfileprocess"+pcom.get(j).toString());
huge.add(pcom.get(j));
}
System.out.println("STARTING ..");
}
}catch(Exception e){
logger.info(" Exception occured in file processing that can be safely ignored");
}
logger.info(" Processed the AML flat file successfully ");
return huge;
}
public ArrayList<Item> showLines( String fileName, int startLine, int endLine){
ArrayList<Item> preList = new ArrayList<Item>();
int currentLineNo = 0;
String line = null;
try(BufferedReader bReader = new BufferedReader(new FileReader(fileName)) ){
Item pre = new Item();
while(currentLineNo<startLine){
if(bReader.readLine()==null){
throw new IOException("File too small");
}
currentLineNo++;
}
for( ;currentLineNo <=endLine;currentLineNo++ ){
line = bReader.readLine();
if(line==null){
return null;
}
if(line.startsWith("H")){
String bnum = line.substring(17,20);
pre.setBin(bnum);
String cnum = line.substring(12,16);
pre.setCycNumber(cnum);
}
if(line.startsWith("D")){
String upcNum = line.substring(4, 16);
pre.setUpcCode(upcNum);
String qty = line.substring(16,20);
pre.setQuantity(Integer.parseInt(qty));
logger.info(line);
logger.info(" The List Bin :"+pre.getBin()+" upcCode: "+pre.getUpcCode()+" Quantity: "+pre.getQuantity()+" cycle = "+pre.getCycNumber());
}
preList.add(pre);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return preList;
}
public ArrayList<Integer> getLineNo(String fileName){
ArrayList<Integer> hlist = new ArrayList<Integer>();
try(LineNumberReader lReader = new LineNumberReader(new FileReader(fileName)) ){
String line;
while((line = lReader.readLine()) != null){
if(line.startsWith("H")||line.startsWith("END")){
int i = lReader.getLineNumber();
logger.info("Line numbers "+i);
hlist.add(i);
}
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return hlist;
}
}
The log is shown in this picture
I cant understand why my for loop is adding the last record to array list.
Any suggestions will be deeply appreciated
From my observation, ur for loop is missing an int variable declaration to define the starting point for the iteration. Second, ur condition states less than or equal to. U should replacing that with a less than < symbol alone. That leave out the last variable. Hope this helps.
Related
Already fixed. Thanks for Mas & ruhul for observing my bugs.
I was trying to read a text file twice, named stationary.txt. The contents of the file has three columns such as the amount, the name of product and the total price.
What I am trying to do first is by averaging each product's price by reading line by line. Then I closed the Buffered and then open it again and read. The second reading takes a variable average and compares each product's price line by line. If line 1 is over the average, then write it into dearer.txt, otherwise write it into cheap.txt
Here is the stationary.txt
1 Highlighter 5.99
2 Pen 9.00
3 Eraser 5.00
4 DrawingPin 2.75
5 Highlighter 10.99
6 FountainPen 20.50
7 Pencil 14.50
Below is the source code
import java.util.*;
import java.io.*;
public class Ques {
public static void main(String[] args) throws FileNotFoundException {
double average = 0;
File inFile = new File("stationary.txt");
FileReader fileReader = new FileReader(inFile);
BufferedReader bufReader = new BufferedReader(fileReader);
File outFilel = new File("dearer.txt");
FileOutputStream outFileStreaml = new FileOutputStream(outFilel);
PrintWriter outStream1 = new PrintWriter(outFileStreaml);
File outFile2 = new File("cheap.txt");
FileOutputStream outFileStream2 = new FileOutputStream(outFile2);
PrintWriter outStream2 = new PrintWriter(outFileStream2);
computeAverage(bufReader, outStream1, outStream2, average);
}
public static void computeAverage(BufferedReader bufReader, PrintWriter outStream1, PrintWriter outStream2, double average) {
String line = "";
double mark = 0;
double sum = 0;
int count = 0;
try {
bufReader.readLine();
while ((line = bufReader.readLine()) != null) {
String [] data = line.split(" ");
mark = Double.parseDouble(data[2]);
sum += mark;
count++;
}
average = sum / count;
compareMark(outStream1, outStream2, average);
} catch (NumberFormatException | IOException e) {
System.out.println(e);
} finally {
if (bufReader != null) {
try {
bufReader.close();
} catch ( IOException e) {
e.printStackTrace();
}
}
}
}
public static void compareMark(PrintWriter outStream1, PrintWriter outStream2, double average) throws FileNotFoundException {
File inFile = new File("stationary.txt");
FileReader fileReader = new FileReader(inFile);
BufferedReader bufReader = new BufferedReader(fileReader);
String line = " ";
double sum = 0;
double mark = 0;
int count = 0;
try {
double ave = (double) Math.round(average * 100) / 100;
System.out.println("another " + ave);
bufReader.readLine();
while ((line = bufReader.readLine()) != null) {
System.out.println(line);
String [] data = line.split(" ");
mark = Double.parseDouble(data[2]);
if (mark > ave) {
System.out.println("Over");
outStream1.write(line);
} else {
System.out.println("Less");
outStream2.write(line);
}
}
} catch (IOException e) {
System.out.println(e);
} catch (NumberFormatException ex) {
System.out.println(ex);
} finally {
if (bufReader != null) {
try {
bufReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
The source code is perfectly working, just that I received 0 bytes of both files after executing reading twice (first, doing average and last, doing comparison). Why is that? what am I doing wrong here?
Thank you for your kind help.
Your code is not correct and does not compile. But the main flaws are the following:
Your Double.parseDouble(data[2]) shouldn't work with your 4th line of data. Better use Double.parseDouble(data[data.length - 1])
Remove the readLine()-calls in front of the while-loop.
Write the lines including a line separator.
Close the OutStreams
The Data File that you have provided have the columns seperated by a space. As the 2nd Column has data which contains spaces, the convertion of data[2] to double will trigger an exception. Which will make the program to close the buffers and exit.
Use Commas to seperate column data.
Use better exception handling to find exceptions easily.
All you need is to close those output stream. As you are using bufferredWriter and not flushing it after each write you need to close those output-stream. which will write back those lines or datas into the file. Here is an example how you can do it:
Example 1: using flush().
....
outStream1.write(line);
outStream1.flush();
} else {
System.out.println("Less");
outStream2.write(line);
outStream2.flush();
}
Example 2: most efficient (either way you need to close those buffer too like bufReader.close())
...
} catch (IOException e) {
System.out.println(e);
} catch (NumberFormatException ex) {
System.out.println(ex);
} finally {
// add try catch.
outStream2.close();
outStream1.close();
if (bufReader != null ... ) {
try {
bufReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
As requested, an example using List
First a class to hold the stationary data, must be completed:
public class Stationary {
private final int id; // or String if desired
private final String name;
private final double mark; // BigDecimal would be better for money
public Stationary(int id, String name, double mark) {
// TODO error checking
this.id = id;
...
}
public int getId() {
return id;
}
... // TODO other getters
// TODO equals, hashCode, toString
}
and to read the file:
public List<Stationary> read(File file) {
List<Stationary> list= new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
while ((line = reader.readLine()) != null) {
// TODO parse line into id, name, mark
list.add(new Stationary(id, name, mark);
}
}
return list;
}
now the list can be used as needed, e.g. average:
List<Stationary> stationaries = read(STATIONARY_FILE);
...
for (Stationary stationary : stationaries) {
sum += stationary.getMark();
count += 1;
}
...
streams not used to keep it simple
I'm trying to read a .txt file called Heights.txt, which contains a string of numbers, each separated by a ":". The method produces one error that I can't seem to figure out.
It says that "the method must return a result of type int[]", at the very first line of this code.
I don't understand why it says this, as integerHeightDataPoints should be an integer array at that point, and should be able to be returned to a int[] method?
public static int[] readFile(){
BufferedReader br = null;
String dataPoints;
try {
br = new BufferedReader(new FileReader("Path\\Heights.txt"));
}
catch(IOException e) {
System.out.println("Please enter data first");
System.exit(0);
}
try {
while((dataPoints = br.readLine()) != null) {
if (dataPoints.contains(":")) {
String[] heightDataPoints = dataPoints.split(":");
int[] integerHeightDataPoints = new int[heightDataPoints.length];
for (int i = 0; i < integerHeightDataPoints.length; i++) {
integerHeightDataPoints[i] = Integer.parseInt(heightDataPoints[i]);
}
return integerHeightDataPoints;
}
}
}
catch (IOException e) {
System.out.println("Error reading file");
e.printStackTrace();
}
}
It's because you don't return anything in second IOException case or (as #Exception_al mentioned) when while never triggers.
public static int[] readFile() {
BufferedReader br = null;
String dataPoints;
try {
br = new BufferedReader(new FileReader("/tmp/file1"));
} catch (IOException e) {
System.out.println("Please enter data first");
System.exit(0);
}
int[] integerHeightDataPoints = new int[0];
try {
while ((dataPoints = br.readLine()) != null) {
if (dataPoints.contains(":")) {
String[] heightDataPoints = dataPoints.split(":");
integerHeightDataPoints = new int[heightDataPoints.length];
for (int i = 0; i < integerHeightDataPoints.length; i++) {
integerHeightDataPoints[i] = Integer.parseInt(heightDataPoints[i]);
}
return integerHeightDataPoints;
}
}
} catch (IOException e) {
System.out.println("Error reading file");
e.printStackTrace();
}
return integerHeightDataPoints;
}
I want to save to a file in android , Some of my arrayList that will be deleted after that.I already have two methods to write/read from android file here but the problem is I want the two methods do that:
the first method must save the element of arraylist then if I call it again it will not write the new element in the same line but write it in another line
The second must read a line (for example I give to the method which line and it returns what the lines contains)
The file looks like that :
firstelem
secondelem
thridelem
anotherelem
another ..
is this possible to do in android java?
PS: I don't need database.
Update
This is My methods :
private void writeToFile(String data) {
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(openFileOutput("config.txt", Context.MODE_PRIVATE));
outputStreamWriter.write(data);
outputStreamWriter.close();
}
catch (IOException e) {
Log.e("Exception", "File write failed: " + e.toString());
}
}
private String readFromFile() {
String ret = "";
try {
InputStream inputStream = openFileInput("config.txt");
if ( inputStream != null ) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String receiveString = "";
StringBuilder stringBuilder = new StringBuilder();
while ( (receiveString = bufferedReader.readLine()) != null ) {
stringBuilder.append(receiveString);
// stringBuilder.append("\\n");
}
inputStream.close();
ret = stringBuilder.toString();
}
}
catch (FileNotFoundException e) {
Log.e("login activity", "File not found: " + e.toString());
} catch (IOException e) {
Log.e("login activity", "Can not read file: " + e.toString());
}
return ret;
}
Using the save method you linked to you can create the text to save with a StringBuilder:
public String makeArrayListFlatfileString(List<List<String>> listOfLists)
{
StringBuilder sb = new StringBuilder();
if (!listOfLists.isEmpty()) {
// this assumes all lists are the same length
int listLengths = listOfLists.get(0).size();
for (int i=0; i<listLengths; i++)
{
for (List<String> list : listOfLists)
{
sb.append(list.get(i)).append("\n");
}
sb.append("\n"); // blank line after column grouping
}
}
return sb.toString();
}
To parse the contents from that same file (again assuming equal length lists and a String input):
public List<List<String>> getListOfListsFromFlatfile(String data)
{
// split into lines
String[] lines = data.split("\\n");
// first find out how many Lists we'll need
int numberOfLists = 0;
for (String line : lines){
if (line.trim().equals(""))
{
// blank line means new column grouping so stop counting
break;
}
else
{
numberOfLists++;
}
}
// make enough empty lists to hold the info:
List<List<String>> listOfLists = new ArrayList<List<String>>();
for (int i=0; i<numberOfLists; i++)
{
listOfLists.add(new ArrayList<String>());
}
// keep track of which list we should be adding to, and populate the lists
int listTracker = 0;
for (String line : lines)
{
if (line.trim().equals(""))
{
// new block so add next item to the first list again
listTracker = 0;
continue;
}
else
{
listOfLists.get(listTracker).add(line);
listTracker++;
}
}
return listOfLists;
}
For writing, just as Illegal Argument states - append '\n':
void writeToFileWithNewLine(String data) {
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(openFileOutput("config.txt", Context.MODE_PRIVATE));
outputStreamWriter.write(data + "\n");
outputStreamWriter.close();
}
catch (IOException e) { /* handle exception */ }
}
For reading (just the idea, in practice you should read the file only once):
String readLine(final int lineNo) {
InputStream in = new FileInputStream("file.txt");
ArrayList<String> lines = new ArrayList<String>();
try {
InputStreamReader inReader = new InputStreamReader(in);
BufferedReader reader = new BufferedReader(inReader);
String line;
do {
line = reader.readLine();
lines.add(line);
} while(line != null);
} catch (Exception e) { /* handle exceptions */ }
finally {
in.close();
}
if(lineNo < lines.size() && lineNo >= 0) {
return lines.get(lineNo);
} else {
throw new IndexOutOfBoundsException();
}
}
I am trying to read from 45 pages that are all the same (except for the part im reading of course) and write them in a list of line lists.
I wrote this code so far:
public static ArrayList<ArrayList<String>> linesWeNeed(){
ArrayList<ArrayList<String>> returnListList = new ArrayList<ArrayList<String>>();
for(int i = 1; i<=45; i++){
int pageNum=(i*20)-20;
System.out.println("PageNum"+pageNum);
URL url=null;
try {
url = new URL("http://tq.mot.gov.il/index.php?option=com_moofaq&iotype=w&view=category&lang_ovrrde=ENG&id=3&Itemid=29&limitstart="+pageNum);
} catch (MalformedURLException e) {
System.out.println("Oh uh!");
}
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8"));
} catch (IOException e) {
System.out.println("FATAL ERROR");
e.printStackTrace();
}
ArrayList<String> lineCodes = new ArrayList<String>();
ArrayList<String> linesWeNeed = new ArrayList<String>();
String line;
try {
readLines:
while((line=in.readLine())!=null){
if(line.contains("</tr></table></div></div></li></ul></div></div><br /></div>")){
break readLines;
}
lineCodes.add(line);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int o = 1; o>=lineCodes.size(); o++){
String readLine = lineCodes.get(o-1);
if(o>=297){
linesWeNeed.add(readLine);
}
}
returnListList.add(linesWeNeed);
}
return returnListList;
}
There are no errors, but for some reason every list in the arraylist the methods return is empty. Why?
Thanks in advance!
for(int o = 1; o>=lineCodes.size(); o++){
Your loop condition is back to front. Try <=.
for(int o = 1; o>=lineCodes.size(); o++){
Double-check the loop condition there; seems like that block is never going to execute...
I will try to explain this as much as I can. I am reading scores from a file onto which my form appends lines. The line consists of a date, home team, score, away team, score.
The stats I gather is away wins, home wins and draws.
The following code works perfectly
JButton viewStatsButton = new JButton(new AbstractAction("VIEW STATS")
{
public void actionPerformed( ActionEvent e )
{
int homeScore = 0;
int awayScore = 0;
int homeWins = 0;
int awayWins = 0;
int scoreDraw = 0;
String line = null;
String output;
String matchDay;
#SuppressWarnings("unused")
String homeTeam;
#SuppressWarnings("unused")
String awayTeam;
String file = "scores.dat";
StringTokenizer tokenizer;
FileReader fileReader = null;
try
{
fileReader = new FileReader (file);
}
catch (FileNotFoundException e1)
{
e1.printStackTrace();
}
BufferedReader inFile = new BufferedReader (fileReader);
try
{
line = inFile.readLine();
}
catch (IOException e1)
{
e1.printStackTrace();
}
while(line != null)
{
tokenizer = new StringTokenizer(line);
matchDay = tokenizer.nextToken();
homeTeam = tokenizer.nextToken();
try
{
homeScore = Integer.parseInt(tokenizer.nextToken());
}
catch (NumberFormatException exception)
{
System.out.println("Error in input. Line ignored:");
System.out.println(line);
}
awayTeam = tokenizer.nextToken();
try
{
awayScore = Integer.parseInt(tokenizer.nextToken());
}
catch (NumberFormatException exception)
{
System.out.println("Error in input. Line ignored:");
System.out.println(line);
}
if(homeScore > awayScore)
{
homeWins++;
}
else if(awayScore > homeScore)
{
awayWins++;
}
else
{
scoreDraw++;
}
try
{
line = inFile.readLine();
}
catch (IOException e1)
{
e1.printStackTrace();
}
}
try
{
inFile.close();
}
catch (IOException e1)
{
e1.printStackTrace();
}
output = "Home Wins : "+homeWins+"\nAway Wins : "+awayWins+"\nDraws : "+scoreDraw;
JTextArea textArea = new JTextArea();
frame.getContentPane().add(textArea, BorderLayout.CENTER);
textArea.setText(output);
}
});
scorePanel.add(viewStatsButton);
}
The problem does not come to light until the name of team is made out of two strings i.e.Newcastle United. What I had to do was append the two strings together like NewcastleUnited. I have tried to find out the length of the token and if it's less than 3 then i take it and parse it as integer but it seems that even if the next token reference is in an if statement it still moves to the token after it.
I would appreciate any help and guidance.
Try following
Before calling tokenizer.nextToken() check tokenizer.hasMoreTokens() to ensure that there is a token to read
if(tokenizer.hasMoreTokens())
{
x = tokenizer.nextToken();
}
After reading team name(first part) check whether next part is integer if it is, treat it as score, otherwise append it to team name.
homeTeam = tokenizer.nextToken();
String temp = tokenizer.nextToken();
try
{
homeScore = Integer.parseInt(temp);
}
catch(Exception e)
{
//Comes here if temp is not an integer, so temp is second part of name
homeTeam = homeTeam + " "+temp;
homeScore = Integer.parseInt(tokenizer.nextToken());
}
//Whatever the case, if we come here, it means both hometeam and score are assigned.
...........
...........
...........
Don't forgot to check tokenizer.hasMoreTokens() if you are not sure whether there is a token.