文件名 绝对路径与相对路径

EGE专栏:EGE专栏

1. 文件路径

  文件路径 是用于描述文件系统资源的一个文本标识。文件系统是对文件存储设备的空间进行组织和分配,负责文件存储并对存入的文件进行保护和检索的系统。文件存放在外部存储器中的某些位置上,经由文件系统管理后,被系统以文件路径标识,系统可以通过文件路径检索到对应文件。

1.1 DOS路径的构成

Windows 系统中的文件路径格式

在这里插入图片描述

标准的 DOS 路径可由以下三部分组成:

  • 卷号驱动器号,后跟卷分隔符 :
  • 目录名。 目录分隔符 (/\) 用来分隔嵌套目录层次结构中的子目录。
  • 可选的文件名。 目录分隔符(/\) 用来分隔文件路径和文件名。

路径写法: 驱动器号:/目录名/文件名


  ① 如果一个路径中没有文件名部分,那么此路径对应的是一个目录,如:C:/Users/Names/

  当路径是一个目录路径时,目录名称末尾中用于分隔文件名的分隔符可以省略。但是省略后会有歧义,如路径 C:/Users/Names 可能指的是 Names 文件夹,也可能是一个名为 Names的文件,无法从路径上区分是目录还是文件。此时这个路径被识别成目录还是文件依赖于对其进行的操作。

  ② 如果一个路径中有文件名部分,那么此路径对应的是一个文件, 如C:/Users/Names/file.txt


1.1.1 卷号或驱动器

  在文件资源管理器中,在此电脑目录下,我们可以看到各个驱动器,驱动器名称中带有的C:D:为驱动器号,即常说的盘符。

在这里插入图片描述

1.1.2 目录名称

  在文件资源管理器中,打开各种盘,我们可以看到里面是大量的文件夹和文件,文件夹中也嵌套包含着文件夹和文件,是一个层级结构,这个结构称为 目录树

  目录树示例如下:

在这里插入图片描述

  打开一个文件,上方地址栏即为当前所在文件夹的路径,除去盘符(如下图中的E:)后,其余部分称为目录名。下图中的目录名则为\ege\EGE20.08\include

在这里插入图片描述
  我们再次看一下这个文件夹所在目录树的结构,可以看到,目录名由到达当前位置所路经的文件夹名称 组合而成,按进入的文件夹顺序拼接,中间用目录分隔符\隔开。

在这里插入图片描述

  windows系统的中目录分隔符默认用\表示,也可以用/表示,由于在一些编程语言中(如C/C++),\在字符串中代表转义,表示原来的\字符要使用\\,这样较为麻烦,并且其它系统如Linux可能识别不了\,所以推荐使用/

1.1.3 文件名

  文件名主名扩展名 两部分组成,主名和扩展名用英文句号.隔开,即主名.扩展名。扩展名用于表示文件的类型,文件主名为用户自定义的文件名称。

在这里插入图片描述

文件名的组成部分作用备注
主名用户自定义的文件名称
扩展名表示文件的类型可省略

  扩展名是可选的,文件名可以只有主名。

  如下图所示,在图中的目录下有两个文件 index.htmreadme.md名称栏中显示的是文件夹和文件对应的名称,在 类型 栏可看到文件对应的文件类型(由扩展名确定)。

在这里插入图片描述

  如果显示的文件名称里没有显示文件扩展名,只有文件主名,可以在 查看 菜单中,勾选文件扩展名

在这里插入图片描述

  文件扩展名表示文件的类型,系统是按照文件扩展名来确定文件的类型的,当用户要打开某个文件时,如果没有指定软件,那么系统会自动选用支持该文件格式的默认应用来打开该文件(常见的文件类型一般在系统中设置有默认应用)。
  如果想用其它软件来打开某个文件,而不是使用默认应用,那么可以在右键菜单中选择 打开方式,然后在列出的软件列表中选择,如果列表中没有想要的软件,可以点击列表最下面的 选择其它应用 ,让系统找出所有关联到这个文件格式的软件。

