- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章C#文件流读写和进度回调示例详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
前言 。
前不久遇到一个问题,是公司早期的基础库遇到的,其实很低级,但是还是记录下来。出错点是一个 io 流的写入bug,我们项目会有一种专有的数据格式,这个格式的奇葩点在于如果设置 io 读缓冲区为 2014 字节的时候,整个文件刚好能读完,也就是说其 length 刚好是 1024 的倍数。后来在一次升级中增加了更多的文件格式,并且新的文件格式使用了新的自定义写入流,具有加密和压缩的作用,这样一来,文件的长度就不一定是 1024 的倍数了.
后来通过查看这个基础类的源代码发现因为是 .net 2.0 时代的东西,也没有 stream.copy 的方法,于是当时的程序员手动写了个 stream.copy 的方法,我稍作改动为了更直观将输出流改为输出到文件,代码大概如下:
1
2
3
4
5
6
7
8
|
var fs_in = system.io.file.openread(
@"c:\3.0.6.apk"
);
var fs_out = system.io.file.openwrite(
@"c:\3.0.6.apk.copy"
);
byte
[] buffer =
new
byte
[1024];
while
(fs_in.read(buffer,0,buffer.length)>0)
{
fs_out.write(buffer, 0, buffer.length);
}
console.writeline(
"复制完成"
);
|
所以一眼就能看出这个方法简直有天大的 bug ,假设文件长度不为 1024 的倍数,永远会在文件尾部多补充上一段的冗余数据.
这里整整多出了 878 字节的数据,导致整个文件都不对了,明显是基础知识都没学好.
增加一个变量保存实际读取到的字节数,改为如下:
1
2
3
4
5
6
7
8
9
|
var fs_in = system.io.file.openread(
@"c:\迅雷下载\3.0.6.apk"
);
var fs_out = system.io.file.openwrite(
@"c:\迅雷下载\3.0.6.apk.copy"
);
byte
[] buffer =
new
byte
[1024];
int
readbytes = 0;
while
((readbytes= fs_in.read(buffer, 0, buffer.length)) >0)
{
fs_out.write(buffer, 0, readbytes);
}
console.writeline(
"复制完成"
);
|
对于处理大型文件,一般都有进度指示,比如处理压缩了百分多少之类的,这里我们也可以加上,比如专门写一个方法用于文件读取并返回 byte[] 和百分比.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
static
void
readfile(
string
filename,
int
bufferlength, action<
byte
[],
int
> callback)
{
if
(!system.io.file.exists(filename))
return
;
if
(callback ==
null
)
return
;
system.io.fileinfo finfo =
new
system.io.fileinfo(filename);
long
filelength = finfo.length;
long
totalreadbytes = 0;
var fs_in = system.io.file.openread(filename);
byte
[] buffer =
new
byte
[bufferlength];
int
readbytes = 0;
while
((readbytes = fs_in.read(buffer, 0, buffer.length)) > 0)
{
byte
[] data =
new
byte
[readbytes];
array.copy(buffer, data, readbytes);
totalreadbytes += readbytes;
int
percent = (
int
)((totalreadbytes / (
double
)filelength) * 100);
callback(data, percent);
}
}
|
调用就很简单了:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
static
void
main(
string
[] args)
{
string
filename =
@"c:\3.0.6.apk"
;
var fs_in = system.io.file.openread(filename);
long
ttc = 0;
readfile(filename, 1024, (
byte
[] data,
int
percent) =>
{
ttc += data.length;
console.setcursorposition(0, 0);
console.write(percent+
"%"
);
});
console.writeline(
"len:"
+ttc);
console.readkey();
}
|
这是基于文件读取的,稍微改一下就可以改成输入流输出流的,这里就不贴出来了。文件读写非常耗时,特别是大文件,io 和 网络请求都是 “重操作”,所以建议大家 io 都放在单独的线程去执行。c# 中可以使用 task、thread、如果同时有多个线程需要执行就用 threadpool 或 task,java 或 android 中用 thread 或线程池,以及非常流行的 rxjava 等等 ... 。
总结 。
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我的支持.
原文链接:https://www.jianshu.com/p/33ed9e665620 。
最后此篇关于C#文件流读写和进度回调示例详解的文章就讲到这里了,如果你想了解更多关于C#文件流读写和进度回调示例详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在开发一个在 gridview 中显示数据表内容的网页。而且,还有一个名为“发送到 Excel”的按钮。如果用户单击此按钮,该程序将开始生成报告(将数据表内容写入 excel 文件)。完成后,会出
理论:我在开始时做出了大约 100 个 promise ,然后使用 Promise.all() 解决它们。 这 100 个 promise 中的每一个依次进行一些异步 REST 调用,其响应可能主要不
在将文件添加到 python 中的 tar 存档时,是否有任何库可以显示进度,或者可以扩展 tarfile 模块的功能来执行此操作? 在理想情况下,我想展示 tar 创建的总体进度以及关于何时完成的预
有没有办法在 Xcode 中更改进度 View 栏的高度? 我正在使用 Xcode 4.3 并且需要一个垂直进度条。我旋转了栏,但现在无法更改高度并且显示为一个圆圈。 还有一种更有效的旋转进度条的方法
您好,我想在栏按钮项上制作未确定的进度 View 。完成后我想让它隐藏,但 hidden() 方法没有像 disabled(Bool) 这样的参数。任务完成后如何隐藏进度 View ? 这就是我要的
我有一个管理员控制的功能(导入数据库)可能需要一些时间才能完成,所以我想在这段时间内向用户显示一些反馈 - 例如进度条,或者只是一些消息。即使在长时间的 Action 中分部分发送页面也足够了。 在
我是一个进步的菜鸟,实际上在基本 block 方面有问题。 下面的问题是在我的 if else 语句中。它在 if, then, else then 时工作正常,但是当我想将多个语句放入 if 部分时
我有一个来自 rsync 命令的日志文件,其中有进度。运行此进度时,会更新同一行上的显示信息。当我捕获此命令的输出时,我得到一个在终端上使用 cat 正常显示的文件(重播所有退格键和重新编辑)但我希望
我需要处理一些数据,每 5-10 秒显示一个进度(我以 % 显示进度,但我也更新了一些图表)。我想在没有多线程的情况下做到这一点。 循环可能相当大。它可以从数百万开始,可以高达数十亿。 我可以使用 G
我正在致力于使用 PHP、HTML 和 JavaScript 制作半直播互联网 channel 。 您可以在此处查看演示:http://mariocreative.host/chanelko/inde
我实际上正在使用图像为“点点点”进度设置动画。我想通过使用下面的代码来使用不透明度。 动画将持续 3 秒,有没有更简单的动画方法? 最佳答案 这是一个快速版本,它会在控
我写了这个程序,它返回用户插入的最大整数。现在,我希望程序返回第二大整数。我创建了一个新变量(称为“状态”),该变量应该在每次循环重复时增加 1 个单位。然后,在中断条件发生后,我将在状态变量中后退
我正在制作一个需要保存进度的java游戏。但我不想让外部文件保存进度(像《我的世界》这样的游戏有一个存储文件的“保存”目录)。所以基本上我希望它存储一些数据,当用户退出并再次返回时可以检索这些数据。比
我正在使用 forEach_root 方法在 Android 上计算图像。 RenderScript RS=RenderScript.create(context); Allocation inPix
我希望这个进度 View 在完成后基本上“重置”。 尝试将计数重置为 0,它确实重置了,但是对于每次重置,计时器只会变得越来越快。 .h @property (nonatomic, strong) N
我不确定这是否可能。当您单击“提交”按钮时,似乎有一种方法可以做到这一点。 private Button getButton(String id) { return new AjaxButto
我找不到关于如何在迭代循环时更新 UIProgressbar 进度的明确答案,例如: for (int i=0;i
我正在尝试在 Xcode 中翻转 UIProgressView 180,同时我正在尝试缩放进度 View 。在我添加翻转之前缩放效果很好,然后缩放不再起作用。有什么建议么?谢谢! [self.seco
我目前正在通过评估 prepareForSegue 中的 segue.identifier 动态加载新 View : - (void)prepareForSegue:(UIStoryboardSegu
当任意进程发生时,我需要在屏幕上为用户提供状态。我无法知道需要多长时间。我怎样才能永远增加 progressView (当它接近 1 时它会减慢)。 最佳答案 This如果您愿意更换进度 View ,
我是一名优秀的程序员,十分优秀!