合并大文件而不将整个文件加载到内存中?
我想将包含字符串的大文件合并到一个文件中,并尝试使用nio2。 我不想将整个文件加载到内存中,所以我尝试使用BufferedReader:
public void mergeFiles(filesToBeMerged) throws IOException{ Path mergedFile = Paths.get("mergedFile"); Files.createFile(mergedFile); List _filesToBeMerged = filesToBeMerged; try (BufferedWriter writer = Files.newBufferedWriter(mergedFile,StandardOpenOption.APPEND)) { for (Path file : _filesToBeMerged) { // this does not work as write()-method does not accept a BufferedReader writer.append(Files.newBufferedReader(file)); } } catch (IOException e) { System.err.println(e); } }
我尝试了这个,这个工作,hower,字符串的格式(例如新行等不会被复制到合并文件):
... try (BufferedWriter writer = Files.newBufferedWriter(mergedFile,StandardOpenOption.APPEND)) { for (Path file : _filesToBeMerged) { // writer.write(Files.newBufferedReader(file)); String line = null; BufferedReader reader = Files.newBufferedReader(file); while ((line = reader.readLine()) != null) { writer.append(line); writer.append(System.lineSeparator()); } reader.close(); } } catch (IOException e) { System.err.println(e); } ...
如何在不将整个文件加载到内存的情况下将巨大的文件与NIO2合并?
如果你想有效地合并两个或多个文件,你应该问问自己,为什么你在使用基于char
的Reader
和Writer
来执行该任务。
通过使用这些类,您可以将文件的字节转换为字符,从系统的默认编码转换为unicode,然后从unicode转换回系统的默认编码。 这意味着程序必须对整个文件执行两次数据转换。
顺便说一句, BufferedReader
和BufferedWriter
绝不是NIO2
工件。 这些类从Java的第一个版本开始就存在。
当您通过真正的NIO函数使用逐字节复制时,可以在不被Java应用程序触及的情况下传输文件,在最好的情况下,传输将直接在文件系统的缓冲区中执行:
import static java.nio.file.StandardOpenOption.*; import java.io.IOException; import java.nio.channels.FileChannel; import java.nio.file.Path; import java.nio.file.Paths; public class MergeFiles { public static void main(String[] arg) throws IOException { if(arg.length<2) { System.err.println("Syntax: infiles... outfile"); System.exit(1); } Path outFile=Paths.get(arg[arg.length-1]); System.out.println("TO "+outFile); try(FileChannel out=FileChannel.open(outFile, CREATE, WRITE)) { for(int ix=0, n=arg.length-1; ix
同
Files.newBufferedReader(file).readLine()
你每次创建一个新的缓冲区,它总是在第一行重置。
用。。。来代替
BufferedReader reader = Files.newBufferedReader(file); while ((line = reader.readLine()) != null) { writer.write(line); }
和.close()
读者完成后。
readLine()
不会产生行结尾(“\ n”或“\ r \ n”)。 那是错误。
while ((line = reader.readLine()) != null) { writer.write(line); writer.write("\r\n"); // Windows }
您也可以忽略对(可能不同的)行结尾的过滤,并使用
try (OutputStream out = new FileOutputStream(file); for (Path source : filesToBeMerged) { Files.copy(path, out); out.write("\r\n".getBytes(StandardCharsets.US_ASCII)); } }
如果最后一行没有以换行符结束,则会明确写入换行符。
可选的,难看的Unicode BOM字符可能仍然存在问题,以在文件开头将文本标记为UTF-8 / UTF-16LE / UTF-16BE。
- 无法从START_ARRAY标记中反序列化java.util.HashMap的实例
- 空指针exception
- 将JSON结构转换为BasicDBObject
- 使用hadoop指定内存限制
- java中的java.lang.ClassNotFoundException:org.springframework.web.context.ContextLoaderListener
- 使用多个数据源时Spring中存在多个实体管理器问题
- Java – 无法调用编译错误方法
- Java SSO:针对Active Directory的Kerberos身份validation
- 如何跟踪和防止在单独进程中运行的c3po中出现的死锁?