C# 檔案操作

别动我的猫發表於2024-07-30

本篇主要記錄C#操作檔案

相對路徑在專案檔案...\bin\Debug 目錄下

一、寫入讀取檔案

寫入
        /// <summary>
        /// initial 檔案寫入
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button1_Click(object sender, EventArgs e)
        {
            //1.建立一個鍵值對
            Dictionary<String, Dictionary<string, string>> data = new Dictionary<string, Dictionary<string, string>>();
            //2.新增資料來源
            data.Add("裝置套接字", new Dictionary<string, string>()
            {
                {"ip","192.168.21.11" },
                {"","502" }
            });
            //3.寫入到本地
            using (StreamWriter streamWriter = new StreamWriter(path,true))
            {
                //4.迴圈寫入
                foreach (string item in data.Keys)
                {
                    //4.1寫入鍵
                    streamWriter.WriteLine($"[{item}]");
                    //5.寫入值
                    foreach (string item2 in data[item].Keys)
                    {
                        streamWriter.WriteLine($"{item2}={data[item][item2]}");
                    }

                }
            }
            
        }
  
讀取
        /// <summary>
        /// initial 檔案讀取
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button2_Click(object sender, EventArgs e)
        {
            Dictionary<String, Dictionary<string, string>> saveData = new Dictionary<string, Dictionary<string, string>>();
            string key = null;

            //配置io流
            using (StreamReader reader = new StreamReader(path,true))
            {
                while (!reader.EndOfStream)
                {
                    //讀取
                    string data = reader.ReadLine();
                    //判斷是否鍵
                    if (data.StartsWith("[") && data.EndsWith("]"))
                    {
                        key = data.Substring(1, data.Length - 2);
                        saveData.Add(key,new Dictionary<string, string>());
                    }
                    //判斷是否是值
                    else if (!string.IsNullOrEmpty(data) && !data.EndsWith(";"))
                    {
                        int index = data.IndexOf("=");
                        if (index > 0)
                        {
                            //獲取值
                            saveData[key].Add(data.Substring(0,index), data.Substring(index+1));
                        }
                    }
                   
                }
               
            }
        }

二、檔案的基本操作

目錄操作
        /// <summary>
        /// 建立目錄
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button1_Click(object sender, System.EventArgs e)
        {
            //###一.建立資料夾兩種路徑方式
            //1.相對路徑地址,專案輸出路徑,在../bin/Debug目錄下
            Directory.CreateDirectory("log");
            //在建立的目錄中建立子目錄
            Directory.CreateDirectory("log/zhangsan");

            //2.絕對路徑地址,加磁碟符
            //Directory.CreateDirectory("D:\\c#\\source\\test");


            // ###2.判斷指定路徑下是否有該目錄
            if (Directory.Exists("log"))
            {
                MessageBox.Show("存在");
            }

        }

        /// <summary>
        /// 刪除目錄
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button2_Click(object sender, System.EventArgs e)
        {
            //刪除目錄,刪除的目錄必須為空,見構造方法
            Directory.Delete("log/zhangsan",true);
           
            MessageBox.Show(Directory.Exists("log")?"刪除成功":"刪除失敗");
            
        }

        /// <summary>
        /// 查詢子檔案
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button3_Click(object sender, System.EventArgs e)
        {
            //查詢目錄下的檔案,不是資料夾,檔案是帶字尾名的,例如:111.txt
            string[] files = Directory.GetFiles("log");
            foreach (var item in files)
            {
                MessageBox.Show(item);
            }
        }

檔案流
 // FileStream: 檔案流

        Encoding encoding = Encoding.UTF8;//二進位制轉換格式
        /// <summary>
        /// 寫入檔案
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button4_Click(object sender, System.EventArgs e)
        {
            //第一步:配置檔案操作物件
            string path = "opreationLog.txt";
            FileMode fileMode = FileMode.Append;
            FileAccess fileAccess = FileAccess.Write;

            //初始化IO流物件
            FileStream fileStream = new FileStream(path, fileMode, fileAccess);

            //第二步:寫入
            //TODO: 注意這裡要加入 \r 才能識別儲存換行
            byte[] data = encoding.GetBytes($"{textBox1.Text}\r\n");
            fileStream.Write(data,0,data.Length);

            //關閉IO流
            fileStream.Close();

        }

        /// <summary>
        /// 讀取檔案
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button5_Click(object sender, System.EventArgs e)
        {
            //第一步:配置檔案操作物件
            string path = "opreationLog.txt";
            FileMode fileMode = FileMode.Open;
            FileAccess fileAccess = FileAccess.Read;

            //初始化IO流物件
            FileStream fileStream = new FileStream(path, fileMode, fileAccess);

            byte[] readBytes = new byte[1024];
            fileStream.Read(readBytes, 0, 1024);
            textBox2.Text = encoding.GetString(readBytes);

            //關閉IO流
            fileStream.Close();
        }

