Team LiB
Previous Section Next Section

Modifying the Contents of a File

Now I want to provide a facility that modifies the content of a file based on a regex pattern. That is, I want to provide a mechanism that opens a file, searches its contents based on a regex pattern, and changes every occurrence of that pattern with a replacement string. Because I already have code that will open and search a file, modifying the content of the file is fairly easy. The logic for doing so is shown in Figure 5-2.

Click To expand
Figure 5-2: Basic flow diagram for updating the content of a file

Again, I decide to use a FileChannel for efficiency, as shown in Listing 5-11.

Listing 5-11: Modifying the Content of a File Based on a Regex Pattern
Start example
01  /**
02  * updates the content of the file. By default, the
03  * Pattern.MULTILINE is used. Also supports the
04  * $d notation in the replacement string, per the
05  * Matcher.replaceAll method
06  * @param the String fileName is the name and file path
07  * @param the String regex pattern to look for
08  * @param the String replacement for the regex
09  * @throws IOException if there is an IO error
10  *
11  * @return boolean true if the file was updated
12  */
13  public static boolean updateFileContent
14  (
15     String fileName,
16     String regex,
17     String replacement
18  ) throws IOException
19  {
20     boolean retval = false;

21     RandomAccessFile raf =
22         new RandomAccessFile(fileName,"rwd");
23     FileChannel fc = raf.getChannel();

24     String fileContent = getFileContent(fc);
25     //Activate the MULTILINE flag for this regex
26     regex = "(?m)"+regex;

27     String newFileContent =
28         fileContent.replaceAll(regex,replacement);

29     //if nothing changed, then don't update the file
30     if (!newFileContent.equals(fileContent))
31     {
32        setFileContent(newFileContent,fc);
33        retval = true;
34     }
35     //close up shop
36     fc.close();
37     fc = null;
38     raf = null;

39     return retval;
40 }

41  /**
42  * sets the content of a file. Completely
43  * overwrites previous file content, and truncates
44  * file to the length of the new content.
45  * @param the <code>String</code> newContent
46  * @param the <code>FileChannel</code> fc
47  * @throws <code>IOException</code>
48  *
49  * @author M Habibi
50  */
51  private static void setFileContent(
52     String newContent, FileChannel fc
53  )
54  throws IOException{
55     //write out the content to the file
56     ByteBuffer bb = ByteBuffer.wrap(newContent.getBytes());
57     //truncate the size of the file, in case the
58     //original file content was longer the new
59     //content
60     fc.truncate(newContent.length());

61     //start writing as position 0
62     fc.position(0);
63     fc.write(bb);

64     fc.close();
65     fc = null;
66  }
End example

Listing 5-11 takes advantage of the getFileContent method defined earlier in line 29 of Listing 5-7. Otherwise, the example is self-contained.


Team LiB
Previous Section Next Section