1

私はJavaのスキャナークラスを理解しようとしていますが、このコードがパート1の最初の行のみを出力し、パート2のすべての情報を出力しない理由は誰でもわかります。

import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.NoSuchElementException;
import java.util.Scanner;

public class BadParse {

public static String getNextEntry(InputStream in) {
    Scanner sin = new Scanner(in);

    try {
        String ssn = sin.next();
        String name = sin.next();
        int age = sin.nextInt();

        return name + "(" + ssn + ") is " + age + " years old.";
    } catch (NoSuchElementException e) {
        return null;
    }
}

public static void putNextEntry(String ssn, String name, int age, OutputStream out) {
    PrintWriter pout = new PrintWriter(new OutputStreamWriter(out));

    pout.print(ssn + " ");
    pout.print(name + " ");
    pout.print(age + " ");
}

public static void main(String[] args) throws IOException {

    // Part I
    String input = "1234567890 John 20\n0987654321 Beth 18\n2468101214 Jack 19\n";
    InputStream in = new ByteArrayInputStream(input.getBytes());

    String entry;
    while ((entry = getNextEntry(in)) != null) {
        System.out.println(entry);
    }

    // Part II
    OutputStream out = new FileOutputStream("data");

    putNextEntry("1234567890", "John", 20, out);
    putNextEntry("0987654321", "Beth", 18, out);
    putNextEntry("2468101214", "Jack", 19, out);

    out.close();
}

}

区切り文字を使用してみましたが、成功しませんでした。

4

2 に答える 2

2

問題は、Scanner内部getNextEntryにオブジェクトを作成していて、そのオブジェクトが破棄されるとストリームが閉じられることです。次のように、ストリームの代わりに Scanner を引数として渡してみてください (PrintWriter についても同様です)。

 import java.io.ByteArrayInputStream;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.NoSuchElementException;
import java.util.Scanner;

public class BadParse {
public static String getNextEntry(Scanner sin) {

    try {
        String ssn = sin.next();
        String name = sin.next();
        int age = sin.nextInt();

        return name + "(" + ssn + ") is " + age + " years old.";
    } catch (NoSuchElementException e) {
        return null;
    }
}

public static void putNextEntry(String ssn, String name, int age, PrintWriter pout) {

    pout.print(ssn + " ");
    pout.print(name + " ");
    pout.print(age + " ");
}

public static void main(String[] args) throws IOException {

    // Part I
    String input = "1234567890 John 20\n0987654321 Beth 18\n2468101214 Jack 19\n";
    InputStream in = new ByteArrayInputStream(input.getBytes());
    Scanner sin = new Scanner(in);

    String entry;
    while ((entry = getNextEntry(sin)) != null) {
        System.out.println(entry);
    }

    // Part II
    OutputStream out = new FileOutputStream("data");
    PrintWriter pout = new PrintWriter(new OutputStreamWriter(out));

    putNextEntry("1234567890", "John", 20, pout);
    putNextEntry("0987654321", "Beth", 18, pout);
    putNextEntry("2468101214", "Jack", 19, pout);

    pout.close();
}
} 
于 2013-01-24T06:24:01.210 に答える
2

デバッガーを実行してgetNextEntryメソッドをステップ実行すると、2 回目の呼び出しでScannerNoSuchElementException. これが発生する理由は、最初のScannerが の一部を消費したためByteArrayInputStreamです。

できる修正の 1 つは、ループのScanner前にを作成し、 を渡す代わりにtoを渡すことです。whileScannergetNextEntryByteArrayInputStream

public static String getNextEntry(Scanner sin) {

...

Scanner sin = new Scanner(in);
String entry;
while ((entry = getNextEntry(sin)) != null) {

パート 2 に関しては、PrintWriterフラッシュされていません。pout.flush()その下に追加すると、putNextEntryデータがファイルに送信されます。PrintWriterオブジェクトの場合、 、 、 、または を呼び出した場合にのみ、データがフラッシュprintlnprintfformatますflush

public static void putNextEntry(String ssn, String name, int age, OutputStream out) {
    PrintWriter pout = new PrintWriter(new OutputStreamWriter(out));
    pout.print(ssn + " ");
    pout.print(name + " ");
    pout.print(age + " ");
    pout.flush();
}

ただし、スキャナーと同様に PrintWriter を作成して渡すことをお勧めします。putNextEntry作成されるリソースを削減し、複数回呼び出した後に最後までフラッシュできます。

于 2013-01-24T06:20:29.203 に答える