在这里插入图片描述
  如果列表中还是没找到对应的软件,可点击 更多应用 ,然后再点击 在这台电脑上查找其它应用,手动在文件资源管理器中选择软件的位置。
在这里插入图片描述
在这里插入图片描述

  文件的扩展名可以随意命名,甚至可以没有。但是因为扩展名关联着文件的格式,当扩展名和文件类型对不上时(或者文件本身没有扩展名),有可能会因为无法识别文件格式从而导致文件不可用(系统找不到能打开扩展名对应类型的软件,或者指定软件打开时,软件无法根据内容识别其真正格式,造成数据错乱等)。(可以对文件重命名,重新把扩展名修改回去)
  如果确定是文本文件,可以用 Notepad++,记事本等文本编辑器打开,这些软件会按照文本文件的格式来识别文件内容。

  一些软件会根据文件内容识别文件格式,即使扩展名和文件实际的类型不符,也能正确打开。

在这里插入图片描述

  以下为常见文件类型对应的扩展名:

文件类型扩展名
文本文件txt
MP3音乐文件mp3
MP4视频文件mp4
JPEG格式图片文件jpg
PNG格式图片文件png
C源程序文件c
C++源程序文件cpp
C/C++头文件h

1.2 当前目录 (Current directory)

  在命令行中,可以看到在每行输入的开头都显示着一个路径,这个路径和输入之间用一个交互提示符 > 隔开。

在这里插入图片描述

  这个路径即为命令行的当前目录,也叫 工作目录(Working directory)当前路径(Current path)

  在windows 的命令行中,交互提示符为右尖括号 >

  如下图所示,当前目录为 C:Users\19078

在这里插入图片描述

  程序运行时,会把某个目录设定为程序的当前目录。如果在存储、读取文件时没有指定文件所在的目录,那么将认为文件是放置在当前目录中。

程序中当前目录的获取

  在程序中,当前目录可以使用 <stdlib.h> 中的 getcwd() 函数,<Windows.h> 中的 GetCurrentDirectory() 函数等获取。
  下面的程序会读取当前目录并输出到控制台窗口。

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

int main(int argc, char* argv[])
{
	// 调用getcwd()函数获取,getcwd()被弃用,换成_getcwd()
	//如果buffer传入NULL,则内部动态分配内存,需要调用者自行释放
	char* cwd = _getcwd(NULL, MAX_PATH);
	
	
	//使用 GetCurrentDirectory() 函数获取
	TCHAR CurrentDirectory[MAX_PATH];
	GetCurrentDirectory(MAX_PATH, CurrentDirectory);
	
	//输出当前路径
	puts(cwd);
	//释放内存
	free(cwd);
	
	return 0;
}

1.3 切换盘符(驱动器跳转)

命令示例
切换盘符盘符:切换到D盘:D:

  如下所示,当前位于C盘,如果想要切换到其它盘符,可通过输入 盘符: 来进行切换。

在这里插入图片描述

  例如,使用命令E:可切换到 E盘。如果想要再次切换回C盘,输入C:即可。

  盘符由一个英文字母(不区分大小写)和一个冒号 : 组成。

在这里插入图片描述

  切换到另一个盘符时,其实是跳转到对应驱动器下的当前目录(每个驱动器都有各自的当前目录),所以在上图可以看到,切换回C盘时,并不是跳转到 C:\目录,而且跳转到C盘的当前目录中。

1.4 设置当前目录

  当前目录有多种不同的含义,如命令行下的驱动器的当前目录、进程的当前目录等,作为路径的一个参考位置。

1.4.1 驱动器的当前目录

  Windows下,每个驱动器都有自己的当前目录,跳转到其它驱动器后,其实跳转到其对应的当前目录上,如下图所示,跳转到其它驱动器后再跳转回C盘,依然是回到C盘的当前目录上。

在这里插入图片描述

  在windows命令行下,可以使用 cd命令改变驱动器的当前目录,例如 cd 驱动器号:/目录名。如果目录路径中包含了驱动器号,那么会改变指定驱动器的当前目录,如果没有驱动器号,则改变当前驱动器的当前目录。

