5

在一个 java 项目中,我生成一个大的 csv 文件(大约 500 Mb),我需要将该文件拆分为多个文件,每个文件最多 10 Mb 大小。我发现很多类似的帖子,但其中任何一个都回答了我的问题,因为在所有帖子中,Java 代码将原始文件拆分为正好 10 Mb 的文件,并且(显然)截断记录。相反,我需要每条记录都是完整的、完整的。任何记录都应该被截断。如果我将记录从原始大 csv 文件复制到一个生成的文件,并且如果我复制记录,文件尺寸将溢出 10 Mb,我应该能够不复制该记录,关闭该文件,创建一个新文件并将记录复制到新的记录中。可能吗?有人能帮我吗?谢谢!

我试过这段代码:

File f = new File("/home/luca/Desktop/test/images.csv");
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f));
FileOutputStream out;
String name = f.getName();
int partCounter = 1;
int sizeOfFiles = 10 * 1024 * 1024;// 1MB
byte[] buffer = new byte[sizeOfFiles];
int tmp = 0;
while ((tmp = bis.read(buffer)) > 0) {
 File newFile=new File("/home/luca/Desktop/test/"+name+"."+String.format("%03d", partCounter++));
 newFile.createNewFile();
 out = new FileOutputStream(newFile);
 out.write(buffer,0,tmp);
 out.close();
}

但显然行不通。此代码将源文件拆分为 n 个 10Mb 文件以截断记录。在我的情况下,我的 csv 文件有 16 列,因此通过上面的过程,例如,最后一条记录只填充了 5 列。其他被截断。

解决方案 这里是我写的代码。

FileReader fileReader = new FileReader("/home/luca/Desktop/test/images.csv");
BufferedReader bufferedReader = new BufferedReader(fileReader);
String line="";
int fileSize = 0;
BufferedWriter fos = new BufferedWriter(new FileWriter("/home/luca/Desktop/test/images_"+new Date().getTime()+".csv",true));
while((line = bufferedReader.readLine()) != null) {
    if(fileSize + line.getBytes().length > 9.5 * 1024 * 1024){
        fos.flush();
        fos.close();
        fos = new BufferedWriter(new FileWriter("/home/luca/Desktop/test/images_"+new Date().getTime()+".csv",true));
        fos.write(line+"\n");
        fileSize = line.getBytes().length;
    }else{
        fos.write(line+"\n");
        fileSize += line.getBytes().length;
    }
}          
fos.flush();
fos.close();
bufferedReader.close();

此代码读取一个 csv 文件并将其拆分为 n 个文件,每个文件最多 10 Mb 大,并且每个 csv 行被完全复制或根本不复制。

4

2 回答 2

3

原则上非常简单。

您创建一个 10MB (byte[]) 的缓冲区并从源中读取尽可能多的字节。然后从后面搜索换行符。从缓冲区开始到换行的部分 = 新文件。您保留您已阅读的部分,并将其复制到缓冲区的开头(偏移量 0)。你重复一切,直到没有更多的来源。

于 2013-10-28T13:51:26.663 回答
0

用这个split -a 3 -b 100m -d filename.tar.gz newfilename

于 2013-12-02T02:41:46.210 回答