大量数据的读写,优化读写速度

假的旁边就是真的 2013-04-10 03:03:57
随机生成10亿个整数,写入文件。下面是代码:

FileWriter f=new FileWriter("D:/data.txt");
BufferedWriter buf=new BufferedWriter(f,1024*512);
int o=0;
while(o<10000){
int []array=new int[100000];
for(int i=0;i<array.length;i++)
array[i]=(int) (Math.random()*1000000);
int j=0;
while(j<array.length){
buf.write(String.valueOf(array[j]));
System.out.println(array[j]);
j++;
}
o++;
}
buf.close();

发现速度真的是太慢了,该怎么优化一下使写入文件的速度加快,各位大牛指点
...全文
903 49 打赏 收藏 转发到动态 举报
写回复
用AI写文章
49 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 20 楼 shine333 的回复:
1 你这个array数组是否有必要? 2 是否一定要txt,也就是打开来看,如果只有一个数字1234,就要能肉眼看到是1234? 换句话说,可以用字节流替代字符流。同样一个数字123456789,字符流9个字符,至少要9个字节(看编码格式,可能18个字节)。而字节流的话,只要是int范围内,无论多大,最多只要4个字节。 如果只是想要存储,数字肉眼看不看得……
坦克哥 数据过于庞大无法一次性把数据读入内存啊~
tommwq 2013-04-12
  • 打赏
  • 举报
回复
dd if=/dev/urandom of=./random_int bs=4 count=1000000000
摆烂办不到 2013-04-11
  • 打赏
  • 举报
回复
表示有点困惑
cxmshh 2013-04-11
  • 打赏
  • 举报
回复
前来学习一下。。。新人,好多不懂的地方
小绵羊 2013-04-11
  • 打赏
  • 举报
回复
用@shine333 的代码就好了
冰思雨 2013-04-11
  • 打赏
  • 举报
回复
引用 2 楼 heyufengcc1 的回复:
你看这代码是不是写入文件的次数太多了导致用的时间太多了 估计要用几个小时才能写完10亿个整数 1个整数4bit,10亿个就是4G,我这个文件就得是4G
楼主,你那程序何止4G啊。 你随机生成了整数,但是写入文件的时候,你把整数转换成字符串了。 一位整数就占一个字符,也就是一个字节。 如果随机数,生成个十位八位,那你一个整数,岂不是占十个八个字节。并且,整数和整数之间也没弄个分隔符,读取都不好读取。
  • 打赏
  • 举报
