Omdat ik het toch wel een beetje sneu vond dat ik je zo de verkeerde kant op had gestuurd, heb ik maar even een oplossing voor je geimplementeerd. Hij bartst van de design-patterns, is toch redelijk simpel en is heel erg goed te hergebruiken. Ook gaat hij erg efficient om met geheugen en kan daardoor alle grote files aan.
Allereerst heb ik een read methode die de elke regel doorgeeft aan een 'ContentHandler'. Deze ContentHandler kan iets met de String gaan doen: opslaan in een structuur zoals een List of bijvoorbeeld zoals ik ga doen vervangen door een andere regel of wegschrijven naar een file.
Dit is de code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| import java.io.*;
public class XFileReader
{
public void read(File file, ContentHandler handler) throws IOException, FileNotFoundException, ContentHandleException
{
BufferedReader reader = new BufferedReader(new FileReader(file));
String s;
boolean proceed = true;
while((s = reader.readLine())!=null && proceed)
{
proceed = handler.handle(s);
}
reader.close();
}
} |
redelijke simpel he?
Dit is de ContentHandler:
code:
1
2
3
4
| public interface ContentHandler
{
public boolean handle(String line) throws ContentHandleException;
} |
Nu kan je de ContentHandler op veel verschillende manieren implementeren. Je kunt bijvoorbeeld een ContentHandler maken die de regel gelijk weer wegschrijft naar een andere file:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| import java.io.IOException;
import java.io.Writer;
public class WritingContentHandler implements ContentHandler
{
private Writer writer;
public WritingContentHandler(Writer writer)
{
super();
this.writer = writer;
}
public boolean handle(String line) throws ContentHandleException
{
try
{
writer.write(line);
writer.write('\n');
return true;
}
catch(IOException exc)
{
throw new ContentHandleException("Couldn't write line: " + line , exc);
}
}
} |
Als je een file gaat lezen via de XFileReader en daarbij deze ContentHandler meegeeft zul je zien dat hij gewoon de file kopieert.
Zoals je ziet gebruik ik nog een Exception:
code:
1
2
3
4
5
6
7
8
9
10
11
12
| public class ContentHandleException extends Exception
{
public ContentHandleException(String message, Exception exc)
{
super(message, exc);
}
public ContentHandleException(String message)
{
super(message);
}
} |
Als je geen 1.4.0 gebruikt moet je even de Exception uit de constructor halen (en uiteraard ook niet meegeven in de WritingContentHandler).
Maar goed, kopieren willen we niet: bepaalde regels moeten vervangen worden. Daarom schrijven we een replacer:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
| import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class SimpleReplacingContentHandler implements ContentHandler
{
private ContentHandler next;
private String firstline;
private String replacement;
public SimpleReplacingContentHandler(ContentHandler next, String line, String replacement)
{
super();
this.next = next;
this.firstline = line;
this.replacement = replacement;
}
public boolean handle(String line) throws ContentHandleException
{
String newline;
if(line.equals(firstline))
{
newline = replacement;
}
else
{
newline = line;
}
return next.handle(newline);
}
} |
Deze ContentHandler is in feite een tussenlaag: hij heeft de line weer door aan een volgende ContentHandler. Hij vervangt echter bepaalde regels zoals je kunt aangeven in de constructor.
Als je nu aan de SimpleReplacingContentHandler een WritingContentHandler meegeeft en hiermee een File gaat inlezen, heb je precies wat jij wil!
Ik heb een kleine applicatie gemaakt om het te testen:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| import java.io.*;
public class Application
{
public static void main(String[] ps)
{
try
{
File source = new File(ps[0]);
File target = new File(ps[1]);
Writer writer = new BufferedWriter(new FileWriter(target));
ContentHandler contentHandler = new SimpleReplacingContentHandler(
new WritingContentHandler(writer),
"Dit is een te vervangen regel!",
"Dit is de vervanging");
new XFileReader().read(source, contentHandler);
writer.flush();
writer.close();
}
catch(Exception exc)
{
exc.printStackTrace();
}
}
} |
Als ik nu deze input neem:
code:
1
2
3
4
5
6
7
| Test voorbeeld
Dit is een te vervangen regel!
Boeh
Bah
Dit is een te vervangen regel!
Dit is een te vervangen regel!ha
Boeh |
komt er keurig dit uit:
code:
1
2
3
4
5
6
7
| Test voorbeeld
Dit is de vervanging
Boeh
Bah
Dit is de vervanging
Dit is een te vervangen regel!ha
Boeh |
Dit is dus precies wat je wilde

. Ik hoop dat je het tot nu toe allemaal snapt en kunt toepassen

.
Om even aan te tonen hoe makkelijk deze aanpak is, heb ik nog even een vervanger met reguliere expressies gemaakt. Als je geen 1.4.0 hebt, zal deze niet compileren.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class RegexReplacingContentHandler implements ContentHandler
{
private ContentHandler next;
private Pattern pattern;
private String replacement;
public RegexReplacingContentHandler(ContentHandler next, String regex, String replacement)
{
super();
this.next = next;
this.pattern = Pattern.compile(regex);
this.replacement = replacement;
}
public boolean handle(String line) throws ContentHandleException
{
Matcher matcher = pattern.matcher(line);
String newline = matcher.replaceAll(replacement);
return next.handle(newline);
}
} |
deze kan je aanroepen met deze applicatie:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| import java.io.*;
public class RegexApplication
{
public static void main(String[] ps)
{
try
{
File source = new File(ps[0]);
File target = new File(ps[1]);
Writer writer = new BufferedWriter(new FileWriter(target));
ContentHandler contentHandler = new RegexReplacingContentHandler(
new WritingContentHandler(writer),
"Dit is een te vervangen regel!",
"Dit is de vervanging");
new XFileReader().read(source, contentHandler);
writer.flush();
writer.close();
}
catch(Exception exc)
{
exc.printStackTrace();
}
}
} |
Uiteraard is de gekozen reguliere expressies hier niet zo spannend, maar het gaat maar even om het voorbeeld

.