was ist falsch mit diesem Code?
-
09-10-2019 - |
Frage
Ich lese Inhalt von Dateien eines Verzeichnisses. Ich habe, um die Dateien entmischen nach ihren Namen und dann ihren Inhalt lesen. Wenn ich den Code ausführen einfach, ohne den Inhalt zu lesen, werden alle Dateien werden von einem bestimmten Dateinamen aufgeführt, aber wenn ich versuche, den Inhalt zu lesen, liest Inhalte von nur wenigen Dateien in der Tat nur 10 von ihnen. Aber das Verzeichnis hat etwa 1000 Dateien eines bestimmten Namens. Ich veröffentliche den Code hier.
for (i = 0; i <= filenames.length; i++) {
read = new FileReader("trainfiles/"+filenames[i]);
br = new BufferedReader(read);
if (filenames[i].matches(".*ham.*")) {
System.out.println("ham:" + filenames[i]);
while ((lines = br.readLine()) != null) {
st = new StringTokenizer(lines);
while (st.hasMoreTokens()) {
System.out.println(st.nextToken());
}
}
br.close();
}
}
Kann mir jemand sagen, wo mache ich falsch !?
Dank
EDIT # 1 Ich habe einige Änderungen tat, was ich hier gesagt worden, aber das Problem weiterhin besteht, hier ist der Code.
for(i=0;i<=filenames.length;i++){
read = new FileReader("trainfiles/"+filenames[i]);
br = new BufferedReader(read);
if(filenames[i].matches(".*ham.*")){
System.out.println("ham:"+filenames[i]);
while((lines = br.readLine())!= null){
st = new StringTokenizer(lines);
while(st.hasMoreTokens()){
System.out.println(st.nextToken());
}
}
}
br.close();
read.close();
}
EDIT # 2 Jetzt ist die Code wie folgt aussieht, aber wieder ... sein gibt mir nicht das Ergebnis, das ich will.
for (i = 0; i < filenames.length; i++) {
try {
if (filenames[i].matches(".*ham.*")) {
read = new FileReader("trainfiles/"+filenames[i]);
br = new BufferedReader(read);
System.out.println("ham:" + filenames[i]);
while ((lines = br.readLine()) != null) {
st = new StringTokenizer(lines);
while (st.hasMoreTokens()) {
System.out.println(st.nextToken());
}
}
}
} finally {
read.close();
br.close();
}
}
Lösung
Ich würde der Code wie folgt neu schreiben, und sehen, was Ausgabe erhalten Sie:
for (filename : filenames) {
if (filename.matches(".*ham.*")) {
System.out.println("ham:" + filename);
// reset these to null (where are they declared?)
read = null;
br = null;
try {
read = new FileReader("trainfiles/"+filename);
br = new BufferedReader(read);
while ((lines = br.readLine()) != null) {
System.out.println(lines);
// st = new StringTokenizer(lines);
// while (st.hasMoreTokens()) {
// System.out.println(st.nextToken());
// }
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (br != null) br.close();
if (read != null) read.close();
}
}
}
Einige allgemeine Bemerkungen zu Ihrem ursprünglichen Code:
-
Nur eine
for
Schleife verwenden, wenn Sie tatsächlich den Array-Index benötigen. Bevorzugen eine für-jede Schleife (d.h.for (filename : filenames) ...
). -
Declare Variablen im engsten Umfang möglich. In diesem Fall sollten Sie Ihre
read
undbr
Variablen deklarieren, wo ich sie zunull
initialisieren. -
Sie niemals eine Datei öffnen, wenn du gehst, es zu benutzen. Hier, das heißt das Öffnen innen der bedingte Block.
-
Da das Öffnen einer Datei eine Ausnahme auslösen kann,
br
kann nicht initialisiert erhalten, in dem Fall, dass Sie es nichtclose
kann. Sie müssen sich zuerst fürnull
überprüfen.
Andere Tipps
Als erstes sollten Sie i<filenames.length
verwenden. Zweitens erwartet matches
ein regulärer Ausdruck, nicht *
-Kleckse. Der Ausdruck, den Sie verwendet wird, ist ein gültiger regulärer Ausdruck für [something]ham[something]
- ist das, was Sie gemeint
Ich glaube nicht, dass Sie das Filereader schließen müssen - ich glaube, BR close
breitet sich nach oben. Aber das ist wert. Bearbeiten wie bereits erwähnt wurde, müssen Sie immer in der Nähe der Datei außerhalb des if.
Sie sollten Ihre FileReader
Objekt read
auch schließen.
Wenn diese Hausaufgaben ist, würde ich auch vorschlagen, dass Sie einen Blick auf commons-io .
EDIT # 1:. Ich würde vorschlagen, beide schließen Operationen in einem finally-Block tun
EDIT # 2: Haben Sie dies versuchen
for (i = 0; i <= filenames.length; i++) {
try {
read = new FileReader("trainfiles/"+filenames[i]);
br = new BufferedReader(read);
if (filenames[i].matches(".*ham.*")) {
System.out.println("ham:" + filenames[i]);
while ((lines = br.readLine()) != null) {
st = new StringTokenizer(lines);
while (st.hasMoreTokens()) {
System.out.println(st.nextToken());
}
}
}
} finally {
br.close();
read.close();
}
}
1000-Dateien sind eine Menge von Dateien zu lesen. Wenn eine Datei nicht lesen kann es eine Ausnahme auslösen sollte (IOException um genau zu sein). Vielleicht hier ausdrucken die Ausnahmemeldung im Block fängt und einfügen.
Ich weiß nicht, die Klasse StringTokenizer aber der Code geben Fehler beim Drucken nur die Zeile ohne StringTokenizer?
Eine andere Option ist, Threads zu verwenden. Sie haben die Anordnung von Dateien und Sie dann einige Threads starten, der eine Datei liest (Producer / Consumer-Problem).
By the way, können Sie Dateien mit der Klasse Filefilter filtern.