首页 新闻 会员 周边

C#如何在csv文件某行插入数据或重写数据

0
悬赏园豆:20 [已解决问题] 解决于 2020-01-17 08:52

我想在C#窗体应用中操作csv文件,需要查询某个数据,然后确定改行位置,然后在这个位置添加数据或重写数据,如何实现?类似数据库的增删改查,可以实现吗?

问题补充:

我想问csv文件能不能在某行添加或修改数据,一定要读取全部数据出来,修改后再重新写进去吗?

😀明笔记的主页 😀明笔记 | 初学一级 | 园豆:13
提问于:2020-01-16 09:21
< >
分享
最佳答案
1

操作系统把文件抽象成了“流”,流是无法在中间插入数据的,只能在末尾插入。你可以打开文件,并用Stream.Seek()方法定位到指定位置,也可以改写数据,但是无法在中间插入。如果想在中间插入数据,你得把从你插入位置之后的所有数据重新写入到流中。

收获园豆:20
sweetjian | 菜鸟二级 |园豆:276 | 2020-01-16 13:38

如何使用seek定位到指定位置,可以定位到某一行吗?
假如改写了第三行,后面的都要重写吗?

😀明笔记 | 园豆:13 (初学一级) | 2020-01-16 13:41

@😀明笔记: 文件本身是没有“行”的。“行”只是文件中的一个换行符号。

比如三行文本,在流中是这样的:
AAAAAAA\r\nBBBB\r\nCCCC\r\n

如果你要定位某一行,可以读取流并查找换行符(\r\n),要定位第几行就查找几个换行符,读取的时候,跟seek一样,流的Position也在往前走。

sweetjian | 园豆:276 (菜鸟二级) | 2020-01-16 13:54

@sweetjian: 加入现在有一个文本AAAAAAA\r\nBBBB\r\nCCCC\r\n,可以提供改写BBBB的代码参考一下吗?

😀明笔记 | 园豆:13 (初学一级) | 2020-01-16 13:59

@😀明笔记:
有了思路要自己去研究,不能总是要代码。

            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 | 园豆:276 (菜鸟二级) | 2020-01-16 14:38

@sweetjian:
这边任务紧急,谢谢指导,但是你的代码我试过了。实现不了我说的功能啊。没有把“XXXXXX”修改进去。是什么原因呢?

😀明笔记 | 园豆:13 (初学一级) | 2020-01-16 15:00

@😀明笔记:

           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();
            }
sweetjian | 园豆:276 (菜鸟二级) | 2020-01-16 15:09
其他回答(4)
0

楼主可以看一下这篇文章:https://blog.csdn.net/pan_junbiao/article/details/8872936

初夏的阳光丶 | 园豆:641 (小虾三级) | 2020-01-16 09:25

恕我愚钝,信息量太大看不过来。可以提供思路和方法吗?

支持(0) 反对(0) 😀明笔记 | 园豆:13 (初学一级) | 2020-01-16 09:29

@😀明笔记: 如果要简单点的思路。两种吧。第一种 你可以先读取到所有的数据 然后转成List<T> ,再将你需要处理的数据处理掉 最后重新写入到excel中 第二种 就是先读取到数据,然后用索引的方式找到你要处理的数据,再讲哪一行添加到特定的行数下

支持(0) 反对(0) 初夏的阳光丶 | 园豆:641 (小虾三级) | 2020-01-16 09:34

@初夏的阳光丶: 我想要第二种方法,问题就是如何在csv表格特定行数下添加数据,可否提供例子或方法?

支持(0) 反对(0) 😀明笔记 | 园豆:13 (初学一级) | 2020-01-16 09:37

@😀明笔记: 获取数据和添加数据这个网上例子应该很多 https://blog.csdn.net/huanglin529/article/details/81079781 插入空白行
https://blog.csdn.net/kevinfan2011/article/details/83961117 指定单元格赋值

支持(0) 反对(0) 初夏的阳光丶 | 园豆:641 (小虾三级) | 2020-01-16 09:46

@初夏的阳光丶: 我想操作的是csv文件。不是excel表格哦

支持(0) 反对(0) 😀明笔记 | 园豆:13 (初学一级) | 2020-01-16 10:31

@😀明笔记: 两者区别不大

支持(0) 反对(0) 初夏的阳光丶 | 园豆:641 (小虾三级) | 2020-01-16 10:31

@初夏的阳光丶: 一个是需要引用Microsoft.Office.Interop.Excel的,一个是直接写文本的。我感觉区别很大,哈哈哈

支持(0) 反对(0) 😀明笔记 | 园豆:13 (初学一级) | 2020-01-16 10:33
0

csv文件就是用什么号分隔的文本文件。。百度读写文本文件就行了

猝不及防 | 园豆:2781 (老鸟四级) | 2020-01-16 09:45

读写文本我会,但是我想在具体某行添加数据

支持(0) 反对(0) 😀明笔记 | 园豆:13 (初学一级) | 2020-01-16 09:47

@😀明笔记: 可以追加,单独插入的话好像没有啥好办法,都是整体变动的

支持(0) 反对(0) 猝不及防 | 园豆:2781 (老鸟四级) | 2020-01-16 10:04

@猝不及防: 所以csv不行,只能用excel的形式了?

支持(0) 反对(0) 😀明笔记 | 园豆:13 (初学一级) | 2020-01-16 10:05

@😀明笔记: 看你的业务场景了,用excel的话如果用com组件,首先要求电脑上得装office,还不能是盗版的,大数据的话最好是用数据库,否则直接读写文件也费不了什么性能

支持(0) 反对(0) 猝不及防 | 园豆:2781 (老鸟四级) | 2020-01-16 10:15

@猝不及防: 数据量很大哦,上千。如果全部读出来,再修改,会不会很影响性能?

支持(0) 反对(0) 😀明笔记 | 园豆:13 (初学一级) | 2020-01-16 10:17

@猝不及防: 有没有在csv文件中某一行开始写数据?

支持(0) 反对(0) 😀明笔记 | 园豆:13 (初学一级) | 2020-01-16 10:22

@😀明笔记: 会占内存,最大也就是你这个文件的大小,这就为什么说要用数据库存储数据而不是大文件了

支持(0) 反对(0) 猝不及防 | 园豆:2781 (老鸟四级) | 2020-01-16 10:23

@😀明笔记: 文件是个整体,除非追加,否则动了一点所有都要重写

支持(0) 反对(0) 猝不及防 | 园豆:2781 (老鸟四级) | 2020-01-16 10:25

@猝不及防: 那可以在某一行追加内容吗?

支持(0) 反对(0) 😀明笔记 | 园豆:13 (初学一级) | 2020-01-16 10:32
0

可以用第三方操作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);

ms_doudou | 园豆:1166 (小虾三级) | 2020-01-16 11:22
0

C#我不会,python操作起来蛮方便的pandas,numpy两个模块就好了

小小咸鱼YwY | 园豆:3210 (老鸟四级) | 2020-01-16 11:27
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册