微软文档:cd 命令

  cd 命令的全称是 Change Directory,也可以写作 chdir,使用 cd 目录路径 命令只能设置对应跨盘符跳转,只能在当前盘符内跳转,要跳转到其它盘符的目录,需要先切换到对应盘符后,再用 cd 命令跳转。

  下图中,当前目录位于C盘下。在命令 cd \Users\19078\Desktop 中,所要跳转的目标目录路径并没有包含驱动器号,那么意思就是设置当前驱动器的当前目录为 \Users\19078\Desktop 目录,设置后可以看到C盘的当前目录已经改变。再用 cd 命令设置E盘的当前目录,可以看到当前仍在C盘,切换到E盘后,可以看到E盘的当前目录已经修改成功。

在这里插入图片描述

如何查看各驱动器的当前目录

  跳转到对应驱动器后就可以查看它的当前目录,除此之外,还可以用 cd 驱动器号: 命令进行查看,该命令会输出对应驱动器的当前目录。

在这里插入图片描述

1.4.2 进程的当前目录

  启动一个程序时会开启一个进程,一个进程的当前目录默认是应用程序启动的目录,但启动时很有可能被更改。

  例如,如果是在命令行下输入exe可执行文件的路径来启动应用程序,那么程序运行后,进程的当前目录是命令行的当前目录。
  如果在文件资源管理器中打开可执行文件所在的目录,双击运行,此时进程的当前目录是可执行文件所在的目录。如果是经由其它文件搜索软件搜索后打开,当前目录需要看软件是如何调用的程序。

1.4.2.1 程序中设置当前目录

  可以在程序中调用 SetCurrentDirectory() 函数来设置当前进程的当前目录。

  一般是设置成exe可执行文件所在的位置。这个路径可以从main()函数的参数中获取。

#include <Windows.h>
SetCurrentDirectory("目录路径")

1.5 路径跳转

命令
  路径跳转一共需要两步,分别是盘符:命令切换盘符 和 cd 目录路径设置当前目录。
  ① 使用 盘符: 命令切换盘符。
  ② 使用 cd 路径 命令跳转到对应路径上。

  当目标目录位于当前驱动器时,不需要切换盘符。

操作示例
  如下图所示,打开命令行后,当前目录默认为用户目录:
  1. 输入cd Desktop 跳转到当前目录下的Desktop子目录中(这种路径写法我们称为相对路径)。
  2. 输入 cd C:\Users 跳转到 C:\Users目录下。
  3. 输入 E: 切换到E盘。
  4. 输入 cd E:\ege\EGE20.08 跳转到 E盘中的 E:\ege\EGE20.08 目录下

在这里插入图片描述

1.6 根目录 (Root directory)

  根目录即直接位于驱动器中最顶层的目录,不被其它目录所包含,路径为 盘符:\,如C盘根目录 C:\, D盘根目录 D:\
  要跳转到根目录下,输入 cd \ 即可。

在这里插入图片描述

1.7 当前目录与上一级目录的符号表示

  命令行用句号 .表示当前目录,用两个句号..表示上一级目录。

目录符号
当前目录.
上一级目录..

  如下图所示,当前目录为 E:\ege\EGE20.08,输入cd .. 后会跳转到当前目录的上一级目录,即E:\ege

在这里插入图片描述

  这些符号可以插入到路径之中。
  如E:\ege\EGE20.08\.. 表示 E:\ege\EGE20.08 的上一级目录,即 E:\ege,而E:\ege\..\ege\EGE20.08则表示 E:\ege\的上一级目录的ege\EGE20.08 子目录下,即 E:\ege\EGE20.08
  .\ege表示当前目录下的ege子目录。

1.8 分割路径(Split Path)

  <stdlib.h> 头文件中的 _splitpath() 函数可以对一个路径进行分割,分割成驱动器号、目录名、文件主名和文件扩展名四个部分。
  需要注意的是,为了区分一个路径是文件还是目录,目录路径中目录名后的目录分隔符不可省略,即使没有文件名,如 C:/Users/

