【问题标题】:InputStreamReader and reading random lines from .txt fileInputStreamReader 并从 .txt 文件中读取随机行
【发布时间】:2012-01-02 19:57:20
【问题描述】:

我有一种方法让我的应用程序从文本文件中读取随机行并将其返回。我使用 randTxt() 从 txt 文件中读取并返回随机行。 但它每次只显示同一行(第一行)。

public String randTxt(){

  // Read in the file into a list of strings
  InputStreamReader inputStream = new InputStreamReader(getResources().openRawResource(R.raw.randomstuff));
  //ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

  String theLine="";
  int i;
  try {
    i = inputStream.read();
    while (i != -1) {
      i = inputStream.read();
    }
  } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }

  LineNumberReader  rdr = new LineNumberReader(inputStream);
  int numLines = 30;
  Random r = new Random();
  rdr.setLineNumber(r.nextInt(numLines));

  try {
    theLine = rdr.readLine();
  } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }

  return theLine;
}

我该如何解决?有人可以解释我的代码有什么问题吗?

【问题讨论】:

  • 在调试器中单步调试代码时,您学到了什么?

标签: java android inputstreamreader


【解决方案1】:

这是使用 BufferedReader 完成所需工作的框架。在这种情况下,您不需要将值存储在临时数组中。

InputStreamReader inputStream = new InputStreamReader
  (getResources().openRawResource(R.raw.randomstuff));
BufferedReader br = new BufferedReader(inputStream);
int numLines = 30;
Random r = new Random();
int desiredLine = r.nextInt(numLines);

String theLine="";
int lineCtr = 0;
while ((theLine = br.readLine()) != null)   {
  if (lineCtr == desiredLine) {
    break;
  }
  lineCtr++;
 }
...
Log.d(TAG, "Magic line is: " +theLine);

【讨论】:

  • 谢谢我已经尝试过了,但它有一个我一直在尝试修复的错误:BufferedReader br = new BufferedReader(new InputStreamReader (inputStream, "UTF-8"));错误:构造函数 InputStreamReader(InputStringReader,String) 未定义。
  • 哎呀,我相信应该是“BufferedReader br = new BufferedReader(inputStream)”。我已经编辑过了 - 你现在可以试试吗?
【解决方案2】:

您已经得到了如何修复代码的答案,但没有解释为什么我们的原始代码不起作用。

LineNumberReader.setLineNumber(int) 不会转到实际行,它只是更改您调用当前行的数字。

所以,假设你读了两行,getLineNumber() 现在将返回 2(它从 0 开始,每次遇到换行时增加 1)。如果您现在 setLineNumber(10)getLineNumber() 将返回 10。读取另一行(您的第三行)将导致 getLineNumber()返回 11。

这在Java Doc 中有描述。

【讨论】:

  • 谢谢,我想我太兴奋了:D
【解决方案3】:

inputStream.read 不返回行号。它返回读取的字节。这不是您逐行阅读的方式。要逐行读取,您应该使用缓冲读取器的 readLine 方法。那时可能更容易将其全部读入本地数组并使用该数组随机获取一个条目,而不是使用行号阅读器。

【讨论】:

  • 我的文本文件有很长的字符串。我认为将其加载到数组中不是一个好主意。
  • 文件的行数是静态的还是动态的?如果它是静态的,您可以将其用作基础。既然是android,为什么不直接把文件内容放到sqllite数据库中呢?
  • 再看一点,如果您想了解一种更快的方法来计算文件中的行数,请看这里:stackoverflow.com/questions/453018/…
  • 它是静态的。因为我只是一个初学者,我根本没有使用过sqlite。
【解决方案4】:

我认为 Random() 函数返回一个介于 0 和 1 之间的值。因此,您可能必须将其乘以 100 才能得到一个整数值。甚至可以考虑一个MOD“你的上限”操作来保证你最终得到的索引在0和你的上限之间

在你的 setLineNumber() 方法中使用你计算的索引。

编辑: 正如 john 所说,我们可以使用 Random() 对象获取整数。

【讨论】:

【解决方案5】:
public String getRandomLine(String fileLoc) throws IOException
{
    BufferedReader reader = new BufferedReader(new FileReader(fileLoc));
    ArrayList<String> lines = new ArrayList<String>();

    String line =null;
    while( (line = reader.readLine())!= null ) 
        lines.add(line);

    // Choose a random one from the list
    return lines.get(new Random().nextInt(lines.size()));
}
public String getRandomLineOpt(String fileLoc)throws IOException
{
    File f=new File(fileLoc);
    RandomAccessFile rcf=new RandomAccessFile(f, "r");
    long rand = (long)(new Random().nextDouble()*f.length());
    rcf.seek(rand);
    rcf.readLine();
    return rcf.readLine();
}

【讨论】:

  • 感谢您发布答案!虽然代码 sn-p 可以回答这个问题,但添加一些附加信息仍然很棒,比如解释等 ..
猜你喜欢
  • 2017-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-29
  • 1970-01-01
  • 2022-12-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多