3

I basically want to ignore certain lines with characters in them, like if there's a line

// hello, i'm bill

I want to ignore that line while reading it because it contains the character "//". How can I do that? I tried method skip(), but it gives me errors.

public String[] OpenFile() throws IOException {

  FileReader reader = new FileReader(path);
  BufferedReader textReader = new BufferedReader(reader);

  int numberOfLines = readLines();
  String[] textData = new String[numberOfLines];
  int i;

  for (i=0; i<numberOfLines; i++) {
      textData[i] = textReader.readLine();
  }

  // close the line-by-line reader and return the data
  textReader.close();
  return textData;
}

int readLines() throws IOException {
  FileReader reader = new FileReader(path);
  BufferedReader textReader = new BufferedReader(reader);
  String line;
  int numberOfLines = 0;

  while ((line = textReader.readLine()) != null) { 
    // I tried this:
    if (line.contains("//")) {
      line.skip();  
    }
    numberOfLines++;       
  }    
  reader.close();  
  return numberOfLines;
}

Update: HERE's MY MAIN METHOD:

try{
 ReadFile files = new ReadFile(file.getPath());
 String[] anyLines = files.OpenFile();
 }
Brian Webster
  • 30,033
  • 48
  • 152
  • 225
lrvilnius
  • 107
  • 1
  • 3
  • 8
  • How does that even compile? I cannot find a "skip" method in the String class. – gnomed May 23 '11 at 00:42
  • Do you realize that the file is being read twice, in the code pasted after the edit? – Brian Webster May 23 '11 at 00:43
  • The `readLines()` method would be more accurately called `countLines()` or `countNonCommentLines()`. This entire exercise would be neater & faster by reading the lines into a structure that can expand as needed, such as an `ArrayList`, since it seems you only use the count to establish the size of a `String[]`. – Andrew Thompson May 23 '11 at 00:44
  • It doesn't read the file twice, just counts the number of lines a file has and outputs them (in my main method). – lrvilnius May 23 '11 at 00:48
  • 1
    @Irvilnius: You are so reading it twice. First you count the number of lines (where the posted solutions will not count the `//` lines, as you wished), then you go back to your main function and output all lines (where the solutions that were posted were not applied). However, the lines were miscounted, so you only show the first N lines, where N is the number of non-`//` lines. This explains your "cutoff". – Amadan May 23 '11 at 00:52
  • @Amadan: so you suggest doing this in my main method? – lrvilnius May 23 '11 at 01:02
  • @Irvilnius: You should do it in both, because the counted lines should match the read lines. Better yet, you might pay attention to @Andrew's comment above (and the updated code from both contributors below), and not read the file twice. – Amadan May 23 '11 at 01:05

2 Answers2

5

As Andrew Thompson points out, it would be best to read the file line by line into an ArrayList. Pseudo-Code:

 For Each Line In File
   If LineIsValid()
     AddLineToArrayList()
 Next

UPDATE to fix your actual code:

public String[] OpenFile() throws IOException {

  FileReader reader = new FileReader(path);
  BufferedReader textReader = new BufferedReader(reader);

  int numberOfLines = readLines();
  String[] textData = new String[numberOfLines];
  int BufferIndex = 0;
  String line;

  while ((line = textReader.readLine()) != null) {
    if (line.trim().startsWith("//")) {
      // Don't inject current line into buffer
    }else{
       textData[BufferIndex] = textReader.readLine();
       BufferIndex = BufferIndex + 1;
    }      
  }

  // close the line-by-line reader and return the data
  textReader.close();
  return textData;
}

In your ReadLines() Function:

while ((line = textReader.readLine()) != null) {
    if (line.trim().startsWith("//")) {
      // do nothing
    }else{
      numberOfLines++;
    }      
}

Basically, you're on the right track.

Note: You may be interested in the startsWith() string function

