.NET 6学习笔记(1)——通过FileStream实现不同进程对单一文件的同时读写
会写这篇纯属机缘巧合,虽然一直以来认为对单一文件的读、写操作是不冲突,可并行的,但实际并未实践过。正好有个UWP的程序要并行读取由Desktop Extension创建的文本,需要有个原型程序来验证,那不妨点开最新的VS 2022,顺手试试新的语法糖。
首先我们明确本篇对文件的操作均通过FileStream类来实现,FileStream在.NET 6进行了完全的重写,提高了性能和可靠性。但是本篇提到的共享读写权限,在之前版本也是完全支持的。
本篇提到的同时读写功能依赖FileStream的这个构造函数:
public FileStream (string path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share);
接下来我们通过实际的代码来进行分析。创建第一个工程CreateWriteSharedFile,该工程为.NET 6的Console程序,用于新建和写入内容到名为TestFile.txt的文件中。
var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "TestFile.txt");
var fileStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite);
StreamWriter sw = new StreamWriter(fileStream);
int cout = 0;
while (true)
{
for (var i = 0; i < 10; i++)
{
sw.WriteLine(cout++);
Console.WriteLine(cout);
}
sw.Flush();
await Task.Delay(1000);
}
没有命名空间,没有类名和Main函数,这是C# 10里的新语法糖——顶级语句。作为简化后的程序入口点,十分适合我们这样的简短示例程序,对初学者也更友好。
代码的内容也很好懂,就是每个1秒连续写入10个自增的数字。唯一值得留意的是FileShare.ReadWrite,这个枚举标识对应的是后续其他对该文件的请求,不管是该进程内还是另外进程,均给与ReadWrite的权限。
我们的第二个工程ReadSharedFile仅做读取的操作,所以上面CreateWriteSharedFile中的FileShare只给Read也可以。但是相反,ReadSharedFile因为要允许CreateWriteSharedFile来进行写操作,所以它必须给与FileShare.Write枚举。
var path =Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "TestFile.txt");
var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read,FileShare.Write);
var reader = new StreamReader(fileStream); while (!reader.EndOfStream)
{
Console.WriteLine(reader.ReadLine());
await Task.Delay(1000);
}
上述代码是在ReadSharedFile工程中读取由CreateWirteSharedFile创建的TestFile.txt中的内容。想要测试的话,build成功后运行对应的exe文件即可。并行的读和写操作很好理解,也不会存在冲突或生成脏数据的问题。