微软参考文档:_splitpath, _wsplitpath

#include <stdlib.h>

const char* fullPath = "C:/dir/file.txt";
char drive[_MAX_DRIVE], dir[_MAX_DIR], fileName[_MAX_FNAME], ext[_MAX_EXT];

_splitpath(argv[0], drive, dir, fileName, ext);

1.9 构造路径

  <stdlib.h> 头文件中的 _makepath() 函数可以将驱动器号,目录名,文件主名,文件扩展名这些其中几个部分组合成一个路径。

微软参考文档:_makepath、_wmakepath

#include <stdlib.h>

char path[_MAX_PATH];
_makepath(path, "盘符:", "目录名", "文件主名", "文件扩展名");

1.10 全路径(Full Path)

  <stdlib.h> 中的 _fullpath 可以计算出一个路径对应的全路径。当给出的路径是相对路径时,函数会根据进程的当前路径来计算出对应的全路径。

微软参考文档:_fullpath, _wfullpath

#include <stdlib.h>
#include <stdio.h>

int main()
{
	//内部自动分配内存,返回字符串首地址,需要调用者自行释放内存
	char* fullPathName = _fullpath(NULL, "file.txt", MAX_PATH);

	//输出
	puts(fullPathName);

	//释放内存
	free(fullPathName);
	return 0;
}	

2. 绝对路径与相对路径

2.1 绝对路径与相对路径的区分

  如果在一个路径中,包含了驱动器号(或卷号)和 目录名,并且目录名以目录分隔符(\/) 开头,那么这个路径称为 绝对路径(Absolute path)。如果绝对路径中包含了文件名,那么则称其为 文件的绝对路径

  在一个文件系统中,绝对路径对应着一个明确、唯一且固定的文件或目录,也称为 完整路径全路径

在这里插入图片描述

  如果一个路径未指定卷号或驱动器号, 或者目录名不以分隔符开头,那么这种路径称之相对路径

  相对路径无法直接确定一个唯一的且固定的文件或目录,随着当前目录当前驱动器变化。

  相对路径中,是否指定卷号或驱动器号,和目录名是否以分隔符开头,所得到的路径含义不同:

  • 未指定驱动器号表示路径位于当前驱动器
  • 目录名不以分隔符开头表示路径相对于当前目录,否则表示路径相对于驱动器根目录。

列表如下:

驱动器号含义目录名是否以目录分隔符开头含义
相对于指定的驱动器相对于根目录
相对于当前的驱动器相对于当前目录
路径示例

  假设C盘的当前目录为C:\Users, E盘的当前目录为 E:\ege,切换到了E盘,即当前驱动器为 E:

驱动器号是否指定目录名是否以目录分隔符开头含义路径性质示例实际路径
相对于指定驱动器的根目录,是明确、唯一且固定的绝对路径C:\UsersC:\Users
相对于当前驱动器的根目录相对路径\UsersE:\Users
相对于指定驱动器的当前目录相对路径C:UsersC:\Users\Users
相对于当前驱动器当前目录相对路径UsersE:\ege\Users

2.2 相对路径的使用

  相对路径指的是文件或目录与当前目录的相对位置,只要保证文件和当前目录的相对位置不变,那就能通过相对路径正确索引到对应的文件或目录,这带来的好处是文件不需要存放在固定的目录下。

  将可执行文件及其所需的资源打包好后,由于可执行文件与其它资源文件相对位置没有改变,所以解压到计算机的任意位置后,运行可执行文件能够通过相对路径正确地读取到文件。

  当前目录用. 表示,如果一个名为directory目录在当前目录下,那么这个目录的相对路径为 ./directory,文件同理,若当前目录下有一个名为 file.txt 的文件,则文件的相对路径为 ./file.txt。通常 ./可以省略,所以可以直接简写为 directoryfile.txt

2.3 文件路径的确定