Brian Webster
  • 30,033
  • 48
  • 152
  • 225
  • it doesn't work - I want to skip lines that start with this symbol - // and have text in them. I tried your method and those lines are still being outputted. – lrvilnius May 23 '11 at 00:37
  • Did you post your actual code above? Also, can you explain the purpose of your code? Is it to count lines, output lines, dump lines into a buffer? – Brian Webster May 23 '11 at 00:39
  • What do you mean, "outputted"? Your code sample did not contain any string output. If @hamlin11's or @ratchet's code is not working for you, you're adapting it wrong. – Amadan May 23 '11 at 00:39
  • In my main method, I output the strings using System.out.println by creating an array. The one that I'm talking about now is a File Reading class that I created. – lrvilnius May 23 '11 at 00:45
  • I was able to fix the issue that was causing the problem in your code -- that became possible when you pasted the full code. Good luck – Brian Webster May 23 '11 at 00:57
  • Change i to bufferIndex. I tried to rename it to a variable name that would make some sense, but missed an 'i' – Brian Webster May 23 '11 at 01:25
  • @Ratchet's method is clearly best. The last java I wrote was 10 years ago, so my syntax is lacking regarding data structures -- had to keep it simple. – Brian Webster May 23 '11 at 06:04
5
while ((line = textReader.readLine()) != null) {

    // I tried this:
    if (line.contains("//")) {
      continue;
    }

    numberOfLines++;

}

note that continue might seem a bit goto like and be prone to critique


edit here's what you are after (note this doesn't need the countLines method)

public String[] OpenFile() throws IOException {
   FileReader reader = new FileReader(path);
   BufferedReader textReader = new BufferedReader(reader);

   List<String> textData = new LinkedList<String>();//linked list to avoid realloc
   String line;
   while ((line = textReader.readLine()) != null) {
       if (!line.contains("//")) textData.add(line);
   }

   // close the line-by-line reader and return the data
   textReader.close();
   return textData.toArray(new String[textData.size()]);
}
ratchet freak
  • 47,288
  • 5
  • 68
  • 106
  • Whoever critiques `goto` in context such as this does not understand why `goto` was considered harmful. Dijkstra was against *unrestricted* `goto`. – Amadan May 23 '11 at 00:36
  • +1 I love `continue` personally. not quite as bad as `goto` I dont think. I equate it more to `break` which is definitely not so prone to critique since it definitely the best way to end a loop in mid-set. – gnomed May 23 '11 at 00:39
  • `Continue` is 100% perfectly valid, and to compare it to `goto` is doing it a disservice. `Continue` is pretty much the analogue of `break` – Falmarri May 23 '11 at 00:42
  • @lrvilnius it definitely does answer the question that was posed and works without using a made up method on Strings. If you are getting erroneous output its because you dont understand what youre doing and how to predict the behaviour. – gnomed May 23 '11 at 00:44
  • I did say *might* in terms of `continue` – ratchet freak May 23 '11 at 00:45
  • @gnomed: Some of the people who are against `continue` just know it's kind of like `goto`, and are doing mob justice on it, without even considering *why* `goto` is said to be bad - just taking it on face value. The others think `continue` is bad style, because it doesn't indent whatever is below it - so you don't visually see that the code below it would not be executed. Compare: `if (x) { a(); continue; } unindented();` with `if (x) { a(); } else { indented(); }`. However, people who are used to non-local exits will not miss it that easily. – Amadan May 23 '11 at 00:47
  • @ratchet: I know you did, it just irks me. We should not pander to people who think there's something wrong with `continue`. – Amadan May 23 '11 at 00:48
  • i tested this method and it doesn't remove the lines that have "//", but it does cut off ending lines. any clues why? – lrvilnius May 23 '11 at 00:52
  • @irvilnius check the edit you went over the file twice (and didn't account for skips in the second time) there is no need for that – ratchet freak May 23 '11 at 00:59
  • @ratchet freak: I don't get how to implement your method. What's variable "line"? – lrvilnius May 23 '11 at 01:12
  • @irvilnius it's a String, I updated my answer again so the full method is shown – ratchet freak May 23 '11 at 01:16
  • @Amadan never considered indentation, but i guess youre right, readability helps. but once you define benefits that specific it will probably become subjective. For instance there are some times where I prefer the lack of indentation caused by "continue" it triggers something in my mind to pay more attention to what is apparently a unique situation in the code I am writing. just a thought. nice to learn more about how other people use it though. – gnomed May 23 '11 at 23:28
  • @Amadan, gnomed: This entirely depends on the usage. If it's just an if/else with a few statements in each, then yes a continue would be unnecessary. But if the continue occurs at the very beginning of the loop, and there's lots of logic afterwards, there may be an argument that the compiler can better predict the branch and fetch the correct code, especially in java with dynamic branch prediction. Although this is a pretty specific optimization as well as premature without evidence. – Falmarri May 27 '11 at 20:47