0

Here is my code :

public static void modif(String name, String color, int k)
    {
        try {
        File input= new File("file1.txt");
        File output= new File("temp.txt");

        String correctLine = (String) FileUtils.readLines(input).get(k-3);

        BufferedReader br = new BufferedReader(new FileReader(input));
        BufferedWriter bw = new BufferedWriter(new FileWriter(output));
        String line="";


        while ((ligne = br.readLine()) != null){

            String lineConcat = line  + "\n";

         if(ligne.startsWith("\""+name+"\"")){

         System.out.println(correctLine); // i can display the line to change

             bw.write("\"" + name + "\"" + ": " + "\"" + color + "\"" + "\n"); // this is the way i replace my line
             System.out.println("Awesome !");
             bw.flush();
         }else{
             bw.write(lineConcat);
             bw.flush();
         }
        }
        bw.close();
        br.close();

        output.renameTo(new File("file2.txt"));

        } catch (IOException e) {
            e.printStackTrace();
        }

}

Basically i want to replace a specific line when a condition is detected. I know which line is to change but i don't know how to replace it. Because for now i can only detect the beggining of a line and change the current line not a previous one.

I tried to use FileUtils.writeStringToFile but it's not working so i'm here for help :(

Thanks guys !

Edit : my input is like that :

{
      "type": "Feature",
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              6.07721374522497,
              43.08716485432151
            ],
            [
              6.051202617426629,
              43.07969629888752
            ],
            [
              6.032563261594762,
              43.07758570385911
            ]
          ]
        ]
      },
      "properties": {
        "_storage_options": {
"color": "Orange"
        },
"name": "CARQUEIRANNE"
      }
    }

What i'm doing actually is when i found the line "name": "CAREQUEIRANNE", i want to replace his color attribute so i have to go the current line - 3 and i really don't know how to do it

Edit 2 :

My method is called like that :

                BufferedReader in2 = new BufferedReader(new FileReader("file1.txt"));
    String line;
    String lineConcat = null;
    int k=1;
    
    while ((line = in2.readLine()) != null)
    {

     
     lineConcat = line + "\n";

     String myPattern = tabCity[21];
     Pattern p = Pattern.compile(myPattern);
     Matcher m = p.matcher(lineConcat);
     //Matcher m2 = p2.matcher(lineConcat);
     if (m.find()){

      System.out.println("Found !");
      System.out.println(k);
      
      modif("color", "Orange", k);
      
      
     }
     else
     {
      System.out.println("Not Found");
     }
     
     k++;

    }
    in2.close();

When i found that my Pattern matched with research in file, i call my function to replace the color attribute of a city

Edit 3 :

@BrettWalker here is the new code :

public static void modif(String nom, String color, int k)
 {
  try {
  File input = new File("file1.txt");
  File output = new File("temp.txt");
  
  BufferedReader br = new BufferedReader(new FileReader(input));
  BufferedWriter bw = new BufferedWriter(new FileWriter(output));
  String line="";

  Stack st = new Stack();
  
  st.push(br.readLine());
  st.push(br.readLine());
  st.push(br.readLine());
  
  while ((ligne = br.readLine()) != null){
   
   String ligneConcat = ligne  + "\n";
   
   st.push(ligneConcat);
   
   String oldLine = (String) st.pop();

   if(ligne.startsWith("\""+nom+"\"")){
    

    oldLine = "\"" + nom + "\"" + ": " + "\"" + color + "\"" + "\n";

   }
    bw.write(oldLine);
  }
  
  
  bw.write((int) st.pop());
  bw.write((int) st.pop());
  bw.write((int) st.pop());
  
  bw.close();
  br.close();
   
  output.renameTo(new File("file2.txt"));
  
  } catch (IOException e) {
   e.printStackTrace();
  }

}
Kyouma78
  • 73
  • 1
  • 9

1 Answers1

1

You need to use a queue (buffer) to temporarily hold a small segment of the file in Java to allow you to detect when and allow you to change the appropriate line.

Instead of writing out the line immediately push the line onto a queue (buffer) and pop off the next item from the queue. If the one just popped of is the one to change then write the modified line to the file otherwise write the original line to the file.

A bit of poor pseudo code to help express the idea.

// Open up the readers/writers

// Prime the queue with the first few line of the file.
// Need to add safeguard to protect against small files!!
queue.push(br.readLine());
queue.push(br.readLine());
queue.push(br.readLine());

while ((line = br.readLine()) != null) {
    String lineConcat = line  + "\n";

    queue.push(lineConcat);

    String oldLine = queue.pop();

    if (line.startsWith("\""+name+"\"")) {
         oldLine = < Modify oldLine >
    }

    bw.write(oldLine)
}

// Empty the queue
bw.write(queue.pop());
bw.write(queue.pop());
bw.write(queue.pop());

// Close the readers/writer
Brett Walker
  • 3,566
  • 1
  • 18
  • 36
  • Unfortunately i wan't to do that in a loop like : "each time i see that myPattern[i] == arrayCity[i] then replace the n-3 line by my BufferedWriter" (with n the current number of line) so i can't push the beggining of my file into a queue :/ – Kyouma78 Jun 05 '15 at 13:32
  • @Kyouma78 you could just create your own buffer holding 3 lines like a sliding window and when you go to the next line you can write line n-4... – maraca Jun 05 '15 at 13:36
  • Think carefully about this. You wont see a matching line in the first three lines. These can be safely read one at a time and pushed on to the queue. You may need to provide safeguard to protect against short files but this should work. – Brett Walker Jun 05 '15 at 13:36
  • The queue I'm suggesting is my sliding window. It should only hold at most three lines. – Brett Walker Jun 05 '15 at 13:38
  • @BrettWalker just tried to clarify that when you reach line `n` then it is safe to write line `n-4`, it won't change. (+1) – maraca Jun 05 '15 at 13:40
  • How can i stack only 3 lines in a BufferedReader ? because the while loop is always like "while ((ligne = br.readLine()) != null){" – Kyouma78 Jun 05 '15 at 13:52
  • See my edits to the pseudo code that show more details for priming the queue. – Brett Walker Jun 05 '15 at 14:01
  • Thx for your editing i've implemented the Stack class for using push() et pop() but when you make "bw.write(queue.pop());" it tells me that queue.pop is an int :/ – Kyouma78 Jun 05 '15 at 14:19
  • Not seeing you new code it is hard to say why this is happening. Maybe a new question? – Brett Walker Jun 05 '15 at 14:21
  • @BrettWalker I made a last edit to illustrate what i did but it's not working at all – Kyouma78 Jun 05 '15 at 14:26
  • Two thing are wrong with the new edits to your code. 1) A stack is not the right data structure. A stack is different from a queue. (Sorry if push/pop confused you, the queue terminology is enqueue/dequeue) Do some research. 2) You push onto the queue a String and want to pop off an int. Confused data types. This is not going to work. – Brett Walker Jun 05 '15 at 14:31
  • @BrettWalker is this link can help ? http://stackoverflow.com/questions/4626812/how-do-i-instantiate-a-queue-object-in-java – Kyouma78 Jun 05 '15 at 14:56
  • It is getting closer. Try `Queue q = new LinkedList(4);` and use `offer` to put lines onto the queue, and `poll` to pull lines off the queue. http://docs.oracle.com/javase/7/docs/api/java/util/Queue.html & http://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html – Brett Walker Jun 05 '15 at 15:03
  • Thanks for your help :) I succeed my task by using hashMap instead of another data structure. It worked well ! – Kyouma78 Jun 19 '15 at 08:57