Java Android上的IO速度慢吗?

Java Android上的IO速度慢吗?,java,android,io,fat,Java,Android,Io,Fat,这应该显示内部和外部内存速度,但不幸的是,它说是0.02或0.04 MB/s?这是安卓系统的巨大低效,还是编码错误 findViewById(R.id.buttonStorageSpeed).setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { double SDSpeed = MBPSTest(ge

这应该显示内部和外部内存速度,但不幸的是,它说是0.02或0.04 MB/s?这是安卓系统的巨大低效,还是编码错误

findViewById(R.id.buttonStorageSpeed).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                double SDSpeed = MBPSTest(getExternalCacheDir()); // /sdcard
                double MemSpeed = MBPSTest(getCacheDir());        // /data/data
                final AlertDialog dialog = new AlertDialog.Builder(thisContext)
                .setTitle("Memory speed")
                .setMessage( "Internal:"+String.valueOf(MemSpeed) + "\n"  + "SD:"+String.valueOf(SDSpeed))
                .create();
                dialog.show();
            }
        });




/**
     * Test MB/s write speed in some directory.
     * Writes 4MB, deletes it after.
     * @param outdir
     * @return
     */
    private double MBPSTest(File outDir) {

        long start = System.currentTimeMillis();
        try {
            for (int fnum = 0; fnum < 1024; fnum++) {
                File out = new File(outDir,"TESTspeed"+String.valueOf(fnum));
                FileOutputStream fos = new FileOutputStream(out);

                //Write 4k files
                for (int i=0; i < 1024; i++) {
                    fos.write(65);//A
                    fos.write(69);//E
                    fos.write(73);//I
                    fos.write(79);//O
                }
                fos.flush();
                fos.close();
                //System.out.println("Wrote file.");
            }
            //Wrote 4MB

            //Toast.makeText(getApplicationContext(), "Wrote External at: "+String.valueOf(4.0 / (elapsed/1000.0) )+" MB/S", Toast.LENGTH_LONG).show();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return 0;
        } catch (IOException e) {
            e.printStackTrace();
            return 0;
        }

        long elapsed = System.currentTimeMillis() - start;

        //Clean up:
        for (int fnum = 0; fnum < 1024; fnum++) {
            File out = new File(outDir, "TESTspeed"+String.valueOf(fnum));
            out.delete();
        }
        // 4 MB / (seconds)
        return 4.0 / (elapsed/1000.0);
    }
findViewById(R.id.buttonStorageSpeed).setOnClickListener(新的OnClickListener(){
@凌驾
公共void onClick(视图arg0){
双SDSpeed=MBPSTest(getExternalCacheDir());///sdcard
double MemSpeed=MBPSTest(getCacheDir());///data/data
最终AlertDialog=新建AlertDialog.Builder(thisContext)
.setTitle(“内存速度”)
.setMessage(“内部:“+String.valueOf(MemSpeed)+”\n“+”SD:“+String.valueOf(SDSpeed))
.create();
dialog.show();
}
});
/**
*在某个目录中测试MB/s的写入速度。
*写入4MB,然后将其删除。
*@param outdir
*@返回
*/
专用双MbpTest(文件输出目录){
长启动=System.currentTimeMillis();
试一试{
对于(int-fnum=0;fnum<1024;fnum++){
File out=新文件(outDir,“TESTspeed”+String.valueOf(fnum));
FileOutputStream fos=新的FileOutputStream(输出);
//写4k文件
对于(int i=0;i<1024;i++){
fos.write(65);//A
fos.write(69);/E
fos.write(73);//我
fos.write(79);//O
}
fos.flush();
fos.close();
//System.out.println(“写入文件”);
}
//写了4MB
//Toast.makeText(getApplicationContext(),“外部写入:”+String.valueOf(4.0/(已用/1000.0))+“MB/S”,Toast.LENGTH_LONG.show();
}catch(filenotfounde异常){
e、 printStackTrace();
返回0;
}捕获(IOE异常){
e、 printStackTrace();
返回0;
}
长时间运行=System.currentTimeMillis()-开始;
//清理:
对于(int-fnum=0;fnum<1024;fnum++){
File out=新文件(outDir,“TESTspeed”+String.valueOf(fnum));
out.delete();
}
//4MB/(秒)
返回4.0/(经过/1000.0);
}

您在这里引入了大量开销:

        for (int fnum = 0; fnum < 1024; fnum++) {
            File out = new File(outDir,"TESTspeed"+String.valueOf(fnum));
            FileOutputStream fos = new FileOutputStream(out);

            //Write 4k files
            for (int i=0; i < 1024; i++) {
                fos.write(65);//A
                fos.write(69);//E
                fos.write(73);//I
                fos.write(79);//O
            }
            fos.flush();
            fos.close();
            //System.out.println("Wrote file.");
        }
        //Wrote 4MB
for(int-fnum=0;fnum<1024;fnum++){
File out=新文件(outDir,“TESTspeed”+String.valueOf(fnum));
FileOutputStream fos=新的FileOutputStream(输出);
//写4k文件
对于(int i=0;i<1024;i++){
fos.write(65);//A
fos.write(69);/E
fos.write(73);//我
fos.write(79);//O
}
fos.flush();
fos.close();
//System.out.println(“写入文件”);
}
//写了4MB
您每4k(每个文件1024次)关闭和打开一次文件。相反,您应该在循环外只打开它一次

这还远远不是一项科学测试。您正在进行一系列API调用,这些调用不会显示设备的实际速度。此外,您可能会有大量的文件系统调整开销

更好的方法可能是:

  • 打开文件
  • 写入所需大小的数据
  • 查找到文件的开头
  • 冲洗
  • 启动计时器
  • 在尽可能大的数据块中写入所需大小的数据
  • 停止计时器
  • 清理

除了Jonathon提到的打开和关闭文件的开销之外,您还为每个字节调用
write(int)


使用带有大缓冲区的
write(byte[])
,或使用
BufferedOutputStream
包装
文件输出流。
FileOutputStream
中可能已经存在一些缓冲区,但同样可能没有。您可能会发现,一旦您的写入操作更少(但数据量仍然相同),它就会更快。

它正在写入多个相当小的文件-这与正常使用情况是否太不同?我想这是一个问题:您要测试什么?许多小东西几乎总是比一个大东西慢。这大大提高了写入速度-0.13 MB/s。我忘了,我已经有一段时间没有用Java做过了。想想看,我记得出于某种原因,在桌面上复制许多小文件的速度也非常慢,所以这个基准测试对这种情况来说是否准确?