序列化
        /// <summary>
        /// 序列化匯出
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button6_Click(object sender, System.EventArgs e)
        {
            //第一步:配置檔案操作物件
            string path = "save_person.txt";
            FileMode fileMode = FileMode.Create;
            FileAccess fileAccess = FileAccess.Write;

            // 第二步:配置io流物件
            //using自動管理關閉檔案流
            using (FileStream fileStream = new FileStream(path, fileMode, fileAccess))
            {
                //建立序列化物件
                BinaryFormatter binary = new BinaryFormatter();
                //獲取表格中的資料
                List<Person> persons = new List<Person>();
                Person person;
                for (int i = 0; i < dataGridView1.Rows.Count-1; i++)
                {
                    person = new Person();
                    person.Id = Convert.ToInt32(dataGridView1.Rows[i].Cells[0].Value); 
                    person.Name = dataGridView1.Rows[i].Cells[1].Value.ToString(); 
                    person.Age = Convert.ToInt32(dataGridView1.Rows[i].Cells[2].Value); 
                    persons.Add(person);
                }
                //開始序列化
                binary.Serialize(fileStream,persons);
            }
        }

        /// <summary>
        /// 序列化匯入
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button7_Click(object sender, EventArgs e)
        {
            //第一步:配置檔案操作物件
            string path = "save_person.txt";
            FileMode fileMode = FileMode.Open;
            FileAccess fileAccess = FileAccess.Read;

            // 第二步:配置io流物件
            //using自動管理關閉檔案流
            using (FileStream fileStream = new FileStream(path, fileMode, fileAccess))
            {
                //建立序列化物件
                BinaryFormatter binary = new BinaryFormatter();
                //反序列化
                Object obj = binary.Deserialize(fileStream);
                //轉換成集合
                List<Person> people = (List<Person>)obj;
                //清理表格上的資料
                dataGridView1.Rows.Clear();
                //迴圈寫入
                foreach (var item in people)
                {
                    dataGridView1.Rows.Add(item.Id, item.Name, item.Age);
                }


            }
        }
    }

    [Serializable]
    class Person
    {
    }

三、CSV檔案

        /// <summary>
        /// 匯入CSV
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button2_Click(object sender, EventArgs e)
        {
            //第一步:配置IO流操作物件
            using (StreamReader streamReader = new StreamReader("產品資料.csv"))
            {
                int index = 0;

                while(!streamReader.EndOfStream)
                {
                    string data = streamReader.ReadLine();
                    string[] str = data.Split(',');
                    //不插入表頭
                    if (index > 0)
                    {
                        dataGridView1.Rows.Add(str);
                    }
                    index++;
                }
                

            }
        }

        /// <summary>
        /// 匯出CSV
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button1_Click(object sender, EventArgs e)
        {
            //第一步:配置檔案流操作物件
            using(StreamWriter streamWrite = new StreamWriter("產品資料.csv",false))
            {
                //加入表頭
                streamWrite.WriteLine($"{dataGridView1.Columns[0].HeaderText},{dataGridView1.Columns[1].HeaderText},{dataGridView1.Columns[2].HeaderText}");
                //第二步:迴圈寫入
                for (int i = 0; i < dataGridView1.Rows.Count -1; i++)
                {
                    streamWrite.WriteLine($"{dataGridView1.Rows[i].Cells[0].Value},{dataGridView1.Rows[i].Cells[1].Value},{dataGridView1.Rows[i].Cells[2].Value}");
                }
             
            }
        }

四、Excel

       /// <summary>
        /// 匯出excel檔案
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button4_Click(object sender, EventArgs e)
        {
            //第一步:配置Excel檔案操作物件
            using (XLWorkbook xl = new XLWorkbook())
            {
                //第二步:建立工作頁
                IXLWorksheet sheet = xl.AddWorksheet("產品資料頁1");
                //第三步:迴圈新增資料

                //寫入表頭
                for (int i = 0; i < dataGridView1.Columns.Count; i++)
                {
                    //注意Cell 必須從1開始,否則報錯
                    sheet.Cell(1, i + 1).Value = dataGridView1.Columns[i].HeaderText;
                }

                //寫入表格資料
                for (int i = 0; i < dataGridView2.Rows.Count-1; i++)
                {
                    //第四步:獲取第i行列的值
                    for (int j = 0; j < dataGridView2.Rows[i].Cells.Count; j++)
                    {
                        //第五步:寫入資料
                        sheet.Cell(i+2,j+1).Value = dataGridView2.Rows[i].Cells[j].Value.ToString();
                    }
                }
                //第六步:儲存到本地
                xl.SaveAs("資料.xlsx");
            }
        }

        /// <summary>
        /// 匯入Excel檔案
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button3_Click(object sender, EventArgs e)
        {
            //第一步:配置Excel檔案操作物件
            using (XLWorkbook xl = new XLWorkbook("資料.xlsx"))
            {
                //第二步:獲取第一個sheet頁
                IXLWorksheet workbook = xl.Worksheet(1);
                //第三步:獲取sheet頁中資料
                IXLRow row;
                List<string> list;
                // 從2開始不要表頭
                for (int i = 2; i <= workbook.Rows().Count(); i++)
                {
                    row = workbook.Row(i);
                    list = new List<string>();
                    for (int j = 1; j <= row.Cells().Count(); j++)
                    {
                        string data = workbook.Cell(i, j).Value.ToString();
                        list.Add(data);
                    }

                    dataGridView2.Rows.Add(list);
                }
            }
        }