但如果是同时进行写操作会怎么样呢?之前的FileShare.ReadWrite就是为接下来的测试准备的。我们创建第二个写文件的工程SecondWriteSharedFile,同样要注意除了设置Read以外,还要为CreateWriteSharedFile特别准备Write权限,才能实现两边同时写入该文件的要求。
var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "TestFile.txt");
var fileStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite);
StreamWriter sw = new StreamWriter(fileStream); while (true)
{
for (var i = 0; i < 10; i++)
{
sw.WriteLine("A".PadRight(i,'A'));
Console.WriteLine("A".PadRight(i, 'A'));
} sw.Flush();
await Task.Delay(1000);
}
非常不幸的是,SecondWriteSharedFile在默认情况下,同样会从文件的头部开始写入,这样就覆盖了先运行的CreateWriteSharedFile在同样位置写入的内容。所以在一般情况下,我们要避免并行的写操作,这样极容易互相覆盖产生脏数据。
本篇简单地讨论了使用FileShare枚举,通过FileStream并行的读写文件的一般场景。希望能够抛砖引玉,给各位大佬在实际生产场景中以微小的帮助。
示例代码:(因为GitHub经常打不开,我在gitee也同样放了一份)
https://github.com/manupstairs/FileReadWriteSample
https://gitee.com/manupstairs/FileReadWriteSample
以下链接,是MS Learn上Windows开发的入门课程,单个课程三十分钟到60分钟不等,想要补充基础知识的同学点这里:
开始使用 Visual Studio 开发 Windows 10 应用
.NET 6学习笔记(1)——通过FileStream实现不同进程对单一文件的同时读写的更多相关文章
- VSTO学习笔记(四)从SharePoint 2010中下载文件
原文:VSTO学习笔记(四)从SharePoint 2010中下载文件 上一次我们开发了一个简单的64位COM加载项,虽然功能很简单,但是包括了开发一个64位COM加载项的大部分过程.本次我们来给CO ...
- Java学习笔记四---打包成双击可运行的jar文件
写笔记四前的脑回路是这样的: 前面的学习笔记二,提到3个环境变量,其中java_home好理解,就是jdk安装路径:classpath指向类文件的搜索路径:path指向可执行程序的搜索路径.这里的类文 ...
- Java学习笔记4---打包成双击可运行的jar文件
写笔记四前的脑回路是这样的: 前面的学习笔记二,提到3个环境变量,其中java_home好理解,就是jdk安装路径:classpath指向类文件的搜索路径:path指向可执行程序的搜索路径.这里的类文 ...
- node学习笔记1——配置node环境变量及执行node文件
最近在学习node,今天说一下node的变量环境配置.虽然网上有说,最新版的已经不需要配置这个东东了,但是我的电脑还是得配置.闲话少扯,进入正题: 1.安装node,这步就略过了.就是下载 node, ...
- UNP学习笔记(第十三章 守护进程和inetd超级服务器)
关于守护进程可以查看apue的笔记 http://www.cnblogs.com/runnyu/p/4645046.html daemon_init函数 下面给出名为daemon_init函数,通过调 ...
- linux初级学习笔记二:linux操作系统及常用命令,文件的创建与删除和命名规则,命令行展开以及linux中部分目录的作用!(视频序号:02_3)
本节学习的命令:tree,mkdir,rmdir,touch,stat,rm 本节学习的技能:Linux中主要的目录作用以及特殊的目录文件: 文件的命名规则,命令行展开: 文件的创建与删除: Linu ...
- java学习笔记(2):获取文件名和自定义文件过滤器
//自定义文件过滤器import java.io.File; import javax.swing.filechooser.*; public class JavaChooser extends Fi ...
- struts2视频学习笔记 15-17 (访问或添加request属性,文件上传)
课时15 访问或添加request/session/application属性 1.简单说 page指当前页面.在一个jsp页面里有效 2.request 指从http请求到服务器处理结束,返回响应的 ...
- Android(java)学习笔记184:生成 4种 不同权限的文件
1.首先我们编写一个生成 4种 不同权限的文件的程序案例: (1)首先是activity_main.xml文件: <RelativeLayout xmlns:android="http ...
随机推荐
- 服务器表单字符串转化Vue表单挂在到对应DOM节点
今天在项目开发中,遇到从后端返回的vue文件(包含template,js,css)的文件,试过用v-html解析文件,渲染到页面,但是无法渲染,后来去查了一堆资料,自己写了一个全局方法来解析这类文件 ...
- 【Java】成员变量赋值执行顺序
程序中成员变量赋值的执行顺序
- Idea操作Maven详细使用:
Idea操作Maven详细使用: Maven简介 什么是 Maven Maven 的正确发音是[ˈmevən] "卖v",而不是"马瘟"以及其他什么瘟. Mav ...
- 《剑指offer》面试题50. 第一个只出现一次的字符
问题描述 在字符串 s 中找出第一个只出现一次的字符.如果没有,返回一个单空格. 示例: s = "abaccdeff" 返回 "b" s = "&q ...
- 带你玩转Flink流批一体分布式实时处理引擎
摘要:Apache Flink是为分布式.高性能的流处理应用程序打造的开源流处理框架. 本文分享自华为云社区<[云驻共创]手把手教你玩转Flink流批一体分布式实时处理引擎>,作者: 萌兔 ...
- 《手把手教你》系列技巧篇(五十九)-java+ selenium自动化测试 - 截图三剑客 -上篇(详细教程)
1.简介 今天本来是要介绍远程测试的相关内容的,但是宏哥在操作服务器的时候干了件糊涂的事,事情经过是这样的:本来申请好的Windows服务器用来做演示的,可是服务器可能是局域网的,连百度都不能访问,宏 ...
- vue学习11-监听属性
<!DOCTYPE html> <html lang='en'> <head> <meta charset='UTF-8'> <meta http ...
- 观察者模式(Observer模式)
模式的定义与特点 观察者(Observer)模式的定义:指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新.这种模式有时又称作发布-订阅模式.模型- ...
- java-异常-finally代码块
1 package p1.exception; 2 3 4 class Demo_0{ 5 public int show(int index) throws ArrayIndexOutOfBound ...
- db2服务器linux的cache过高原因
在线上db2数据库服务器,使用的linux操作系统(RHEL,centos),当db2数据库运行一段时间之后,操作系统的物理内存就趋近于0,同时系统的cache暴增,但是use却不高,下面是正常使用 ...