3

2億5000万文字近くの大きなファイルがあります。ここで、それぞれに3,000万文字が含まれる部分に分割したいと思います(したがって、最初の8つの部分には3,000万文字が含まれ、最後の部分には1,000万文字が含まれます)。もう1つのポイントは、各ファイルの最後の1000文字を次のパートの先頭に含めたいということです(つまり、パート1の最後の1000文字が2番目のパートの先頭に追加されます。つまり、2番目のパートには3000万の1000文字が含まれます)。誰かがプログラムで(Javaを使用して)またはLinuxコマンドを(高速で)使用してそれを行う方法を教えてもらえますか?

4

4 に答える 4

2

適切なオプションを使用して、splitまたはcsplitコマンドを使用するだけです。

これらのプログラムをより複雑なシェルスクリプトで駆動するか、他のスクリプト言語を使用して、適切な引数を与えることができます(特に、重複する要件に対処するため)。おそらく、それらを他のユーティリティ(greporheadまたはortailまたはsedorawkなど)と組み合わせることができます。

于 2012-06-24T18:28:56.227 に答える
2

1つの方法は、通常のUNIXコマンドを使用してファイルを分割し、前のファイルの最後の1000バイトを先頭に追加することです。

最初にファイルを分割します。

split -b 30000000 inputfile part.

次に、各部分について(最も遠いものを無視して、前の最後の1000バイトから始まる新しいファイルを作成します。

unset prev
for i in part.*
do if [ -n "${prev}" ]
  then 
    tail -c 1000 ${prev} > part.temp
    cat ${i} >> part.temp
    mv part.temp ${i}
  fi
  prev=${i}
done

組み立てる前に、最初のファイルを無視して最初の1000バイトを破棄し、ファイルを繰り返し処理します。

unset prev
for i in part.*
do if [ -n "${prev}" ]
  then 
    tail -c +1001 ${i} > part.temp
    mv part.temp ${i}
  fi
  prev=${i}
done

最後のステップは、ファイルを再アセンブルすることです。

cat part.* >> newfile

オーバーラップが必要な理由の説明がなかったので、私はそれを作成してから捨てました。

于 2012-06-24T19:10:37.707 に答える
2

あなたはこれを試すことができます。最初はファイルが存在しなかったので、初めて読み取り/モードを使用する必要があります。このコードが示唆するように、読み取り専用で使用してください。

long start = System.nanoTime();
long fileSize = 3200 * 1024 * 1024L;
FileChannel raf = new RandomAccessFile("deleteme.txt", "r").getChannel();
long midPoint = fileSize / 2 / 4096 * 4096;
MappedByteBuffer buffer1 = raf.map(FileChannel.MapMode.READ_ONLY, 0, midPoint + 4096);
MappedByteBuffer buffer2 = raf.map(FileChannel.MapMode.READ_ONLY, midPoint, fileSize - midPoint);
long time = System.nanoTime() - start;
System.out.printf("Took %.3f ms to map a file of %,d bytes long%n", time / 1e6, raf.size());

これは、4GBのメモリを搭載したWindow7x64ボックスで実行されています。

Took 3.302 ms to map a file of 3,355,443,200 bytes long
于 2012-06-24T19:25:25.573 に答える
1

BreakIteratorクラスとその静的メソッドgetCharacterInstance()を使用してこれを行うことができます。デフォルトロケールの文字区切りの新しいBreakIteratorインスタンスを返します。

getWordInstance()、getLineInstance()..を使用して、単語や行などを分割することもできます。

例えば:

BreakIterator boundary = BreakIterator.getCharacterInstance();

boundary.setText("Your_Sentence");

int start = boundary.first();

int end = boundary.next();

Iterate over it... to get the Characters....

For more detail look at this link:

http://docs.oracle.com/javase/6/docs/api/java/text/BreakIterator.html

于 2012-06-24T18:59:02.937 に答える