java IO 流操作
来源:互联网 发布:origin最新版软件 编辑:程序博客网 时间:2024/04/28 10:25
因为最近项目有关于大本文读取和指定行读取,读取第多少行到多少行记录,所以就从网上查询一些资料和自己的一些代码总结。
这里通过一个图简单介绍下java的IO流。
IO流分类
- 根据留得数据对象区分:
高端流:所有内存中的流都属于高端流,比如:InputStreamReader。
低端流:所有的外界设备中的流都属于低端流,比如InputStream。 根据数据的流向区分:
输出流:用来写数据的,由程序(内存)–>>外接设备。
输入流:用来读取数据的,由外界设备–>>程序(内存)。
区分:输入流带有Input,输出流带有Output。根据流数据的格式区分:
字节流:处理声音或者图片等二进制的数据的流,比如InputStream 。
字符流:处理文本数据(如txt文件)的流,比如InputStreamReader。根据流数据的包装过程来区分:
原始流:在实例化流的对象的过程中,不需要另外传入一个流作为自己构造方法的参数的流。
包装流:在实例化流的对象的过程中,需要传入另外一个流作为自己构造方法参数的流。
区分:所有的低端流都是原始流,所有的高端流都是包装流。IO流对象的继承关系图
关于更为细致的分类这里略过,下面简单介绍下几个案例。读取第100万之后的100条数据。
方法代码:
// 按照行号读取文本数据 public static String readByNum(int lineNumber) throws Exception { String str = null; FileReader fr = new FileReader(path); LineNumberReader lr = new LineNumberReader(fr); if (lineNumber < 0 || lineNumber > getTotalLines(new File(path))) { log.debug("不在文件的行数范围之内。"); } int i = 1; long start = System.currentTimeMillis(); while((str=lr.readLine())!=null){ i++; if(i>=1000000&&i<1000015){ log.debug(lr.readLine()); } } long end = System.currentTimeMillis(); fr.close(); lr.close(); log.debug("====方法readByNum(int lineNumber)耗时:"+(end-start)+"毫秒"); return str; } // 文件内容的总行数。 public static int getTotalLines(File file) throws IOException { FileReader in = new FileReader(file); LineNumberReader reader = new LineNumberReader(in); String s = reader.readLine(); int lines = 0; while (s != null) { lines++; s = reader.readLine(); } reader.close(); in.close(); return lines; }
测试结果如下:因为数据太大,这里测试100w的后10条数据
2016-04-12 21:22:17.321 DEBUG [main][ReadbigTxt.java:53] - 0039892655~许水花2016-04-12 21:22:17.323 DEBUG [main][ReadbigTxt.java:53] - 0036102712~应金兰2016-04-12 21:22:17.323 DEBUG [main][ReadbigTxt.java:53] - 0031388582~景德镇市五金交电化工总公司供应站2016-04-12 21:22:17.324 DEBUG [main][ReadbigTxt.java:53] - 0023055030~胡秀梅2016-04-12 21:22:17.324 DEBUG [main][ReadbigTxt.java:53] - 0043752004~李吕华2016-04-12 21:22:17.324 DEBUG [main][ReadbigTxt.java:53] - 0023914932~汪炳荣2016-04-12 21:22:17.324 DEBUG [main][ReadbigTxt.java:53] - 0024564962~胡香凤2016-04-12 21:22:17.324 DEBUG [main][ReadbigTxt.java:53] - 0048613725~史三女2016-04-12 21:22:17.324 DEBUG [main][ReadbigTxt.java:53] - 0043763065~朱永有2016-04-12 21:22:17.325 DEBUG [main][ReadbigTxt.java:53] - 0053238145~夏松林2016-04-12 21:22:17.325 DEBUG [main][ReadbigTxt.java:53] - 0040854072~程林娇2016-04-12 21:22:17.325 DEBUG [main][ReadbigTxt.java:53] - 0029429342~张荣玖2016-04-12 21:22:17.325 DEBUG [main][ReadbigTxt.java:53] - 0048657929~董昌国2016-04-12 21:22:17.325 DEBUG [main][ReadbigTxt.java:53] - 0021460884~周忠德2016-04-12 21:22:17.326 DEBUG [main][ReadbigTxt.java:53] - 0036288939~陈伟涛2016-04-12 21:22:17.570 DEBUG [main][ReadbigTxt.java:60] - ====方法readByNum(int lineNumber)耗时:256毫秒
如果文本超过200M以上,需要使用缓存,每次读取10M放入缓存,操作之后再次读取。代码如下:
/** * 读取txt文件的内容 * @param file 想要读取的文件对象 * 一次读取一行记录 * 每次读取5m数据放入缓存,读取5000行存入文本,然后继续读取 * @return 返回文件内容 * @throws Exception */ public static String txt2String(File file) throws Exception{ FileWriter fw = null; String path = Utils.getProperty("connectPath2"); File f = new File(path); if (!f.exists()) { f.createNewFile(); } //写到文本 FileOutputStream fos = new FileOutputStream(f); OutputStreamWriter out = new OutputStreamWriter(fos, "UTF-8"); StringBuffer sb = new StringBuffer(); try{ FileInputStream in = new FileInputStream(file); // 指定读取文件时以UTF-8的格式读取 如果文件超过2G可以改为10M缓存 BufferedReader br = new BufferedReader(new InputStreamReader(in,"UTF-8"),5*1024*1024); // 用5M的缓冲读取文本文件 //BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件 String s = null; int count = 0;//计数器 while((s = br.readLine())!=null){//使用readLine方法,一次读一行 sb.append(s); //sb.append(processConnect(s));//这个方法是我对读取数据的操作,这里略过直接sb.append(s); if (count % 5000 == 0) {// 5000条数据写入一次 out.write(sb.toString()); sb.setLength(0);//清空 log.debug("====写入文本成功~"); } count++; } out.close(); br.close(); }catch(Exception e){ e.printStackTrace(); } return sb.toString(); }
执行之后一个221M的文本读完并写入到了另一个文本之中。控制台输入如下:
2016-04-12 22:13:56.443 DEBUG [main][ReadTxt2SQL.java:32] - path=F:/OntologyData/tb_data/data.txt2016-04-12 22:13:58.846 DEBUG [main][ReadTxt2SQL.java:107] - ====写入文本成功~2016-04-12 22:13:58.846 DEBUG [main][ReadTxt2SQL.java:109] - ====方法txt2String(File file)耗时:2397毫秒2016-04-12 22:13:58.847 DEBUG [main][ReadTxt2SQL.java:39] - ====整个文本的处理时间:[2455]毫秒
可能有人会对上面代码String path = Utils.getProperty("connectPath2");
有疑惑,这其实就是读取文本的路径,我为了方便写了一个通用类,读取配置文件的内容,可以直接改为绝对路径。
可能有人会疑问,为什么我要读取5000条然后存入文本,继续读取然后在存,这样的因为数据量太大,我们内存空间不足会导致内存溢出,所以需要这样做。改为如下:
while((s = br.readLine())!=null){//使用readLine方法,一次读一行 sb.append(s); //sb.append(processConnect(s)); /*if (count % 5000 == 0) {// 5000条数据写入一次 out.write(sb.toString());//写入文本 sb.setLength(0);//清空 //log.debug("====写入文本成功~"); }*/ count++; } out.write(sb.toString());//写入文本
控制台打印:
2016-04-12 22:18:58.343 DEBUG [main][ReadTxt2SQL.java:32] - path=F:/OntologyData/tb_data/data.txt2016-04-12 22:19:03.531 DEBUG [main][ReadTxt2SQL.java:109] - ====写入文本成功~2016-04-12 22:19:03.531 DEBUG [main][ReadTxt2SQL.java:111] - ====方法txt2String(File file)耗时:4687毫秒2016-04-12 22:19:03.661 DEBUG [main][ReadTxt2SQL.java:39] - ====整个文本的处理时间:[5411]毫秒
相对于第一种方法,这种效率低一些,现在我把读取内容每行都做处理//sb.append(test(s));
2016-04-12 22:24:53.187 DEBUG [main][ReadTxt2SQL.java:32] - path=F:/OntologyData/tb_data/data.txt2016-04-12 22:24:56.134 DEBUG [main][ReadTxt2SQL.java:107] - ====写入文本成功~2016-04-12 22:24:56.135 DEBUG [main][ReadTxt2SQL.java:109] - ====方法txt2String(File file)耗时:2927毫秒2016-04-12 22:24:56.150 DEBUG [main][ReadTxt2SQL.java:39] - ====整个文本的处理时间:[3014]毫秒
改为一次读完再存
2016-04-12 22:25:54.316 DEBUG [main][ReadTxt2SQL.java:32] - path=F:/OntologyData/tb_data/data.txt2016-04-12 22:25:57.671 DEBUG [main][ReadTxt2SQL.java:108] - ====写入文本成功~2016-04-12 22:25:57.672 DEBUG [main][ReadTxt2SQL.java:110] - ====方法txt2String(File file)耗时:3327毫秒2016-04-12 22:25:57.764 DEBUG [main][ReadTxt2SQL.java:39] - ====整个文本的处理时间:[3499]毫秒
这样看基本时间差距不大,今天先写到这里,等有时间我来测试2G数据,这两种方式的效率。
- JAVA IO 流操作
- java io流操作
- java IO流操作
- java IO 流操作
- java笔记-IO流-IO基本操作
- java IO操作之IO流介绍
- Java的IO流操作
- Java的IO流操作
- Java之IO流操作
- Java IO流文件操作
- Java IO流基本操作
- java IO流操作文章
- java中io流操作
- java IO 流操作规律
- 0821 Java io流操作
- java.io常见流/java.io.file文件操作大全
- java IO流之二 IO流操作
- Java IO学习札记(IO流操作小技巧)
- 第一个博客
- Java接口
- 【eclipse插件开发】右键菜单获取选中文件以及文件的创建
- ubuntu14.04 64位 jd-gui
- App更新策略课程-检查更新
- java IO 流操作
- 6.0权限认证
- 创建远程线程实现DLL注入
- netfilter入门
- 第一行代码 读笔⑤ (Broadcast)
- JS实现循环给元素绑定事件的几个常用方法
- Linux监视显卡使用情况
- Runtime(一)
- 命令ln的使用 以及 查看软件是否安装