android一个文件拷贝问题

gazishi0 2016-03-02 10:16:31
最近学做一个在外置TF卡和内置存储之间反复拷贝相同文件并计算拷贝速度的应用,发现一个问题:开机后第一次拷贝的速度总是比之后的拷贝速度要低,我认为是因为第一次拷贝时把数据读取到内存,拷贝完成后没有从内在里面清掉导致的。不知道是不是这个原因,请大神指点一下。下面是源码:
文件拷贝部分:
File a = new File(fromPath);
if (!a.exists()) {
toastStr = "拷贝文件不存在";
mHandler.sendEmptyMessage(showToatStr_10);
return;
}
String[] file = a.list();
File temp = null;
for (int i = 0; i < file.length; i++) {
if (stopStat) {
return;
}
if (fromPath.endsWith(File.separator)) {
fromFilePath = fromPath + file[i];
} else {
fromFilePath = fromPath + "/" + file[i];
}
temp = new File(fromFilePath);
toFilePath = toPath + "/" + file[i];
if (temp.isFile()) {
if (mode.equals("copy")) {
statTxtViewStr = "正在拷贝:" + fromFilePath;
mHandler.sendEmptyMessage(setStatTextView_3);

long FileIputStartTime = System.currentTimeMillis();
FileInputStream input = new FileInputStream(temp);
FileOutputStream output = new FileOutputStream(toPath
+ "/" + (temp.getName().toString()));
long FileIputEndTime = System.currentTimeMillis();
byte[] b = new byte[1024 * 80];
int len;
long whileStartTime = System.currentTimeMillis();
while ((len = input.read(b)) != -1) {
if (stopStat) {
output.flush();
output.close();
input.close();
return;
}
output.write(b, 0, len);
j += len;
prcJ = GetFileSize.FormetFileSize(j);
percent = (double) j * 100 / (double) temLong;
BigDecimal apct = new BigDecimal(percent);
newPct = apct.setScale(2, BigDecimal.ROUND_HALF_UP)
.doubleValue();
Message msg = mHandler.obtainMessage();
msg.arg1 = theNum;
msg.what = refreshSpeedListView_7;
msg.sendToTarget();

}
long whilEndTime = System.currentTimeMillis();
output.flush();
output.close();
input.close();
}

下面这个是计算速度的代码
public void getCopySpeed(int theNum) {
int num = 0;
newPct = 0;// 重置拷贝进度,排除上次拷贝所留下来的影响
while (!stopStat) {
if ((Double.toString(newPct)).equals("100.0")) {
return;
}
num += 1;
DecimalFormat df = new DecimalFormat("#.00");
copyspeed = (double) j * 10 / (double) (num);
if (copyspeed < 1) {
copySpeedStr = "0"
+ df.format((double) copyspeed / (1024 * 1024));
} else {
copySpeedStr = df.format((double) copyspeed / (1024 * 1024));//最后显示的拷贝速度,单位MB/S
}
Message msg = mHandler.obtainMessage();
msg.arg1 = theNum;
msg.what = refreshSpeedListView_7;
msg.sendToTarget();
SystemClock.sleep(100);
}

下面是调用拷贝拷贝和测速的代码:
public void itemCopy(final int itmID) {
String fromPath = alist.get(itmID).get("listViewFrom").toString();
String toPath = alist.get(itmID).get("listViewTo").toString();
step = "拷贝中……";

/**
* 新开一个线程,来计算拷贝速度
*/
new Thread(new Runnable() {

@Override
public void run() {
getCopySpeed(itmID);
}
}).start();
copyOrCompare("copy", fromPath, toPath, itmID);// 开始复制
}


公司不能上传图片,手打运行结果:
第一次从外置copy到内置,速度为5.74 MB/s
之后的8.7MB/s或更高

...全文
292 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
gazishi0 2016-03-03
  • 打赏
  • 举报
回复
引用 5 楼 xingzhong128 的回复:
android操作系统实际上是基于linux操作系统内核,linux在读取文件的时候会在开辟一个内核缓冲区将文件硬盘之类的外部存储设备文件数据拷贝的内核缓冲区中,然后再将内核缓冲区中的数据拷贝到用户的进程空间中;以后每一次再读取数据,都会先查看内核缓冲区中是否已经读取了数据,如果读取了就直接从内核缓冲区中拷贝数据;如果没有找到才会重新从外设中读取数据。由于外部存储设备读取时间通常远高于内存读取时间,所以第一次读取事件会比较慢,以后因为都是内存之间的拷贝访问,速度就比第一次快的多
那有没有什么方法查看到是否真的把文件缓存在了缓冲区中?怎样清空缓存的文件?
gazishi0 2016-03-03
  • 打赏
  • 举报
回复
引用 6 楼 tcmakebest 的回复:
这个问题怪怪的,应该是为什么第二次复制比第一次快,答案应该是文件在内存中缓存了。
那怎样清空内存中的缓存呢?
xingzhong128 2016-03-03
  • 打赏
  • 举报
回复
引用 8 楼 gazishi0 的回复:
[quote=引用 6 楼 tcmakebest 的回复:] 这个问题怪怪的,应该是为什么第二次复制比第一次快,答案应该是文件在内存中缓存了。
那怎样清空内存中的缓存呢?[/quote] 把打开的文件close掉应该就可以了,不过这个是操作系统内部处理
gazishi0 2016-03-02
  • 打赏
  • 举报
回复
引用 2 楼 gazishi0 的回复:
引用 1 楼 heaimnmn 的回复:
遍历索引的问题
版主大大,可以具体一点么?我新手一个
优化的问题可以以后再说,我现在的主要问题是:在重复复制的过程中,为什么第一次复制的速度会比之后的复制速度要慢?每次复制所用的方法应该都是一样的啊
哎,真难 2016-03-02
  • 打赏
  • 举报
回复
引用 2 楼 gazishi0 的回复:
引用 1 楼 heaimnmn 的回复:
遍历索引的问题
版主大大,可以具体一点么?我新手一个
算法你用递归遍历算法,自然会慢,百度下其他算法
gazishi0 2016-03-02
  • 打赏
  • 举报
回复
引用 1 楼 heaimnmn 的回复:
遍历索引的问题
版主大大,可以具体一点么?我新手一个
哎,真难 2016-03-02
  • 打赏
  • 举报
回复
遍历索引的问题
tcmakebest 2016-03-02
  • 打赏
  • 举报
回复
这个问题怪怪的,应该是为什么第二次复制比第一次快,答案应该是文件在内存中缓存了。
xingzhong128 2016-03-02
  • 打赏
  • 举报
回复
android操作系统实际上是基于linux操作系统内核,linux在读取文件的时候会在开辟一个内核缓冲区将文件硬盘之类的外部存储设备文件数据拷贝的内核缓冲区中,然后再将内核缓冲区中的数据拷贝到用户的进程空间中;以后每一次再读取数据,都会先查看内核缓冲区中是否已经读取了数据,如果读取了就直接从内核缓冲区中拷贝数据;如果没有找到才会重新从外设中读取数据。由于外部存储设备读取时间通常远高于内存读取时间,所以第一次读取事件会比较慢,以后因为都是内存之间的拷贝访问,速度就比第一次快的多

80,490

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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