2.3.1 绝对路径的确定

  一个文件的绝对路径,可以打开其所在的文件夹,在地址栏查看其所在目录的路径,绝对路径由所在目录路径和文件名拼接而成,目录和文件名之间用分隔符隔开。
  如下所示,ege.h 文件所在目录的路径为 E:\ege\EGE20.08\include,则文件 ege.h的绝对路径为 E:\ege\EGE20.08\include\ege.h
在这里插入图片描述

  快捷键Shift + 鼠标右键,选择复制文件地址,即可复制文件的绝对路径。
在这里插入图片描述
  还可以右键选择属性,在安全选项卡中查看。

在这里插入图片描述

2.3.2 相对路径的确定

  相对路径首先需要知道当前目录相对路径是相对于当前目录的位置,那么在运行程序时,这个当前目录是什么呢?
  一般情况下,如果你直接到exe可执行文件所在的目录里 运行exe文件,那么当前目录就是 exe文件所在的目录。如果你通过集成开发环境调试运行程序, 那么这个当前目录就是工程中的源文件所在目录(因为在项目中创建源文件时,就是在项目的当前目录创建的)。
  如果是其它地方启动的应用程序,则需要根据实际情况来分析,有可能是启动应用程序时当前所在目录,但不确定。

2.3.2.1 当前目录的获取

  在不确定当前目录的情况下,可以通过在程序中加入一些读取当前目录的代码来查看。

#include <direct.h>
#include <stdio.h>

int main()
{
	//获取当前路径,getcwd()在VS下被弃用,换成了_getcwd()
	char* curWorkDirectory = _getcwd(NULL, MAX_PATH);
	puts(curWorkDirectory);
	
	free(curWorkDirectory);
	
	return 0;
}
2.3.2.3 集成开发环境中调试运行

  假设我们的程序是在集成开发环境中调试运行,那么当前目录应该是源文件所在的目录(如果源文件是在项目中新建的话)。在下面的图中,所圈的图片和 源文件main.cpp 在同一目录下, 那么用相对路径来表示这个图片那就是 ./girl.jpg, 用一个英文句号来表示当前目录因为是在同一目录下,可以省略掉路径,最后简写成 girl.jpg

在这里插入图片描述

在这里插入图片描述

  如果与源文件同目录下有个res文件夹, 而里面有张 girl2,jpg 的图片,那对应位置就是在当前目录的res文件夹中,表示成 ./res/girl2.jpg, 当前路径部分可以省略,简写作 res/gir2.jpg

在这里插入图片描述
在这里插入图片描述

  如果这个res文件是放在上一层目录中,对应文件的路径为 ../res/gril2.jpg,如果是在上上层则为 ../../res/girl2.jpg

在这里插入图片描述

2.3.2.4 直接双击可执行文件运行程序

  直接双击exe可执行文件运行程序时,当前目录就是可执行文件所在的目录。相对路径的计算方式不变。

在这里插入图片描述

  在文件打包时,或者改变程序运行方式时(从集成开发环境中调试运行转到直接双击可执行文件运行),之前能读取到的文件突然无法读取了。出现这种情况时,如果文件位置没有移动,那很有可能是当前路径发生了改变,根据原来的相对路径是找不到文件的。可以通过以下方法解决:

  • 可以根据相对路径,把用到的文件复制到对应的位置上。
  • 或者通过改变当前目录的方式,移动可执行文件到合适的位置上。

2.4 使用相对路径无法正确读取到文件的情况

  这种情况下如果排除了文件格式错误、库内部问题等因素,那很有可能是相对路径不正确。如果之前可以读取,换成某种方式运行程序就无法读取,那可能是当前目录发生了变化。
  可以在程序将相对路径转成全路径并输出,然后和文件的全路径进行比较,以此来检查路径问题。

#include <stdlib.h>
#include <stdio.h>

int main()
{
	char* fullPathName = _fullpath(NULL, "Path", MAX_PATH);
	puts(fullPathName);
	free(fullPathName);
	return 0;
}

EGE专栏:EGE专栏

  • 22
    点赞
  • 75
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

依稀_yixy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值