回复
引用 16 楼 AFer198215 的回复:
Java code?1234567891011121314151617181920static void t8(){ byte[] buff = new byte[512];//4*128//128个int Random rand = new Random(System.currentTimeMillis()); rand.nextBytes(buff)……
cpu运算慢意思是指我的电脑问题吗,这样生成的是字节数据,如果以字节的形式存储,我的初衷是想把写到文件的整数进行排序,那是不是可以重新把这些字节组成一个个整数再进行排序
小绵羊 2013-04-11
  • 打赏
  • 举报
回复
引用 25 楼 shine333 的回复:
Java code?123 byte[] bytes = int2bytes(-1234); int x = bytes2int(bytes); System.out.println(x); >>>
这茬给忘了
小绵羊 2013-04-11
  • 打赏
  • 举报
回复
引用 24 楼 shine333 的回复:
引用 22 楼 x19881216 的回复:Java code?1234567891011121314151617181920212223242526272829303132333435public static void main(String[] args) throws Exception { long startTime = System.curr……
啥子bug,木有看出来。。。
shine333 2013-04-11
  • 打赏
  • 举报
回复
    byte[] bytes = int2bytes(-1234);
    int x = bytes2int(bytes);
    System.out.println(x);
>>>
shine333 2013-04-11
  • 打赏
  • 举报
回复
引用 22 楼 x19881216 的回复:
Java code?1234567891011121314151617181920212223242526272829303132333435public static void main(String[] args) throws Exception { long startTime = System.currentTimeMillis(); ……
虽然你的代码更进一步了,但是还是有bug
shine333 2013-04-11
  • 打赏
  • 举报
回复
如果确保数字很小,即使内存这边用int,读写这里可以改成read/writeShort,更节省空间 目前int读写,n=1000000000,稳定在4,000,000,000 字节(约3.72G)相对于你字符格式的版本,估计可以省去一半,运行才100多秒。 如果是lz的n=100000,不到50毫秒,大小才390K
引用 5 楼 x19881216 的回复:
Java code?123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051public static void main(String[] args) throws Exception { long startTime = S……
小绵羊,没必要发明轮子,直接用DataI/OStream即可。
小绵羊 2013-04-11
  • 打赏
  • 举报
回复
public static void main(String[] args) throws Exception {

		long startTime = System.currentTimeMillis();

		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("c:/test.dat"));

		Random rad = new Random();

		long i = 0;
		while (i < 1000000000) {
			bos.write(int2bytes(rad.nextInt()));
			i++;
		}

		bos.flush();
		bos.close();

		System.out.println(System.currentTimeMillis() - startTime);

	}

	static int bytes2int(byte[] b) {
		return b[0] << 24 + b[1] << 16 + b[2] << 8 + b[3];
	}

	static byte[] int2bytes(int i) {
		byte[] rs = new byte[4];

		rs[0] = (byte) (i >> 24);
		rs[1] = (byte) (i >> 16);
		rs[2] = (byte) (i >> 8);
		rs[3] = (byte) (i);

		return rs;
	}
耗时69217ms,文件大小3.72 GB (4,000,000,000 字节),占用空间3.72 GB (4,000,002,048 字节),不写硬盘耗时11419ms。
小绵羊 2013-04-11
  • 打赏
  • 举报
回复
引用 20 楼 shine333 的回复:
1 你这个array数组是否有必要? 2 是否一定要txt,也就是打开来看,如果只有一个数字1234,就要能肉眼看到是1234? 换句话说,可以用字节流替代字符流。同样一个数字123456789,字符流9个字符,至少要9个字节(看编码格式,可能18个字节)。而字节流的话,只要是int范围内,无论多大,最多只要4个字节。 如果只是想要存储,数字肉眼看不看得……
坦克哥+1
shine333 2013-04-11
  • 打赏
  • 举报
回复
1 你这个array数组是否有必要? 2 是否一定要txt,也就是打开来看,如果只有一个数字1234,就要能肉眼看到是1234? 换句话说,可以用字节流替代字符流。同样一个数字123456789,字符流9个字符,至少要9个字节(看编码格式,可能18个字节)。而字节流的话,只要是int范围内,无论多大,最多只要4个字节。 如果只是想要存储,数字肉眼看不看得懂无所谓(其实那么大量的数字,看不看得懂没区别),可以:

    final int n = 100;
    final int max = 1000000000;

    File file = new File("D:/data.dat");
    DataOutputStream dos = null;
    try {
      dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(
          file)));
      for (int i = 0; i < n; i++) {
        int x = (int) (Math.random() * max);
        System.out.println(x);
        dos.writeInt(x);
      }
    } finally {
      if (dos != null) {
        try {
          dos.close();
          dos = null;
        } catch (Exception ex) {
        }
      }
    }
    System.out.println("==========以下为读取===========");
    DataInputStream dis = null;
    try {
      dis = new DataInputStream(new BufferedInputStream(new FileInputStream(
          file)));
      for (int i = 0; i < n; i++) {
        int x = dis.readInt();
        System.out.println(x);
      }
    } finally {
      if (dis != null) {
        try {
          dis.close();
          dis = null;
        } catch (Exception ex) {
        }
      }
    }
小绵羊 2013-04-11
  • 打赏
  • 举报
回复
引用 18 楼 heyufengcc1 的回复:
引用 14 楼 x19881216 的回复:引用 10 楼 AFer198215 的回复:引用 5 楼 x19881216 的回复:耗时103548ms,生成的文件有9.29G,硬盘写入速度倒成瓶颈了 亲啊,java 的int占4个字节,直接">>"转成4个字节不行吗? System.arraycopy()这个底层的内存拷贝也很耗时的。 Java code?……
用字节存储就快多了,写个相应的还原方法就好了
  • 打赏
  • 举报
回复
引用 14 楼 x19881216 的回复:
引用 10 楼 AFer198215 的回复:引用 5 楼 x19881216 的回复:耗时103548ms,生成的文件有9.29G,硬盘写入速度倒成瓶颈了 亲啊,java 的int占4个字节,直接">>"转成4个字节不行吗? System.arraycopy()这个底层的内存拷贝也很耗时的。 Java code?123456789101112131415 ……
用字符串存储好像就不会乱码了,我是想写入文件,然后再取出来对他们排序,用字节存储也是可以的。只是取出来的时候要排序,还是要转换成int形式。
想喝咖啡的貓 2013-04-11
  • 打赏
  • 举报
回复
lz的慢 应该是慢在cpu运算及内存copy上。
想喝咖啡的貓 2013-04-11
  • 打赏
  • 举报
回复

	static void t8(){
		byte[] buff = new byte[512];//4*128//128个int
		Random rand = new Random(System.currentTimeMillis());
		rand.nextBytes(buff);
		OutputStream out = null;
		
		try{
			out = new FileOutputStream("c:\\test1.data");
			
			long l = System.currentTimeMillis();
			for(int i=0,end=10000*10000*10; i<end; i+=128){
				out.write(buff, 0, 512);
				out.flush();
			}			
			System.out.println(System.currentTimeMillis()-l);
			out.close();
		}catch(Exception ex){
			ex.printStackTrace();
		}
	}
这个测试结果: 写入:3.72 GB (4,000,002,048 字节) 耗时:125734 我估计 我机器上java 写硬盘速度就这样了。
shayandelei 2013-04-11
  • 打赏
  • 举报
回复
引用 10 楼 AFer198215 的回复:
引用 5 楼 x19881216 的回复:耗时103548ms,生成的文件有9.29G,硬盘写入速度倒成瓶颈了 亲啊,java 的int占4个字节,直接">>"转成4个字节不行吗? System.arraycopy()这个底层的内存拷贝也很耗时的。 Java code?123456789101112131415 /** * int转byte数……
移位确实是最快的
加载更多回复(29)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