如何在Java中处理一个巨大的一行文件
我需要读取一个巨大的文件(15 GB)并执行一些小的修改(添加一些换行符,以便不同的解析器可以真正地使用它).您可能会认为已经有正常的答案:
> Reading a very huge file in java 但我的整个文件在一行. 目前我的一般做法是非常基本的: char[] buffer = new char[X]; BufferedReader reader = new BufferedReader(new ReaderUTF8(new FileInputStream(new File("myFileName"))),X); char[] bufferOut = new char[X+a little]; int bytesRead = -1; int i = 0; int offset = 0; long totalBytesRead = 0; int countToPrint = 0; while((bytesRead = reader.read(buffer)) >= 0){ for(i = 0; i < bytesRead; i++){ if(buffer[i] == '}'){ bufferOut[i+offset] = '}'; offset++; bufferOut[i+offset] = 'n'; } else{ bufferOut[i+offset] = buffer[i]; } } writer.write(bufferOut,bytesRead+offset); offset = 0; totalBytesRead += bytesRead; countToPrint += 1; if(countToPrint == 10){ countToPrint = 0; System.out.println("Read "+((double)totalBytesRead / originalFileSize * 100)+" percent."); } } writer.flush(); 经过一番实验,我发现X值超过一百万的值可以提供最佳的速度 – 看起来我每10分钟就会得到2%左右,而X值约为60,000的值在15小时内只有60% .分析显示我花了96%的时间在read()方法中,这绝对是我的瓶颈.在撰写本文时,我的800万X版本在2小时40分钟后已完成文件的32%,以防您想知道如何执行长期. 是否有更好的处理这样大的一行文件的方法?像在这里,是否有更快的方法来阅读这种类型的文件,给我一个相对容易的插入换行符的方法? 我知道不同的语言或程序可能会很好地处理这个问题,但我将其限制在Java视角. 解决方法
你所做的这个比现在要复杂得多.通过使用标准类提供的缓冲区,您应该获得至少几MB的每秒钟数,而不会有任何麻烦.
这个简单的测试程序在我的电脑上不到2分钟内处理1GB(包括创建测试文件): import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.Writer; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.Random; public class TestFileProcessing { public static void main(String[] argv) { try { long time = System.currentTimeMillis(); File from = new File("C:TestInput.txt"); createTestFile(from,StandardCharsets.UTF_8,1_000_000_000); System.out.println("Created file in: " + (System.currentTimeMillis() - time) + "ms"); time = System.currentTimeMillis(); File to = new File("C:TestOutput.txt"); doIt(from,to,StandardCharsets.UTF_8); System.out.println("Converted file in: " + (System.currentTimeMillis() - time) + "ms"); } catch (IOException e) { throw new RuntimeException(e.getMessage(),e); } } public static void createTestFile(File file,Charset encoding,long size) throws IOException { Random r = new Random(12345); try (OutputStream fout = new FileOutputStream(file); BufferedOutputStream bout = new BufferedOutputStream(fout); Writer writer = new OutputStreamWriter(bout,encoding)) { for (long i=0; i<size; ++i) { int c = r.nextInt(26); if (c == 0) writer.write('}'); else writer.write('a' + c); } } } public static void doIt(File from,File to,Charset encoding) throws IOException { try (InputStream fin = new FileInputStream(from); BufferedInputStream bin = new BufferedInputStream(fin); Reader reader = new InputStreamReader(bin,encoding); OutputStream fout = new FileOutputStream(to); BufferedOutputStream bout = new BufferedOutputStream(fout); Writer writer = new OutputStreamWriter(bout,encoding)) { int c; while ((c = reader.read()) >= 0) { if (c == '}') writer.write('n'); writer.write(c); } } } } 当您看到没有精心制作的逻辑或使用过多的缓冲区大小.使用的是简单地缓冲最接近硬件的流FileInput / OutputStream. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- java – Ebean @ManyToOne,finder不检索相关对象的所有数据
- java – 使用subprocess.Popen的奇怪执行模式
- java – JSP EL:动态创建属性名
- Java CookieStore 类使用示例
- java – ArrayList删除索引为0和1的元素
- Java和MySQL中的时间戳和时区转换
- 统一身份访问管理平台 -- Identity Access management plat
- 在独立Java类中使用ClassPathXmlApplicationContext
- java – HttpClient发布进度和MultipartEntityBuilder
- java – 使用ImageIO.write()创建JPEG创建一个0字节的文件