【问题标题】:Read special line from txt file in j2me从 j2me 中的 txt 文件中读取特殊行
【发布时间】:2011-04-26 18:32:07
【问题描述】:

我有一个文本文件,例如:file.txt,我想读取一行,例如第7行,有什么方法可以直接读取第7行而不读取其他行?我想从这项工作中节省内存。

【问题讨论】:

  • 您可以检查一个字符(或制表符)并跳到下一个字符(或制表符)。这也会加快速度
  • 解析成字符串占用内存,这种方法效率不高
  • 你现在用什么代码来读取文件?

标签: java-me file-processing memory-optimization


【解决方案1】:

由于 JME 被削减的方式,你不能这样做。您将不得不阅读整个文件。只有另一种方式,但可能不太适合是读取文件,将其存储在 RecordStore 中每行新条目,但它真的值得......

【讨论】:

    【解决方案2】:

    我认为有可能,但是您需要使用哈希表,这可能会导致更多的堆使用。

    无论如何,首先,文本文件的内容应该存储在一个 char 数组中。然后,其次,必须将 char 数组的内容移动到哈希表中。

    文本文件中的每一行都由一个新行分隔。在 char 数组中,新行(可能)被转换为 '\n'。连接数组中的字符,直到到达换行符。连接的字符(减去'\n')将形成第一行中的字符串。这里还应该有一个计数器,它应该被初始化为 0(或 1,无论你喜欢什么)。将文本保存到哈希表;值将是已创建的字符串,键将是计数器。之后增加计数器。对数组的其余部分重复此过程,直到到达文件末尾。

    使用哈希表,您现在可以在第 7 行获取字符串,而无需通过其他行。好吧,基本上,每一行都被读过一次。但是,至少,一旦将它们存储在哈希表中,您就不必遍历每一行。

    就像我之前所说的那样,这样做可能会增加堆使用量,尤其是在文本文件非常大的情况下。

    [顺便说一下,很抱歉回复得太晚了。这是我第一次来这里(我的意思是我刚刚注册并回答了这个问题):D]

    【讨论】:

      【解决方案3】:

      通用代码

      private String readLine(InputStream _inStream, int lineNum) 
                  throws IOException {
          if (null == _inStream) {
              throw new IOException("Inputstream null.");
          }
          if (lineNum < 0) {
              return ("Cannot read line a number " + lineNum);
          }
      
          final StringBuffer buf = new StringBuffer();
          byte c;
      
          int curLine = 1;
          while (((c = (byte) _inStream.read()) != -1)) {
              //System.out.println((char)c);
              if (c == '\n') {
                  ++curLine;
                  if (curLine > lineNum) {
                      break;
                  } else if (curLine < lineNum) {
                      continue;
                  }
              } else if (curLine != lineNum) {
                  continue;
              }
              buf.append((char) c);
          }
      
          if (0 == buf.length()) {
              return null;
          } else {
              return buf.toString().trim();
          }
      }
      

      .

      private String readLineWithSkip(InputStream _inStream, long skipCharacters) 
                  throws IOException {
          if (null == _inStream) {
              throw new IOException("Inputstream null.");
          }
          if (skipCharacters < 1) {
              return ("Cannot skip stream of " + skipCharacters + " characters");
          }
      
          final StringBuffer buf = new StringBuffer();
          byte c;
      
          _inStream.skip(skipCharacters);
          while ((c = (byte) _inStream.read()) != '\n') {
              //System.out.println((char)c);
              buf.append((char) c);
          }
      
          if (0 == buf.length()) {
              return null;
          } else {
              return buf.toString().trim();
          }
      }
      

      .

      InputStream inStream = null;
      int fileLength = 39;
      int skipCharacters = 10;
      int lineNumber = 3;
      String myLine = "No line read.";
      try {
          inStream = Class.class.getResourceAsStream("/test.txt");
          if (null != inStream) {
              inStream.mark(fileLength);
      
          //For Approach II
              myLine = readLine(inStream, lineNumber);
      
              inStream.reset();
          //For Approach I
              myLine = readLineWithSkip(inStream, skipCharacters);
          }
      } catch (SecurityException se) {
          se.printStackTrace();
      
      } catch (IOException ioe) {
          ioe.printStackTrace();
      
      } finally {
          try {
              inStream.close();
          } catch (IOException ex) {
              ex.printStackTrace();
          } catch (NullPointerException e) {
              e.printStackTrace();
          }
          inStream = null;
      
          System.out.println(myLine);
      }
      

      .

      方法一: 映射没有累积字符的行号

      1. 通过代码运行文件,该代码从文件的第 0 位开始将行号与该行中的最后一个字符映射(用作 skip() 值)所有 +2 ('\r\n\' ) 为每一行。您可以将此映射表存储在同一文件的开头或结尾。
      2. 使用方法readLineWithSkip(inStream, 跳过字符);仅明智地评论其他方法调用。

      需要考虑的要点:

      1. 跳到输入流中的所需位置
      2. 有解析文件和存储映射表的开销。

      .

      方法二: 读取每一行,直到读完第N行

      1. 使用方法readLine(inStream, 电话号码);仅明智地评论其他方法调用。

      需要考虑的要点:

      1. 很慢,因为它必须读取每个字符直到到达所需的行
      2. 没有解析文件的开销,也没有映射表的存储。

      【讨论】:

        【解决方案4】:

        我想进一步简化读取字符的问题,而不需要任何字符与行号的映射。

        ...
                          Form form=new Form("filename");
                          InputStream fin=fconn.openDataInputStream();
                          StringBuffer buf =new StringBuffer();
                          int c;
                          int counter=-1;
                          while((c=fin.read())!=-1)
                          {   
                              counter++;
                              if(counter==23)
                              {
                                  form.append(buf.toString());
                                  buf=null;counter=0;
                                  continue;
                              }
        
                              buf.append((char)c);
                          }
                          if(counter<23 && counter>=0) // write the skipped chars between the last number read and the end of file
                          {
                            form.append(buf.toString());
                            buf=null;counter=0;
                          }
                          fin.close();
                          ...
        

        希望这对其他人有所帮助。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-01-28
          • 2017-10-02
          • 1970-01-01
          • 2020-11-18
          • 2014-06-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多