关于文件的相对路径及绝对路径的问题

Paddi_z 2018-09-12 10:54:45


这个问题是在我用vs的setup项目打包后安装运行发现的,而且这个问题在打包之后必定会出现,而且不管是否文件夹下有没有这个文件都会产生(当然由于安装好的程序没法debug,我是在catch这个异常后弹提示对话框才知道的),而在我debug的时候,这个问题出现的机率很低,即使我用了System.Window.Forms.Application.StartupPath作为路径也会出现错误
使用 string path=System.Window.Forms.Application.StartupPath+@"\Dit\stopwords_zh_hit.txt";
在报错的时候查看path变量的值竟然也是"C:\Users\admin\Desktop\CmDataAnalysis\CmDataAnalysis\bin\Debug\File\Dit\stopwords_zh_hit.txt"
在之前用startuppath是不会出现这个问题的,但是当我在项目中添加了File文件夹后就莫名奇妙的会发生上面的问题。
上述问题在debug中会冷不丁的发生,也就是可能调试10多次会都不会出现这个问题,但当你以为确实没问题的时候,它又会突然冒出来。而把项目打包安装后的软件则是必定会出现该错误。
尝试特意创建上述不存在的目录并将txt文件放入,但仍无济于事,依旧报未发现路径的一部分。
不知道究竟是不是哪块地方出现问题了?
PS:该错误出现时特点就是在Debug后会加上File目录,但当我把File文件夹重命名为fe后,报错的时候仍是Debug后加File目录,不知道是不是那里配置错误了导致在某操作后会自动将可执行文件目录更改为Debug\File或者将相对路径认定为相对Debug\File下
...全文
1392 40 打赏 收藏 转发到动态 举报
写回复
用AI写文章
40 条回复
切换为时间正序
请发表友善的回复…
发表回复
Ruoch 2018-09-15
  • 打赏
  • 举报
回复
路径拼接下 前面加@
kscheng996 2018-09-15
  • 打赏
  • 举报
回复
这个真的简单,绝对路径和相对路径很容易区别啊
qq_43201122 2018-09-14
  • 打赏
  • 举报
回复
不错的内容!!!
姓小名白丶 2018-09-14
  • 打赏
  • 举报
回复
存文件之前 先判断你的路径(要保存的路径)存不存在, 如果不存在是否应该创建?
  • 打赏
  • 举报
回复
编程中除非刻意所谓,否则不要使用所谓“相对路径”方式。当前应用的工作路径实际上随时可能变化。如果你就是想找到相对于 APPDomain 路径的某个路径,那么直接按照绝对路径写代码,例如
file = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "配置文件.ini");

或者
var file = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "files", "学校考试.xlsx");
这类,你自己控制路径,而不要去猜结果。
shootme007 2018-09-14
  • 打赏
  • 举报
回复
没碰到过类似问题,参考一下。
weixin_43202216 2018-09-14
  • 打赏
  • 举报
回复
不错的内容!!!
Paddi_z 2018-09-14
  • 打赏
  • 举报
回复
具体可以看17#与19#我发的截图,保证两次调试的操作完全一致,没有添加或者删改代码。
Paddi_z 2018-09-14
  • 打赏
  • 举报
回复
问题仍然没有解决,不过尝试重装VS、重建工程后错误似乎没有再出现过了。不过我还是想阐述清楚我所遇到的错误,因为我感觉回帖中大部分人都仅仅看到了表面上的报错(目录不存在或者文件不存在),虽然正常情况确实如此,但我这个的的确确是真实存在的。 在使用FileStream方法传入文件路径时,使用System.Window.Forms.Application.StartupPath+@"\Dit\xx.txt"或直接使用@"Dit\xx.txt"构建文件路径,偶尔(可遇不可求)会出现复合路径中自动添加某一级文件夹(本问题中为fe(原File目录)) 因此对于回帖中提示我该目录根本没有或者文件根本没有的坛友,可能我没有阐述清楚或者你断章取义了,我在此统一回复下,我可以确定不是目录不存在或者文件不存在,而是路径参数"被自动"添加了一级目录。
一粒米饭 2018-09-14
  • 打赏
  • 举报
回复
不错的内容 。。
yingyangliabc 2018-09-14
  • 打赏
  • 举报
回复
路过看看,参考一下。
qq_40365587 2018-09-14
  • 打赏
  • 举报
