操作系统把文件抽象成了“流”,流是无法在中间插入数据的,只能在末尾插入。你可以打开文件,并用Stream.Seek()方法定位到指定位置,也可以改写数据,但是无法在中间插入。如果想在中间插入数据,你得把从你插入位置之后的所有数据重新写入到流中。
如何使用seek定位到指定位置,可以定位到某一行吗?
假如改写了第三行,后面的都要重写吗?
@😀明笔记: 文件本身是没有“行”的。“行”只是文件中的一个换行符号。
比如三行文本,在流中是这样的:
AAAAAAA\r\nBBBB\r\nCCCC\r\n
如果你要定位某一行,可以读取流并查找换行符(\r\n),要定位第几行就查找几个换行符,读取的时候,跟seek一样,流的Position也在往前走。
@sweetjian: 加入现在有一个文本AAAAAAA\r\nBBBB\r\nCCCC\r\n,可以提供改写BBBB的代码参考一下吗?
@😀明笔记:
有了思路要自己去研究,不能总是要代码。
using (var fs = File.Create("demo.txt"))
{
//初始化文件
var sw = new StreamWriter(fs);
var sr = new StreamReader(fs);
sw.WriteLine("AAAAAA");
sw.WriteLine("BB");
sw.WriteLine("CCCC");
sw.Flush();
fs.Seek(0, SeekOrigin.Begin);
//查找2个换行符位置
long p1 = -1, p2 = -1;
var last = 0;
for (int i = 0; i < fs.Length; ++i)
{
var c = fs.ReadByte();
if (last == '\r' && c == '\n')
{
if (p1 == -1) p1 = fs.Position;
else
{
p2 = fs.Position;
break;
}
}
last = c;
}
//第二个换行符之后的内容,如果是超大文件,分批缓存,避免内存占用过多
var end = sr.ReadToEnd();
//重新写入第一个换行符之后的内容
fs.Seek(p1, SeekOrigin.Begin);
sw.WriteLine("XXXXXXXXXXXX");
sw.Write(end);
}
@sweetjian:
这边任务紧急,谢谢指导,但是你的代码我试过了。实现不了我说的功能啊。没有把“XXXXXX”修改进去。是什么原因呢?
@😀明笔记:
using (var fs = File.Create("demo.txt"))
{
//初始化文件
var sw = new StreamWriter(fs);
var sr = new StreamReader(fs);
sw.WriteLine("AAAAAA");
sw.WriteLine("BBBBBBB");
sw.WriteLine("CCCC");
sw.Flush();
fs.Seek(0, SeekOrigin.Begin);
//查找2个换行符位置
long p1 = -1, p2 = -1;
var last = 0;
for (int i = 0; i < fs.Length; ++i)
{
var c = fs.ReadByte();
if (last == '\r' && c == '\n')
{
if (p1 == -1) p1 = fs.Position;
else
{
p2 = fs.Position;
break;
}
}
last = c;
}
//第二个换行符之后的内容,如果是超大文件,分批缓存,避免内存占用过多
var end = sr.ReadToEnd();
//重新写入第一个换行符之后的内容
fs.Seek(p1, SeekOrigin.Begin);
fs.SetLength(p1);
sw.WriteLine("XXXX");
sw.Write(end);
sw.Flush();
}
恕我愚钝,信息量太大看不过来。可以提供思路和方法吗?
@😀明笔记: 如果要简单点的思路。两种吧。第一种 你可以先读取到所有的数据 然后转成List<T> ,再将你需要处理的数据处理掉 最后重新写入到excel中 第二种 就是先读取到数据,然后用索引的方式找到你要处理的数据,再讲哪一行添加到特定的行数下
@初夏的阳光丶: 我想要第二种方法,问题就是如何在csv表格特定行数下添加数据,可否提供例子或方法?
@😀明笔记: 获取数据和添加数据这个网上例子应该很多 https://blog.csdn.net/huanglin529/article/details/81079781 插入空白行
https://blog.csdn.net/kevinfan2011/article/details/83961117 指定单元格赋值
@初夏的阳光丶: 我想操作的是csv文件。不是excel表格哦
@😀明笔记: 两者区别不大
@初夏的阳光丶: 一个是需要引用Microsoft.Office.Interop.Excel的,一个是直接写文本的。我感觉区别很大,哈哈哈
csv文件就是用什么号分隔的文本文件。。百度读写文本文件就行了
读写文本我会,但是我想在具体某行添加数据
@😀明笔记: 可以追加,单独插入的话好像没有啥好办法,都是整体变动的
@猝不及防: 所以csv不行,只能用excel的形式了?
@😀明笔记: 看你的业务场景了,用excel的话如果用com组件,首先要求电脑上得装office,还不能是盗版的,大数据的话最好是用数据库,否则直接读写文件也费不了什么性能
@猝不及防: 数据量很大哦,上千。如果全部读出来,再修改,会不会很影响性能?
@猝不及防: 有没有在csv文件中某一行开始写数据?
@😀明笔记: 会占内存,最大也就是你这个文件的大小,这就为什么说要用数据库存储数据而不是大文件了
@😀明笔记: 文件是个整体,除非追加,否则动了一点所有都要重写
@猝不及防: 那可以在某一行追加内容吗?
可以用第三方操作Excel的库比如Free Spire.XLS,载入CSV文件,然后像操作Excel那样就行了
下面是加载CSV,查找和高亮文本并保存为xlsx格式的代码给你参考:
//初始化Workbook对象
Workbook workbook = new Workbook();
//加载CSV文件
workbook.LoadFromFile("SampleCSVFile.csv", ",",1,1);
//获取工作表
Worksheet sheet = workbook.Worksheets[0];
//查找指定文本
CellRange[] ranges = sheet.FindAllString("紧张", false, false);
foreach (CellRange range in ranges)
{
//替换文本
range.Text = "充足";
//设置高亮显示颜色
range.Style.Color = Color.Yellow;
}
//保存为xlsx格式
workbook.SaveToFile("result.xlsx", ExcelVersion.Version2010);
C#我不会,python操作起来蛮方便的pandas,numpy两个模块就好了