java的文件操作 我现在有一个txt文件,里面有几万的数据,怎样能够一次读出许多数据,比如1000条,而不是用readline一条一条读呢,用序列化来做么?怎么做? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 序列化是用来读取对象的,和对几万条数据没什么关系吧~~用readLine()对取数据也很快啊?楼主是想程序读取固定条数的数据吗?每条数据之间应该有固定的"分隔符"的话,可以循环split下,具体情况具体判断吧 如果你文件中的数据是用空白字符(回车,空格,tab)隔开的,可以用以下办法:Scanner scanner=new Scanner(new File("文件名"));while(scanner.hasNext()){ mydata[i++]=scanner.nextInt();}如果文件中的数据是float,用nextFloat()读数,以此类推。如果文件中数据之间是用逗号隔开,第一句改为,Scanner scanner=new Scanner(new File("文件名")).useDelimiter(","); 这个方法的效率有多高?跟readline一条条的读取有什么差别? 我的想法是把这个文件每1000行取出放到一个文本中,就是把原来的文件分隔成许许多多不同的子文本,关于具体实现,可以参考下我的blog,程序二:/** * 用缓冲流实现文件分隔 */package com.basic.io;import java.io.*;public class TestBufferStream { public final int SIZE = 1000; //设置分隔的行数 public static void main(String[] args) { try { BufferedReader br = new BufferedReader(new FileReader("c:/Java编码规范.txt")); BufferedWriter bw = null; String s = null; //单行内容 int countLine = 0; //总行数 int countFile = 1; //子文件数 while((s=br.readLine())!=null){ if (countLine % SIZE == 0) { if (bw != null) { bw.flush(); bw.close(); } bw = new BufferedWriter(new FileWriter("c:/Java编码规范" + countFile + ".txt")); countFile++; } bw.write(s); bw.newLine(); System.out.println(s); countLine++; } System.out.println("countLine:" + countLine); bw.close(); if(countLine != 0){ bw.flush(); bw.close(); } } catch (IOException e) { e.printStackTrace();} }} 这个用缓冲流读取的时候,也是要一条一条读取的吧,我能不能快速定位到txt中的哪一行呢?比如有10000行格式一样的数据,我要读取第8961行的数据,我能不能快速的定位的这个数据呢?数据格式都是完全一样的话。 用java的nio包,高效IO,底层直接用C实现的: try { File f = new File("filename"); //打开文件 ByteBuffer buffer = ByteBuffer.allocate((int) f.length()); //建立缓存,这里用的是文件大小,文件不能过大,不能超过2^32-1个字节。也可以用小点。 FileInputStream in = new FileInputStream(f); //一次读整个文件 in.getChannel().read(buffer);读出文件。 } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } 接以上面的,如每行的数据都一样,就可计数出开始的位置和要读的长度,然后用下面的方法:in.getChannel().read(ByteBuffer[] dsts, int offset, int length), offset是开始的位置,length是长度,dsts还是那个buffer缓存。 再接: try { File f = new File("filename"); int length = 10; //计算出要读出的数据长度,如10个字节。 int pos = 100; //计算出要读出的起始位置. ByteBuffer buffer = ByteBuffer.allocate(length); //建立一个buffer FileInputStream in = new FileInputStream(f); in.getChannel().read(buffer,pos); //从pos的位置开始读,把整个buffer读满返回 } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.nio.ByteBuffer;/** * @author Lei Gao. 16/06/2009 * */public class BlockReadFile { public static void main(String[] args) { try { File f = new File("out.txt"); //例子文件中每个记录10个字节,另1个换行符,共11个字节。文件有7行记录 int pos = 11; //从第二个记录开始读 int length = 11*5; //计算出要读出的数据长度,读5个记录。 ByteBuffer buffer = ByteBuffer.allocate(length); //建立一个buffer FileInputStream in = new FileInputStream(f); //看一下java.nio.channels.FileChannel类的API,有很多有用的方法 in.getChannel().read(buffer,pos); //从pos的位置开始读,把整个buffer读满返回 //这之后再怎么处理都行了,看一下java.nio.ByteBuffer类的API //以下我做的处理,只是打印一下 String[] records = new String(buffer.array()).split("\n"); //转换成字符串,因为读的时候把换行也读出来了,用换行把记录分开。 for(String s : records) //打印一下结果 System.out.println(s); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }} out.txt文件的内容:aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffffgggggggggg运行上面程序打印出的结果:bbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffff 那就是数据处理的问题了,可以用一个固定大小的buffer,再读出文件中的一部分数据。再根据你数据的特点具件处理就行了,举例:如果数据每行用换行符分开,用我上面的例子中的buffer.array()).split("\n"就可以了,分开后的每个字符串是一条数据,在处理最后一条数据时要检查是否完整。用NIO包来读文件特点就是非常高效,还有可以任意读取文件中的一部分内容(random file access). 读出之后该怎么处理就怎么处理呗。。 可以,给出开始的位置和要读取的长度。 我上面的22楼的程序就是例子,从文件中间读取一段。你好好读读代码和API文档。 关于process的问题,求请教 oracle中生僻字显示正常,到用程序写到xml中却是问号,求解答 耽误你一分钟的时间看一下 关于Java泛型的一个问题 JAVA怎样检测硬盘所有分区的剩余空间大小? 笔试中的几道题,不会。。。(初级) 小弟请教了:生产者和消费者问题? 关于 JAVA与图象的问题! 怎么能向数据库中插入当前时间到日期类型的字段 急!请帮忙解决:1.如何解决通过jdbc访问Sybase,插入中文信息Sybase乱码?2.如何在tomcat中设置session的timeout?感谢! 无赖啊 关于Comparator,Map
用readLine()对取数据也很快啊?楼主是想程序读取固定条数的数据吗?
每条数据之间应该有固定的"分隔符"的话,可以循环split下,具体情况具体判断吧
Scanner scanner=new Scanner(new File("文件名"));
while(scanner.hasNext()){
mydata[i++]=scanner.nextInt();
}如果文件中的数据是float,用nextFloat()读数,以此类推。
如果文件中数据之间是用逗号隔开,第一句改为,Scanner scanner=new Scanner(new File("文件名")).useDelimiter(",");
就是把原来的文件分隔成许许多多不同的子文本,
关于具体实现,
可以参考下我的blog,
程序二:
/**
* 用缓冲流实现文件分隔
*/
package com.basic.io;import java.io.*;
public class TestBufferStream {
public final int SIZE = 1000; //设置分隔的行数
public static void main(String[] args) {
try {
BufferedReader br = new BufferedReader(new FileReader("c:/Java编码规范.txt"));
BufferedWriter bw = null;
String s = null; //单行内容
int countLine = 0; //总行数
int countFile = 1; //子文件数
while((s=br.readLine())!=null){
if (countLine % SIZE == 0) {
if (bw != null) {
bw.flush();
bw.close();
}
bw = new BufferedWriter(new FileWriter("c:/Java编码规范" + countFile + ".txt"));
countFile++;
}
bw.write(s);
bw.newLine();
System.out.println(s);
countLine++;
}
System.out.println("countLine:" + countLine);
bw.close();
if(countLine != 0){
bw.flush();
bw.close();
} } catch (IOException e) { e.printStackTrace();}
}
}
File f = new File("filename"); //打开文件
ByteBuffer buffer = ByteBuffer.allocate((int) f.length()); //建立缓存,这里用的是文件大小,文件不能过大,不能超过2^32-1个字节。也可以用小点。
FileInputStream in = new FileInputStream(f); //一次读整个文件
in.getChannel().read(buffer);读出文件。
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
in.getChannel().read(ByteBuffer[] dsts, int offset, int length), offset是开始的位置,length是长度,dsts还是那个buffer缓存。
File f = new File("filename");
int length = 10; //计算出要读出的数据长度,如10个字节。
int pos = 100; //计算出要读出的起始位置.
ByteBuffer buffer = ByteBuffer.allocate(length); //建立一个buffer
FileInputStream in = new FileInputStream(f);
in.getChannel().read(buffer,pos); //从pos的位置开始读,把整个buffer读满返回
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
* @author Lei Gao. 16/06/2009
*
*/
public class BlockReadFile { public static void main(String[] args) {
try {
File f = new File("out.txt"); //例子文件中每个记录10个字节,另1个换行符,共11个字节。文件有7行记录
int pos = 11; //从第二个记录开始读
int length = 11*5; //计算出要读出的数据长度,读5个记录。 ByteBuffer buffer = ByteBuffer.allocate(length); //建立一个buffer
FileInputStream in = new FileInputStream(f);
//看一下java.nio.channels.FileChannel类的API,有很多有用的方法
in.getChannel().read(buffer,pos); //从pos的位置开始读,把整个buffer读满返回
//这之后再怎么处理都行了,看一下java.nio.ByteBuffer类的API
//以下我做的处理,只是打印一下
String[] records = new String(buffer.array()).split("\n"); //转换成字符串,因为读的时候把换行也读出来了,用换行把记录分开。
for(String s : records) //打印一下结果
System.out.println(s);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
bbbbbbbbbb
cccccccccc
dddddddddd
eeeeeeeeee
ffffffffff
gggggggggg
运行上面程序打印出的结果:bbbbbbbbbb
cccccccccc
dddddddddd
eeeeeeeeee
ffffffffff
那就是数据处理的问题了,可以用一个固定大小的buffer,再读出文件中的一部分数据。再根据你数据的特点具件处理就行了,
举例:如果数据每行用换行符分开,用我上面的例子中的buffer.array()).split("\n"就可以了,分开后的每个字符串是一条数据,在处理最后一条数据时要检查是否完整。用NIO包来读文件特点就是非常高效,还有可以任意读取文件中的一部分内容(random file access). 读出之后该怎么处理就怎么处理呗。。
可以,给出开始的位置和要读取的长度。 我上面的22楼的程序就是例子,从文件中间读取一段。你好好读读代码和API文档。