主要我知道的三种方法
- 直接使用缓冲流写入文件,这个不做过多说明
public class Testmain {
public static void main(String[] args) {
Random random = new Random();
try {
BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\work\\ten\\jm.txt"));
long start = System.currentTimeMillis();
for (int i = 0; i < 1024 * 1024 * 128; i++) {
bw.write((-999) + random.nextInt(10999) + "\n");
}
bw.close();
System.out.print(System.currentTimeMillis() - start + "ms");
} catch (Exception e) {
e.printStackTrace();
}
}
}
2 使用多线程一个读一个写,因为产生随机数也是非常耗时的
/*
* 将数据放在缓冲区中
* */
public class Read implements Runnable {
StringBuffer buffer;
@Override
public void run() {
int a = 1024 * 1024 * 128;
Random random = new Random();
buffer = new StringBuffer(a);
for (int i = 0; i <1024*1024*32 ; i++) {
buffer.append((-999) + random.nextInt(10999) + "\n");
}
}
public String jm() {
run();
return buffer.toString();
}
}
/*
* 将数据写入文件
* */
public class Write implements Runnable {
@Override
public void run() {
Read read = new Read();
String jm = read.jm();
long start = System.currentTimeMillis();
synchronized (this) {
try {
BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\work\\ten\\jm.txt"));
for (int i = 0; i < 4; i++) {
bw.write(jm);
}
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
long end = System.currentTimeMillis();
System.out.println(end - start + "ms");
}
}
主线程
/*
* 主线程类
* */
public class Theradmain {
public static void main(String[] args) {
Read read = new Read();
Write write = new Write();
Thread t1 = new Thread(read);
Thread t2 = new Thread(write);
t1.start();
t2.start();
}
}
可以根据自己电脑的内存那些来看开几个线程效率最高,这个可以自己跑跑看,需要自己做测试,最好在固态硬盘上测试,因为数据量比较大,固态硬盘一般是C盘
3 用到了RandomAccessFile这个类,此类非IO流类,详细的用法可以自己看看API
这个方法主要的思想:
我们想要把数据同步一起写入到文件中,这个方法给我们提供了写入文件时的位置与大小(通俗来说,就是我们写一亿行数据,我们把它分成几部分,然后同步写入文件中,每一个写入的位置不一样,不用像多线程一样顺序的写入)
具体的代码
*
* 将数据同时写入同一个文件的不同位置
*
* */
public class Three implements Runnable {
private int offset; //起始量
private int len; //写入文件的数量
@Override
public void run() {
long start = System.currentTimeMillis();
try {
Random random = new Random();
RandomAccessFile rw = new RandomAccessFile("D:\\work\\ten\\jm.txt", "rw");
FileChannel channel = rw.getChannel(); //获取通道
rw.seek(offset); //写入文件的起始位置
rw.setLength(len); //设置文件的长度
//FileLock fileLock = channel.tryLock(offset,len,true); //文件锁,在windows上不能同时读写一个文件
for (int i = 0; i < 1024 * 1024 * 128; i++) {
rw.writeBytes((-999) + random.nextInt(10999) + "\n");
}
//fileLock.release(); //释放文件锁
rw.close();
channel.close();
} catch (Exception e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println(end - start + "ms");
}
public Three(int offset, int len) {
this.offset = offset;
this.len = len;
}
}
主线程
public class ThreeMain {
public static void main(String[] args) {
int length = 1024 * 1024 * 128;
Three[] test = new Three[4];//创建Thrr类型的数组,将数据存入数组中
//起始位置和每一部分很好计算
//起始位置你看你分成几部分,然后把length当成单位一就行了,每一部分的量就用总量/分成几部分
test[0] = new Three(length * 0, length / 4);
test[1] = new Three(length / 4, length / 4);
test[2] = new Three(length / 2, length / 4);
test[3] = new Three(length / 12, length / 4);
Thread t1 = new Thread(test[0]);
Thread t2 = new Thread(test[1]);
Thread t3 = new Thread(test[2]);
Thread t4 = new Thread(test[3]);
t1.start();
t2.start();
t3.start();
t4.start();
这个方法看起来很不错,但是我测了一下,写入的速度有点慢,当然自己还可以在优化
注意: 这个方法在windows操作系统上是不行的,因为用到了文件锁FileLock fileLock,你不加锁,写入文件会出现错误