2

最大 1000 行を含むテキスト ファイルを処理しています。1 つのテキスト ファイルに複数のヘッダーとフッターがあります。したがって、@h と @f を含む行を処理する必要はありません。トランザクションの開始と終了を教えてくれます (データベース トランザクション、これらのレコードを 1 つのトランザクションで DB に保存します)。

サンプル レコードは次のとおりです。行は最大1000行に達し、列は最大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
4

4 に答える 4

5

これが私の解決策です:

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();
    }
  }
}

このようなものをお探しですか?

于 2012-06-26T17:23:32.407 に答える
4

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]
于 2012-06-26T17:56:56.497 に答える
1

CSVは必須ではないと思いますが、ファイルを1行ずつ、または一度にどのように読んでいますか?私は行ごとに行きます、そうすれば、各行を読み取ることはメモリ内でコストがかかりません(一度に1行だけ)。行で正規表現を使用し、必要なグループ(PatternとMatcherを使用)のみを取得して、必要なものを正確に抽出することができます。

于 2012-06-26T17:15:38.557 に答える
0

メモリについて心配する必要はありません。誰にも気づかれずに、ファイル全体を 1 つの char 配列に入れることができます。CSV ファイルは面倒で、何もしてくれません。各行をバッファ (文字列、文字、またはバイト配列) に読み込み、そこから必要なものを取得するだけです。位置が固定されているので簡単です。

一般に、メモリと時間の間にはトレードオフがあります。10Kb とは対照的に、100Kb から 1Mb 以上の大きなバッファを見つけたところ、5 倍から 10 倍高速化できます。(問題がある場合は、さまざまなサイズで自分でテストしてください。私が正しく理解していれば、40Kb について話しているので、それよりも大きなバッファーは必要ありません。(40メガb の場合は、テストを行います。40Mb アレイでも)害はありませんが、メモリを浪費し始めています。)) 他の作業を行う前に、必ずファイルを閉じてファイル クラスへの参照を解放してください。そうすれば、バッファなどはメモリではありません。リーク。

于 2012-06-26T17:52:33.617 に答える