C# IO操作(四)大文件拷贝(文件流的使用)、文件编码
大文件拷贝(文件流的使用)、文件编码
首先说一下大文件拷贝和文件流,因为计算机的内存资源是有限的,面对几个G甚至更大的文件,需要通过程序来完成拷贝,就需要用到文件流(因为我们无法做到把文件一次性加载到内存中;事实上,内存也不允许这么干),所以在C#中出现了内存流这个东西。先看下面的内容,File类中的常用读取文件方法会将文件内容一次性全部加载到内存中:
string sPath = @"C:\Users\Chens-PC\Desktop\Nginx.txt";
//File类的ReadAllBytes()方法会将文本内容一次性读取到内存中,然后以byte数组返回(同时关闭文件)。
byte[] bteData = File.ReadAllBytes(sPath);
//File类的ReadAllLines()方法会将文本内容一次性逐行读取到内存中,然后以string数组返回(同时关闭文件),它的重载能指定读取时使用的编码。
string[] strData = File.ReadAllLines(sPath);
//File类的ReadAllText()方法会将文本内容一次性读取到内存中,然后以string字符串返回(同时关闭文件),它的重载能指定读取时使用的编码。
string sData = File.ReadAllText(sPath);
注:上面的代码,在传参时为Encoding.Default(表示与当前操作系统编码一致,一般是简体中文ANSI),而DotNet新建文本文件编码为UTF-8.
在进行大文件拷贝之前,先说一下,如果使用文件流(FileStream):
#region 通过文件流写文件
string sMsg = "风儿吹来了童年的一幅画 你陪着我在那过家家 竹林是我们的家 竹叶是你送我的花 抬头见你笑得那么的无暇";
using (FileStream fsWrite = new FileStream("msg.txt", FileMode.Create, FileAccess.Write))
{
byte[] bteData = System.Text.Encoding.UTF8.GetBytes(sMsg);
fsWrite.Write(bteData, , bteData.Length);
fsWrite.Flush();
}
Console.WriteLine("文件写入完毕!");
#endregion
#region 通过文件流读文件
using (FileStream fsRead = new FileStream("msg.txt", FileMode.Open, FileAccess.Read))
{
byte[] bteData = new byte[fsRead.Length];
fsRead.Read(bteData, , bteData.Length);
//将byte[]数组转换成字符串时才需要指定编码。
string s = System.Text.Encoding.UTF8.GetString(bteData);
Console.WriteLine(s);
}
#endregion
1.大文件拷贝:
思路:考虑到大文件的拷贝要边读边写,故要创建2个文件流(一个读,一个写),案例的代码如下(winform照样适用):
#region 大文件拷贝
string sSource = @"F:\系统\cn_windows_7_ultimate_with_sp1_x86_dvd_618763.iso";
string sTarget = @"E:\C#练习第一天\windows_7.iso"; CopyBigFile(sSource, sTarget);
Console.ReadKey();
#endregion
private static void CopyBigFile(string sSource, string sTarget)
{
using (FileStream fsRead=new FileStream(sSource,FileMode.Open,FileAccess.Read))
{
using (FileStream fsWrite=new FileStream(sTarget,FileMode.Create,FileAccess.Write))
{
//定义缓冲区
byte[] bteData = new byte[ * * ];
int r = fsRead.Read(bteData, , bteData.Length);
while (r>)
{
fsWrite.Write(bteData, , r);
double d = * (fsWrite.Position / (double)fsRead.Length);
Console.WriteLine("{0}%", d);
r = fsRead.Read(bteData, , bteData.Length);
}
Console.WriteLine("复制大文件成功");
}
}
}
说明:
快速创建文件流的方式:(不要在循环中创建文件流,放在循环外,效率问题)
FileStream fsRead=File.OpenRead(sPath); //快速创建读取流
FileStream fsWrite=File.OpenWrite(sPath); //快速创建写入流
FileStream fs=File.Open(sPath,FileMode.OpenOrCreate); //创建文件流
上面的3个方法只是微软对(大文件拷贝中创建文件流方法的封装,简化代码编写的方式)。
最后再来讨论文件读写乱码的问题(文件编码):
下面是常用的文本文件编码:
1.GB2312编码:兼容ASCII码表,英文字符用1个字节表示(字节用正数来表示),中文用2个字节表示(字节用负数来表示)。
2.GBK编码:兼容GB2312编码。中文用2个字节表示(第1个字节用负数,第2个字节用紧跟其后的正数)。
3.Unicode:国际码表,中英文都占2个字节。
4.UTF-8:国际码表,英文占1个字节,中文占3个字节。
因为各种编码存储数据格式不一致,如果读写编码不同就会乱码,解决乱码的途径就是让读写操作时保证编码一致即可。
文件编码的BOM头:
时常在读取文件时用文件的编码,有时前面会多一个问号,这是因为BOM头造成的File.ReadAllBytes().(不准确,有的编码带BOM头,有的则不带)
2.StreamReader与StreamWriter:
应用场景:在使用FileStream进行大文件拷贝的时候,因为中文占2个字节,那么有可能产生读汉字读一半的情况,进而产生乱码。
StreamReader,逐行读取文本文件。ReadLine()、EndOfStream. 注意:指定编码!
ReadToEnd用于从当前位置一直读到最后,内容大的话会占内存;每次调用都往下走,不能无意中调用了两次.
ReadLine读取一行,如果到了末尾,则返回null.
StreamWriter,逐行写入文本文件。
WriteLine,将字符串写入文件中的当前行。
3.压缩流GZipStream:
//GZipStream就是对FileStream的又一个包装
//将文本文件1.txt压缩
//1.创建读取文本文件的流
using (FileStream fsRead = File.OpenRead("1.txt"))
{
//2.创建写入文本文件的流
using (FileStream fsWrite = File.OpenWrite("yasuo.txt"))
{
//3.创建压缩流
using (GZipStream zipStream = new GZipStream(fsWrite, CompressionMode.Compress))
{
//4.每次读取1024byte
byte[] byts = new byte[];
int len = ;
while ((len = fsRead.Read(byts, , byts.Length)) > )
{
//通过压缩流写入文件
zipStream.Write(byts, , len);
}
}
}
}
Console.WriteLine("ok");
Console.ReadKey();
2>解压:
using (FileStream fsRead = File.OpenRead("yasuo.txt"))
{ using (GZipStream gzipStream = new GZipStream(fsRead, CompressionMode.Decompress))
{
using (FileStream fsWrite = File.OpenWrite("jieya.txt"))
{ byte[] byts = new byte[];
int len = ;
while ((len = gzipStream.Read(byts, , byts.Length)) > )
{
fsWrite.Write(byts, , len);
} }
}
}
Console.WriteLine("ok");
Console.ReadKey();
C# IO操作(四)大文件拷贝(文件流的使用)、文件编码的更多相关文章
- IO流,字节流复制文件,字符流+缓冲复制文件
JAVAIO如果按流向分:输入流和输出流两种 输入流的基类:InputStream Reader 输出流的基类:OutputStream Writer 如果按数据单元划分:字节流和字符流 字节 ...
- Java IO和Java NIO在文件拷贝上的性能差异分析
1. 在JAVA传统的IO系统中,读取磁盘文件数据的过程如下: 以FileInputStream类为例,该类有一个read(byte b[])方法,byte b[]是我们要存储读取到用户空间的缓冲区 ...
- Java IO和Java NIO 和通道 在文件拷贝上的性能差异分析
1. 在JAVA传统的IO系统中,读取磁盘文件数据的过程如下: 以FileInputStream类为例,该类有一个read(byte b[])方法,byte b[]是我们要存储读取到用户空间的缓冲区 ...
- 文件拷贝, 使用 BIO,NIO的对比,四种写法性能分析。
测试环境: jdk 1.7 + 2G内存 测试代码基本上复制了: http://blog.csdn.net/tabactivity/article/details/9317143 1 2 3 4 5 ...
- 提高生产力:文件和IO操作(ApacheCommonsIO-汉化分享)
复制.移动.删除.比较.监控.文件读写 等文件和IO操作是编程中比较常用的功能. 幸运的是,Apache Commons IO等开源组件已经帮我们实现了. 我们可以不用重复 ...
- 利用pom配置实现静态文件拷贝
java项目有时候需要将一些静态文件拷贝到生成的test-class文件夹或者其他地方,虽然手动拷贝可以做到,但是很麻烦.今天主要讲解如何利用pom.xml进行动态的拷贝. 具体的配置信息如下,在de ...
- php--------文件夹文件拷贝和复制
php开发中常常对文件进行操作,文件夹和文件的拷贝,复制等. /** * 文件夹文件拷贝 * * @param string $src 来源文件夹 * @param string $dst 目的地文件 ...
- Linux系统下远程文件拷贝scp命令
在Linux系统下,不同机器上实现文件拷贝 一.将本地文件拷贝到远程机器: scp /home/administrator/news.txt root@192.168.6.129:/etc/squid ...
- PHP文件夹文件拷贝/复制函数 dir_copy($src = '', $dst = '')
/* * 文件夹文件拷贝 * * @param string $src 来源文件夹 * @param string $dst 目的地文件夹 * @return bool */ function dir ...
- 【转】Java中的IO操作
在使用io操作之前,先看一下java中的文件类File如何使用.File包括文件和目录,对文件和目录的操作是新建目录mkdir,新建文件createNewFile,删除文件和目录delete,以及其他 ...
随机推荐
- iOS学习之NSBundle介绍和使用
iOS学习之NSBundle介绍和使用 http://blog.csdn.net/totogo2010/article/details/7672271 新建一个Single View Applicat ...
- mysql slow log分析工具的比较
mysql 中的 slow log 是用来记录执行时间较长(超过 long_query_time 秒)的 sql 的一种日志工具. 启用 slow log 在 my.cnf 中设置 [mysqld] ...
- 查看Linux主机CPU及内存信息
查看CPU信息(型号) # cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c 8 Intel(R) Xeon(R) CPU ...
- iOS音频篇:AVPlayer的缓存实现
授权转载,作者:明仔Su(简书) 在上一篇文章<使用AVPlayer播放网络音乐>介绍了AVPlayer的基本使用,下面介绍如何通过AVAssetResourceLoader实现AVPla ...
- J2EE的13个规范之(三) Servlet简单介绍
Servlet是一种server端脚本,它是一个特殊的Java类,继承自HttpServlet.开发中主要用于处理和响应client的请求. Servlet在容器中执行,事实上例的和销毁创建由容器进行 ...
- 每天进步一点点——负载均衡之DNS域名解析
转载请说明出处:http://blog.csdn.net/cywosp/article/details/38017027 在上一篇文章(http://blog.csdn.net/cywosp/ ...
- Tomcat配置域名访问
在server.xml文件中的<Host>标签里面添加 <Alias>你的域名(比如:www.baidu.com)</Alias> <Context path ...
- Making the impossible: 3 nodes intercontinental replication--转载
原文:http://www.percona.com/blog/2012/01/11/making-the-impossible-3-nodes-intercontinental-replication ...
- Google(谷歌)中国工程研究院 工程师 方坤 对学生朋友的一些建议
对学生朋友的一点建议 发表者:Google(谷歌)中国工程研究院工程师 方坤 自去年春天加入谷歌,我曾多次随公司校园招聘团队一起走访各地院校,帮助公司发掘人才 .利用这样的出差机会到处走走看看,饱览祖 ...
- Java基础知识强化之IO流笔记65:序列化流 和 反序列化流
1. 什么是 序列化 和 反序列化 ? 序列化 (Serialization):将对象的状态信息转换为可以存储或传输的形式的过程.比如转化为二进制.xml.json等的过程. 在序列化期间,对 ...