1

ファイルの特定の部分を取得して別の関数に送信し、BufferedReaderが中断したところからファイルの終わりまで同じことを続けようとしているが、理解できないようです。それを機能させる方法。

これが私が持っているものです:

String str = "";
int count = 0; 

 try {
  while(//condition so it loops through the entire file. I've tried fileReader.ready() and fileReader.read != -1 but both just run into infinite loops){

   while ((count <  4)){ 
    str += fileReader.read();
    count++;
    fileReader.mark(1000);
   }

   fileReader.reset();

   DoSomething(str) // send str to another function and do something with it;
  }
  } catch (IOException e) {
   // TODO Auto-generated catch block
  }

誰かがこれを手伝って、私が間違っていることを説明できますか?よろしくお願いします

4

8 に答える 8

1

文字数がわかっている場合は、BufferedReaderのメソッドを使用して、最初の文字(64ビットの整数).skip(long)をスキップするように指示します。longlong

skipを呼び出すとlong、実際にスキップされた文字数のが返されます。

于 2010-11-12T20:54:01.523 に答える
0

count = 0後にリセットする必要があると思いますDoSomething(Str)。現在、カウント変数をリセットすることはなく、ファイル読み取りループに入ることができません。

于 2010-11-12T22:26:34.520 に答える
0

なぜマークしてリセットするのですか?4バイトを読み取り、それらを処理して、EOFまで繰り返します。

于 2010-11-13T04:28:06.340 に答える
0

Martijns の回答に基づいて、コードを少し単純にしました。

package so4168937;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;

public class SecondTry {

  static void consume(Reader rd, int length) throws IOException {
    StringBuilder sb = new StringBuilder();
    int c;

    for (int i = 0; i < length - 1; i++) {
      if ((c = rd.read()) == -1)
        return;
      sb.append((char) c);
    }

    while ((c = rd.read()) != -1) {
      sb.append((char) c);
      System.out.println("<" + sb + ">");
      sb.deleteCharAt(0);
    }
  }

  public static void main(String[] args) throws IOException {
    consume(new StringReader("hi my name is joe"), 4);
  }

}

markまたはを使用する必要はありません。使用してもresetready複雑さと望ましくない動作が追加されるだけです。

于 2010-11-18T00:40:04.470 に答える
0

以下は私にとってはうまくいきます。コメント後に編集しました。

import java.io.*;
public class Test {


public static void main(String[] args) {
String str = "";
int count = 0; 

try {
  Reader fileReader = new BufferedReader(new FileReader("testfile"));
  fileReader.mark(5);
 while(fileReader.ready()){
   count = 0;
   str ="";
   fileReader.reset();
  while (count <  4 && fileReader.ready()){ 
    if (count == 1){
      fileReader.mark(5);
    }
   str += (char)fileReader.read() ;
   count++;
  }

  System.out.println(str); // send str to another function and do something with it;

 }
 } catch (IOException e) {
  // TODO Auto-generated catch block
 }

}

}

fileReader.read();aにキャストする必要があることに注意してください。そうしないとchar間違った出力が得られます。リセットする必要があります。countそうcount<4しないと、最初の実行後は true になりません (そうしないためfileReader.read()、無限ループに陥ります)。 、読み取りごとに準備ができているかどうかをテストする必要があります(またはブロックする可能性があります)

編集:明らかに、これは例です。str += somethingループ内でストレートを行うべきではありませんが、を使用してStringBuffer、発生する可能性のある例外をキャッチして処理してください。

2 番目の編集に関する注意: これが集中的な手順である場合、これは間違っています。私はそれを正しく行うことができるかどうかを確認します (後戻りせずに)

まだ別の編集:

import java.io.*;

public class Test {


  public static void main(String[] args) {
    StringBuffer buffer = new StringBuffer();
    int length = 4;

    try {
      Reader fileReader = new BufferedReader(new FileReader("teststring"));
      for (int i = 0; i < length && fileReader.ready(); i++) {
        buffer.append((char) fileReader.read());
      }

      while (fileReader.ready()) {
        System.out.println(buffer); // send str to another function and do
                                    // something with it;
        buffer.deleteCharAt(0);
        buffer.append((char) fileReader.read());

      }
      System.out.println(buffer); // send str to another function and do
                                 // something with it;
    }
    catch (IOException e) {
      // TODO Auto-generated catch block
    }

  }

}

