Чтение части файла с помощью BufferedReader - PullRequest
1 голос
/ 12 ноября 2010

Я пытаюсь написать функцию, которая захватывает определенную часть файла, отправляет ее в другую функцию, а затем продолжает делать то же самое с того места, где остановился 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
  }

Может кто-нибудь помочь мне с этим и объяснить, что я делаю неправильно?Много было бы оценено

Ответы [ 8 ]

1 голос
/ 12 ноября 2010

Если вы знаете количество символов, используйте метод BufferedReader .skip(long), который говорит, что он пропускает первые long символы (где long - 64-битное целое число).

При вызове пропуска возвращается long с количеством фактически пропущенных символов.

0 голосов
/ 22 апреля 2011

Я вижу, что большинство из вас предпочитают использовать 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: удалил это редактирование.

Edit2:

только что прочитал, что вы хотели в комментариях ... и это можно легко сделать с любым кодом, на самом деле я изменю свой код вверху, чтобы отразить это изменение.

хм .. да .. это должно работать ..:)

0 голосов
/ 18 ноября 2010

На основании Ответ Мартинса Я сделал код немного проще.

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 или reset, а использование ready только добавляет сложности и нежелательного поведения.

0 голосов
/ 13 ноября 2010

Зачем вообще маркировать и сбрасывать?Просто прочитайте 4 байта, обработайте их и повторяйте до EOF.

0 голосов
/ 13 ноября 2010

Я думаю, вам просто нужно сбросить count = 0 после DoSomething(Str). Прямо сейчас вы никогда не сбрасываете переменную count, и это не позволяет вам войти в цикл чтения файла.

0 голосов
/ 13 ноября 2010

Моя идея состоит в том, чтобы определить CharConsumer, который определяет, что значит использовать группу символов.Затем я написал метод, который принимает произвольный Reader и читает его до конца.Если вы хотите другое условие завершения, замените while (true) на него.

Если вам требуется буферизовать входные данные для метода consume, убедитесь, что вы создали ровно один BufferedReader и непосле этого используйте другой читатель.В противном случае некоторые символы могут быть потеряны при чтении.

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]: Заменен старый код на код, который реализует простой циклический буфер, который, очевидно,находился в розыске в оригинальном вопросе.

0 голосов
/ 13 ноября 2010

У меня работает следующее.Отредактировано после комментария.

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(); к char, иначе вы получите неправильный вывод, вам придется сбросить count, иначе count<4 не будетбыть верным всегда после первого запуска (а поскольку вы не выполните fileReader.read(), вы попадете в бесконечный цикл), и вам придется проверять готовность при каждом чтении (или вы можете заблокировать)

РЕДАКТИРОВАТЬ: Очевидно, это пример.Вы никогда не должны делать прямое str += something в цикле, а использовать StringBuffer, и ловить и обрабатывать возможное исключение.

Примечание по второму редактированию: если это интенсивная процедура, это делаетэто неправильно.Я посмотрю, смогу ли я сделать это правильно (без возврата)

ДАЙТЕ ДРУГОЕ РЕДАКТИРОВАНИЕ:

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
    }

  }

}

Повторный вызов метода, который делает что-то, все еще не симпатичен, но этонамного ближе.

0 голосов
/ 13 ноября 2010

Метод mark () отмечает позицию в файле, и вы можете указать, сколько байтов вы хотите прочитать перед вызовом reset () , что приведет к перемещению потока в отмеченную точку , Поэтому обычно вам нужно вызывать mark () в начале ваших данных, а затем вызывать reset перед следующей итерацией.

   while (count <  4){
    if(count>0) {
      fileReader.reset();
    }
    fileReader.mark(1000);
    str += fileReader.read();
    count++;
   }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...