回复
本地目录的绝对直径不对。
weixin_43194850 2018-09-13
  • 打赏
  • 举报
回复
是没文件夹,不是没文件
Paddi_z 2018-09-13
  • 打赏
  • 举报
回复
        public bool loadComponent()
        {
            DataTable satResult = 地址属性库.SatisfactionResult;
            try
            {
                string date = Application.Current.Resources["HandleDate"].ToString();
                DataRow dr = satResult.NewRow();
                dr["时间"] = date;
                var allsa = CalculateSatisfactionDegree("All");
                dr["全局满意度"] = allsa;

                string opdate = ProcessingDataFunction.DateTrans(date);
                DataTable csvdt = CSVHelper.OpenCSV(@"fe\data.csv");
                var querycsv = csvdt.AsEnumerable().Where(x => x["date"].ToString() == opdate);
                if (querycsv.Count()==0)
                {
                    DataRow csvdr = csvdt.NewRow();
                    csvdr["date"] = opdate;
                    csvdr["score"] = allsa.ToString("f2");
                    csvdt.Rows.Add(csvdr);
                }
                else
                {
                    foreach (var qcsv in querycsv)
                    {
                        qcsv["score"] = allsa.ToString("f2");
                    }
                }
                CSVHelper.SaveCSV(csvdt, AppDomain.CurrentDomain.BaseDirectory+@"fe\data.csv");
                for (int i = 0; i < 地址属性库.CompanyID.Count; i++)
                {
                    dr[地址属性库.CompanyID[i]] = CalculateSatisfactionDegree(地址属性库.companyName[i]);
                }
                satResult.Rows.Add(dr);
                //去重
                DataTable stresult = satResult.DefaultView.ToTable(true);
                DataTable result = stresult.Clone();
                for (int i = 0; i < stresult.Rows.Count; i++)
                {
                    if (result.AsEnumerable().Where(x=>x["时间"].ToString()==stresult.Rows[i]["时间"].ToString()).Count()>0)
                    {
                        continue;
                    }
                    var query = stresult.AsEnumerable().Where(x => x["时间"].ToString() == 地址属性库.SatisfactionResult.Rows[i]["时间"].ToString());
                    if (query.Count()>=2)
                    {
                        result.Rows.Add(query.Last().ItemArray);
                    }
                    else
                    {
                        result.Rows.Add(stresult.Rows[i].ItemArray);
                    }
                }
                地址属性库.SatisfactionResult = result;
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
其中在运行至调用OpenCSV方法时可能会出现错误。
        public static DataTable OpenCSV(string fileName = "")
        {
            if (fileName=="")
            {
                MessageBox.Show("目标CSV文件不存在,请手动选择数据文件.");
                System.Windows.Forms.OpenFileDialog ofd = new System.Windows.Forms.OpenFileDialog();
                ofd.Filter = "CSV文件(*.csv)|*.csv";
                ofd.DefaultExt = "csv";
                if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    fileName = ofd.FileName;
                    return OpenCSV(fileName, 0, 0, 0, 0, true);
                }
                else
                {
                    return null;
                }
            }
            else
            {
                return OpenCSV(fileName, 0, 0, 0, 0, true);
            }
        }

        /// <summary>
        /// 打开CSV 文件
        /// </summary>
        /// <param name="fileName">文件全名</param>
        /// <param name="firstRow">开始行</param>
        /// <param name="firstColumn">开始列</param>
        /// <param name="getRows">获取多少行</param>
        /// <param name="getColumns">获取多少列</param>
        /// <param name="haveTitleRow">是有标题行</param>
        /// <returns>DataTable</returns>
        public static DataTable OpenCSV(string fullFileName, Int16 firstRow = 0, Int16 firstColumn = 0, Int16 getRows = 0, Int16 getColumns = 0, bool haveTitleRow = true)
        {
            DataTable dt = new DataTable();
            FileStream fs = new FileStream(fullFileName, System.IO.FileMode.Open, System.IO.FileAccess.Read);
            StreamReader sr = new StreamReader(fs, System.Text.Encoding.Default);
            //记录每次读取的一行记录
            string strLine = "";
            //记录每行记录中的各字段内容
            string[] aryLine;
            //标示列数
            int columnCount = 0;
            //是否已建立了表的字段
            bool bCreateTableColumns = false;
            //第几行
            int iRow = 1;

            //去除无用行
            if (firstRow > 0)
            {
                for (int i = 1; i < firstRow; i++)
                {
                    sr.ReadLine();
                }
            }

            // { ",", ".", "!", "?", ";", ":", " " };
            string[] separators = { "," };
            //逐行读取CSV中的数据
            while ((strLine = sr.ReadLine()) != null)
            {
                strLine = strLine.Trim();
                aryLine = strLine.Split(separators, System.StringSplitOptions.RemoveEmptyEntries);

                if (bCreateTableColumns == false)
                {
                    bCreateTableColumns = true;
                    columnCount = aryLine.Length;
                    //创建列
                    for (int i = firstColumn; i < (getColumns == 0 ? columnCount : firstColumn + getColumns); i++)
                    {
                        DataColumn dc
                            = new DataColumn(haveTitleRow == true ? aryLine[i] : "COL" + i.ToString());
                        dt.Columns.Add(dc);
                    }

                    bCreateTableColumns = true;

                    if (haveTitleRow == true)
                    {
                        continue;
                    }
                }


                DataRow dr = dt.NewRow();
                //for (int j = firstColumn; j < (getColumns == 0 ? columnCount : firstColumn + getColumns); j++)
                //{
                //    dr[j - firstColumn] = aryLine[j];
                //}
                for (int j = firstColumn; j < aryLine.Length; j++)
                {
                    dr[j - firstColumn] = aryLine[j];
                }
                dt.Rows.Add(dr);

                iRow = iRow + 1;
                if (getRows > 0)
                {
                    if (iRow > getRows)
                    {
                        break;
                    }
                }

            }

            sr.Close();
            fs.Close();
            return dt;
        }
2、查找全部 "SetCurrentDirectory ", 查找结果 1, 整个解决方案, "" 匹配行: 0 匹配文件数: 0 已搜索文件总数: 499
xuzuning 2018-09-13
  • 打赏
  • 举报
回复
或者你自己搜索一下相关程序文件中是否有 SetCurrentDirectory 之类的字样
xuzuning 2018-09-13
  • 打赏
  • 举报
回复
应该是你在调用前改变了工作目录
请贴出完整的相关代码(包括定义、调用),不要截图
Paddi_z 2018-09-13
  • 打赏
  • 举报
回复
引用 16 楼 xuzuning 的回复:
计算机不会无中生有的给你添加一级 File 目录 ../Debug/File/Dit/xx.txt 显然是你计算产生的,你需要在出现这种情况时,检查产生的原因 你的程序操作的是一个动态的文件名,贴代码时不能简化为字符串常量。 你的问题实际出在组装文件名的环节,而你恰恰没有贴出来
我试过用StartupPath+@"/Dit/xx.txt"和直接用@"Dit/xx.txt"作为路径传入,但都出现了自动添加一级目录的情况。 而且我的项目下包含了2个文件夹,一个是Dit放置txt文件,一个是fe放置csv等其他类型的文件,其生成操作都是Content,在生成解决方案的时候这2个文件夹及文件都拷贝到Debug目录下,但是当问题出现的时候,自动添加一级目录的情况总是fe(此前名称为File,在出现问题后将其改名为fe,但问题依旧出现)
Paddi_z 2018-09-13
  • 打赏
  • 举报
回复
就是这样,刚刚结束调试后我立马再次启动调试(没有任何更改),上述代码又能够正常运行了。
Paddi_z 2018-09-13
  • 打赏
  • 举报
回复
刚刚调试的时候又出现了该问题,这次不再是File目录了,而变成我后改的fe目录了 在执行OpenCSV方法的时候,在执行 FileStream fs = new FileStream(fullFileName, System.IO.FileMode.Open, System.IO.FileAccess.Read); 该行的时候抛出了上述异常,fullFileName就是OpenCSV传入的参数。 —————————————————————————————————————————————— 突然发现这个异常就是在我使用FileStream时候出现的; 我刚按找异常又建了fe目录并把csv放进去,发现可以该行又能正常运行了= = 我觉得这张图可能更能清楚的表述我遇到的问题↑↑
xuzuning 2018-09-13
  • 打赏
  • 举报
回复
计算机不会无中生有的给你添加一级 File 目录
../Debug/File/Dit/xx.txt 显然是你计算产生的,你需要在出现这种情况时,检查产生的原因

你的程序操作的是一个动态的文件名,贴代码时不能简化为字符串常量。
你的问题实际出在组装文件名的环节,而你恰恰没有贴出来
加载更多回复(20)

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