何かを実行するメソッドへの繰り返し呼び出しはまだきれいではありませんが、これははるかに近いものです。

于 2010-11-12T21:33:05.803 に答える
0

mark()メソッドはファイル内の位置をマークします。reset()を呼び出す前に読み取るバイト数を指定できます。これにより、ストリームがマークされたポイントに再配置されます。したがって、通常、データの先頭で mark() を呼び出してから、次の反復の前に reset を呼び出す必要があります。

   while (count <  4){
    if(count>0) {
      fileReader.reset();
    }
    fileReader.mark(1000);
    str += fileReader.read();
    count++;
   }
于 2010-11-12T21:20:58.430 に答える
0

質問が求めたように、ほとんどの人が FileReader を使用することを好むようですが、代わりにスキャナーを使用する方が使いやすいので、代わりにスキャナーを使用することを好みます。だからここに私の例があります:

import java.util.Scanner;
import java.io.File;
    private void fileReader(){
        String str;
        try {
            input = new Scanner(new File("FILENAME"));
        } catch (Exception e) {
            System.out.println("Scanner load failed.");
        }
        while(input.hasNext()){
            str+=input.next()+" ";
        }
        input.close();
        int j=0;
        for(int i=3;i<str.length();i++){
            DoSomething(str.substring(j,i));
            j++;
        }
    }

これにより、各行が読み取られて文字列に追加され、文字列が 4 バイト単位で DoSomething メソッドに送信されます。

役立つことを願っています。

Edit1: この編集を削除しました。

編集2:

コメントであなたが望んでいたことを読みました..そして、それはどのコードでも簡単に実行できます。実際、この変更を反映するために上部のコードを変更します。

うーん..ええ..それはうまくいくはずです.. :)

于 2011-04-22T18:21:43.350 に答える
-2

私の考えはCharConsumer、たくさんの文字を消費することの意味を定義するを定義することです。それから私は任意のものを取り、Readerそれを最後まで読むメソッドを書きました。別の終了条件が必要な場合は、を置き換えてwhile (true)ください。

メソッドへの入力をconsumeバッファリングする必要がある場合は、必ず1つだけ作成しBufferedReader、その後はもう1つのリーダーを使用しないでください。そうしないと、一部の文字が読み取り中に失われる可能性があります。

package so4168937;

import java.io.EOFException;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;

public class Main {

  // unused, since the question was initially unclear
  public static void consumeFourInARow(Reader rd, CharConsumer consumer) throws IOException {
    char[] chars = new char[4];
    while (true) {
      for (int i = 0; i < chars.length; i++) {
        int c = rd.read();
        if (c == -1) {
          if (i == 0)
            return;
          throw new EOFException("Incomplete read after " + i + " characters.");
        }
        chars[i] = (char) c;
      }
      consumer.consume(chars);
    }
  }

  public static void consume(Reader rd, CharConsumer consumer) throws IOException {
    char[] chars = new char[4];
    int c;

    for (int i = 0; i < chars.length; i++) {
      if ((c = rd.read()) == -1) {
        return;
      }
      chars[i] = (char) c;
    }
    consumer.consume(chars);

    while ((c = rd.read()) != -1) {
      System.arraycopy(chars, 1, chars, 0, chars.length - 1);
      chars[chars.length - 1] = (char) c;
      consumer.consume(chars);
    }
  }

  interface CharConsumer {
    void consume(char[] chars);
  }

  public static void main(String[] args) throws IOException {
    final StringBuilder sb = new StringBuilder();
    consume(new StringReader("hi my name is joe..."), new CharConsumer() {
      @Override
      public void consume(char[] chars) {
        sb.append('<');
        sb.append(chars);
        sb.append('>');
      }
    });
    System.out.println(sb.toString());
  }

}

更新[2010-11-15]:古いコードを単純な循環バッファーを実装するコードに置き換えました。これは明らかに元の質問で求められていたものです。

于 2010-11-12T22:25:47.447 に答える