电话号码归属地查询——分割较大的文本文件成若干小文件

---------------------- android培训java培训、期待与您交流! ----------------------

       本文是为参加传智播客asp.net黑马班写的第二篇asp.net技术文章。主题是将一个比较大的文本文件分割成若干个体积较小的小文件。

      题目来源:上次我有提到要做个基于数据库的电话号码归属地查询程序,单线程导入数据到数据库中比较费时,效率低下。所以,我就希望做成多线程导入资料,于是就有了上一文章主题:验证多线程同时往一个数据表中插入数据。通过上次文章知道,MS sqlserver是支持多线程同时往一个数据表中写数据的。解决了写数据的问题,那么还有读数据的问题,即如何用多线程将数据读出来?

      由于我下的号段资料是在一个比较大的文本文件中(10.3M),若用多线程同时读一个文件,除不知道是否可行外,也不太好控制,不知道各个线程分别该读哪些内容。于是我就想将大文件分割成数个体积相对较小的文件,然后让一个线程读取一个文件的内容,读完后再独立的往数据库中写数据。因此,接下来就得想方法将一个文件分割分若干份小文件。

      我们知道,操作一个文件肯定要用操作文件相关的IO类。通过查看帮助文档,发现对于有以下几个类可能能用到:

File:提供了很多静态方法操作文件;

FileStream:提供有丰富的读写文件的方法;

Directory:扫描目录,获取文件;

Path:操作文件路径;

好了,准备工作完成,开始写代码,如下:


        private void button2_Click(object sender, EventArgs e)
        {

            if (SplitFiles())
            {
                MessageBox.Show("分割完成!");
            }
            else
            {
                MessageBox.Show("分割失败!");
            }
            

        }

        /// <summary>
        /// 分割文件
        /// </summary>
        /// <returns>成功:true;失败:false</returns>
        bool SplitFiles()
        {
            FolderBrowserDialog filePath = new FolderBrowserDialog();
            if (filePath.ShowDialog() != DialogResult.OK)
            {
                return false;
            }
            string path = filePath.SelectedPath;//得到用户选择的路径
            string[] files = Directory.GetFiles(path, "*.txt", SearchOption.TopDirectoryOnly);//得到路径下的所有文本文件

            foreach (var file in files)//遍历目录下的文件
            {
                int i = 0;
                int readLength =0;
                byte[] bytesRead;
                int getBytes = 0;
                int writeLength = 1024 * 100;//新文件的大小:100K

                //开始读文本数据
                using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read))
                {
                    readLength = (int)fs.Length;
                    bytesRead = new byte[readLength];
                    while (readLength > 0)
                    {

                        int n = fs.Read(bytesRead, getBytes, bytesRead.Length);

                        if (n == 0)
                        {
                            break;
                        }
                        getBytes += n;
                        readLength -= n;
                    }
                }
                
                //建立保存新文件的目录
                string newPath = path + @"\" + Path.GetFileNameWithoutExtension(file) + @"\";
                if (Directory.Exists(newPath) == false)
                {
                    Directory.CreateDirectory(newPath);
                }

                //开始将数据写入小文件中
                while (getBytes > 0)
                {
                    i++;
                    string newfile = newPath + i.ToString() + ".txt";
                    using (FileStream fw = new FileStream(newfile, FileMode.Create, FileAccess.Write))
                    {
                        if (getBytes < writeLength)
                        {
                            fw.Write(bytesRead, readLength, getBytes);
                        }
                        else
                        {
                            fw.Write(bytesRead, readLength, writeLength);
                        }
                    }
                    readLength += writeLength;
                    getBytes -= writeLength;
                }
                
            }
            return true;
        }

通过测试,这个程序      运行结果基本符合预期。但并不是完美的,由于文本文件中的数据一行就是一条完整记录。如下图:

而FileStream基于      数据流进行操作的,因此会造成有些行被分割了。上半条数据在一个文件的尾部,下半条数据在一个文件的开头。如下如所示:


      如果在往数据库写数据时,读取到这样的数据将发生异常。想了很久,都无法解决这个问题。如果有哪位高手要知道怎么做,欢迎给出解决办法,不胜感激。
---------------------- android培训java培训、期待与您交流! ----------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值