繁体   English   中英

如何读取文本文件中字符串数据的特定位置

[英]How to read a specific position of a string data in a text file

我正在处理一个包含多达一千行的文本文件。 一个文本文件中有多个页眉和页脚。 所以我不需要处理包含@h和@f的行。 它告诉我事务的开始和结束(数据库事务,我将在一个事务中将这些记录保存到DB)。

样本记录如下。 虽然这条线达到了一千行而且列数达到了40列。 从每一行我只寻找一个特定的数据,即(例如,我需要从位置8到30获取一个名字,从60到67岁的年份和喜欢的名字)。 该位置可能是下一个空格或字符串之间。 因此,我不想将每行的数据放入缓冲区/内存中来处理它,因为我只对它们中的一些感兴趣。 CSV文件是否允许从一行中的特定位置获取数据? 我应该使用什么来获得更好的性能(尽可能快地处理数据而不占用太多内存。)? 我正在使用Java

@h Header
@074VH01MATT    TARA   A5119812073921 RONG HI  DE BET IA76200  201108222   0500  *
@074VH01KAYT    DJ     A5119812073921 RONG DED CR BET IA71200  201108222   0500  *
@f Footer

@h Header
@074VH01MATT    TARA   A5119812073921 RONG HI  DE BET IA76200  201108222   0500  *
@074VH01KAYT    DJ     A5119812073921 RONG DED CR BET IA71200  201108222   0500  *
@f Footer

这是我的解决方案:

import java.io.*;
class ReadAFileLineByLine 
{
 public static void main(String args[])
  {
  try{
    FileInputStream fstream = new FileInputStream("textfile.txt");
    BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
    String strLine;
    //Loop through and check if a header or footer line, if not
    //equate a substring to a temp variable and print it....
    while ((strLine = br.readLine()) != null)   {
      if (!(strLine.charAt(1) == "h" || strLine.charAt(1) == "f"))
        String tempName = strLine.substring(8,31);
      System.out.println(tempName);
    }
    //Close the input stream
    in.close();
  } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

你正在寻找的是这样的东西吗?

使用BufferedReader,因此它不会保存从InputStreamReader构造的内存中的所有内容,因此您可以指定字符集(因为FileReader的JavaDoc告诉您这样做) - 我的示例使用UTF-8,假设文件采用相同的编码。

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;

public class StringData {
    public static void main(String[] args) throws Exception {
        BufferedReader br = null;
        try {
            // change this value
            FileInputStream fis = new FileInputStream("/path/to/StringData.txt");
            br = new BufferedReader(new InputStreamReader(fis, "UTF-8"));
            String sCurrentLine;
            while ((sCurrentLine = br.readLine()) != null) {
                processLine(sCurrentLine);
            }
        } finally {
            if (br != null) br.close();
        }
    }

    public static void processLine(String line) {
        // skip header & footer
        if (line.startsWith("@h Header") || line.startsWith("@f Footer")) return;

        String name = line.substring(8, 22);
        String year = line.substring(63, 67);

        System.out.println("Name [" + name + "]\t Year [" + year +"]");
    }
}

产量

Name [MATT    TARA  ]    Year [2011] 
Name [KAYT    DJ    ]    Year [2011]

我不认为CSV是必须的,你是如何一行一行地阅读文件的? 我会一行一行,这样,读取每一行的内存并不昂贵(一次只有一行)。 您可以在该行上使用正则表达式,并仅使用您需要的组(使用Pattern和Matcher)来帮助准确提取所需内容。

不要担心记忆; 您可以将整个文件放在一个char数组中,而无需任何人注意。 CSV文件很痛苦,不会为您做任何事情。 只需将每一行读入缓冲区 - 一个字符串,或字符串或字节数组 - 并从中获取所需内容; 固定定位使其变得简单。

通常,在记忆和时间之间存在权衡。 我发现大缓冲区,比如1​​00Kb超过1Mb,而不是10Kb,可以加速你5到10倍。 (如果重要的话,用各种尺寸自己测试。如果我理解你的话,你说的是40Kb,所以不需要比这更大的缓冲区。(如果它是40 b然后进行测试。即使是40Mb阵列不会伤害你,但现在开始浪费内存。)),只是一定要关闭该文件才去上做其他工作释放的文件类(ES)引用,以便您的缓冲区等不记忆泄漏。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM