ファイルは非常に大きく、分割ファイルすることができますので、それ自体がaswell大きくなる可能性がある:
例:
ソースファイルサイズ:5ギガバイト
のNumスプリット:5:デスティネーション
ファイルサイズ:1GB(5ファイル)
このようなメモリがあっても、この大きな分割チャンクを一度に読み取る方法はありません。基本的に各分割ごとに、性能とメモリの両方で実現可能なフィックスサイズbyte-array
を読むことができます。
NumSplits:10 MaxReadBytes:8キロバイト
public static void main(String[] args) throws Exception
{
RandomAccessFile raf = new RandomAccessFile("test.csv", "r");
long numSplits = 10; //from user input, extract it from args
long sourceSize = raf.length();
long bytesPerSplit = sourceSize/numSplits ;
long remainingBytes = sourceSize % numSplits;
int maxReadBufferSize = 8 * 1024; //8KB
for(int destIx=1; destIx <= numSplits; destIx++) {
BufferedOutputStream bw = new BufferedOutputStream(new FileOutputStream("split."+destIx));
if(bytesPerSplit > maxReadBufferSize) {
long numReads = bytesPerSplit/maxReadBufferSize;
long numRemainingRead = bytesPerSplit % maxReadBufferSize;
for(int i=0; i<numReads; i++) {
readWrite(raf, bw, maxReadBufferSize);
}
if(numRemainingRead > 0) {
readWrite(raf, bw, numRemainingRead);
}
}else {
readWrite(raf, bw, bytesPerSplit);
}
bw.close();
}
if(remainingBytes > 0) {
BufferedOutputStream bw = new BufferedOutputStream(new FileOutputStream("split."+(numSplits+1)));
readWrite(raf, bw, remainingBytes);
bw.close();
}
raf.close();
}
static void readWrite(RandomAccessFile raf, BufferedOutputStream bw, long numBytes) throws IOException {
byte[] buf = new byte[(int) numBytes];
int val = raf.read(buf);
if(val != -1) {
bw.write(buf);
}
}
whileループでは、必要なだけ多くの行をStringまたはStringBuilderに集めて別々のファイルに書き込んでください。ファイル内の最大行数を定義することは、あらかじめファイルの数を知ることはできません。 –
2回、線の数を取得するために1回、分割するために1回ループする必要があります。または、線の数を推測してそのように分割することもできます。 –
@ kw4ntaなぜ地球上であなたはラインを保存したいでしょうか? 1)OPは、すべての行を格納することはオプションではない、2)行を別のファイルに直接書くことができるとすれば... –