精华内容
下载资源
问答
  • 在java中,创建一个文件其实很简单,但是你知道文件名中能含有哪些字符吗?如果不了解,也许你该看看这篇文章。文章主要内容:1.文件名中不能有哪些字符?2.创建文件时,如何进行判断?3.如何替换文件名'字符串中的...


    1.文件名中不能有哪些字符?

    在Windows系统创建文件,其名字是由限制的,至于有哪些限制,在你违规时,它就会提醒你,就像这样:
    文件夹名限制
    当你创建文件时,输入图中所含(英文格式)字符时,它就会弹出这个提示框。

    推荐阅读:在文件名中千万不要使用这些字符!

    2.创建文件时,如何进行判断?

    但是我们在编程过程中,如果需要批量创建文件,创建失败但是如果你判断就不会有提示:
    boolean file.mkdir()

    		File dirFile = new File(dirPath);
    		if (!dirFile.exists()) {
    			if (dirFile.mkdir()) {
    				System.out.println("创建文件夹:" + dirPath + " 成功");
    				reslut = 1;
    			} else {
    				System.err.println("创建文件夹:" + dirPath + " 失败");
    				reslut = -1;
    			}
    		} else {
    			System.out.println("文件夹:" + dirPath + " 已存在");
    			reslut = 0;
    		}
    		return reslut;
    

    3.如何替换文件名’字符串中的特殊字符?

    那么如何替换其中的特殊字符呢?

    public static String replaceSpecialCharacters(String dirPath) {
    
    		/*
    		 * windows下文件名中不能含有:\ / : * ? " < > | 英文的这些字符 ,这里使用"."、"'"进行替换。
    		 * \/:?| 用.替换
    		 * "<> 用'替换
    		 */
    		dirPath = dirPath.replaceAll("[/\\\\:*?|]", ".");
    		dirPath = dirPath.replaceAll("[\"<>]", "'");
    
    		return dirPath;
    	}
    

    修改时间:2019年9月5日19:19:17

    4.(很重要的)补充:

    之前我以为这些规则只是针对文件夹的,但是后面发现对于普通文件同样适用,文章中可能有部分内容没有修改过来,因此这里统一说明:这些规则对文件夹和文件都适用


    可参考:在文件名中千万不要使用这些字符!

    展开全文
  • 文件描述与进程描述

    千次阅读 2014-04-25 15:15:05
    Linux系统可以看成是一个由文件组成的系统,在linux系统中,基本上所有的设备,硬件,资源都被看成一个文件,比如,在/dev下面我们可以看到我们的硬盘sda1(我的机器是安装的SCIS硬盘的虚拟机),终端设备ttyn,在/...

    Linux系统可以看成是一个由文件组成的系统,在linux系统中,基本上所有的设备,硬件,资源都被看成一个文件,比如,在/dev下面我们可以看到我们的硬盘sda1(我的机器是安装的SCIS硬盘的虚拟机),终端设备ttyn,在/proc目录下面我们可以看到当前的内存信息,cat/proc/meminfo,可以查看CPU的信息: cat /proc/cpuinfo, 这些文件都是被linux系统抽象成了一个个的文件,通过对文件的操作来,对具体的硬件操作。

           对一个文件的操作可以分为,打开, 读取,写入,关闭等,因此我们对硬件设备文件的操作也抽象成了,对其文件的读取,写入,比如:我们要打印一个字符串到屏幕上,在Linux里面屏幕这个硬件被抽象成了一个文件,我们可以通过往那个文件里面写入字符串,来实现打印。再比如现在有一个串口,他要和其它的一个PC通过串口通信,这个串口在系统里也被抽象成了一个文件,我们可以通过从文件读来取出串口上发过来的数据,通过写入,来向另外一个PC发送数据。看下面的程序:

            #include <stdio.h>

      #include<unistd.h>

      int main(void)

      {

              if(write(STDOUT_FILENO,"hello world", 11) < 0)

                       perror("write");

              return0;

      }

    上一节已经讲过这个例子,它就是向STDOUT_FILENO这个文件里面写入helloworld 这11个字符,这个STDOUT_FILENO是什么东西呢?我们先找到它的定义再说,

    grep –R ’STDOU_FILENO’ /usr/include/

    上面的命令就是在/usr/include/这个目录及其子目录里的文件里查找含有STDOUT_FILENO这个字符串的行,找到就打印出来,我们来看结果

    只有在条,通过后面的注释可以看出,这个宏定义表示的是标准输出,也就是屏幕,那它为什么是1呢。我们引出了下面的术语,文件描述符(Filedescriotor)

    对于内核而言,所有打开文件都由文件描述符引用。文件描述符是一个非负整数。当打开一个现存文件或创建一个新文件时,内核向进程返回一个文件描述符。当读、写一个文件时,用open或creat返回的文件描述符标识该文件,将其作为参数传送给read或write。

    有三个特殊的文件描述符,每个进程在创建时,都默认打开三个文件描述符。

    standard input(0), standard output(1), standarderror(2)

    上面的STDOUT_FILENO就是标准输出文件描述符,它和我们标准C库里的文件指针很相似,只是相似,完全不一样(后面我们有例子来分析两个的不相同之处)。

           其实如果你分析了内核的源码后会发现,文件描述符,其实是当前程序打开文件结构数组的下标,当一个程序启动时,系统默认的让他打开了三个文件,就是标准输入,标准输出,标准错误输出,它们的在打开文件结构数据的下标就是0,1,2,因此,如果我的程序再打开一个新的文件,那么应该这个下标(文件描述符)就应该是3,下面我们证明下。

    #include <stdio.h>

    #include <fcntl.h>

    int main(void)

    {

            intfd;

            fd= open("/tmp/tmp.txt", O_RDONLY);

            printf("fd:%d/n",fd);

            return0;

    }

    下面是执行的结果:

     

    因此我们的猜测是正确的。看下图左边的用户文件描述符表,其实就是当前程序打开的文件的一个数组,其文件描述符就是其下标。

     

    注意下标准输入,标准输出,标准错误输出这三个描述符的定义在<unistd.h>

    头文件中,我们可以通过grep来找出来,具体用法见前面。

    文件描述符的范围是0 ~ OPEN_MAX 。早期的UNIX版本采用的上限值是1 9(允许每个进程打开20个文件),现在很多系统则将其增加至256。这个好理解,一个程序不可能无休止的打开文件,有个限制,这个限制每个系统可能都不太一样,要是想查看你自己系统的最大打开文件数,也就是文件描述符范围,也用grep去找一个OPEN_MAX这个字符串。

    open函数

    前面一直有提到这个函数,看其字面意思就是打开一文件的意思。下面看它的具体用法。

    #include <sys/types.h>

    #include <sys/stat.h>

    #include <fcntl.h>

    int open(const char *pathname, int oflag);

    int open(const char *pathname, int oflag, mode_t mode) ;

    功能:打开文件

    返回值:若成功为文件描述符,若出错为- 1 (与fopen区别开NULL,因为他返回的是FILE指针)

    pathname是要打开或创建的文件的名字。

    oflag参数可用来说明此函数的多个选择项。

    对于open函数而言,仅当创建新文件时才使用第三个参数。

    用下列一个或多个常数进行或运算构成oflag参数(这些常数定义在<fcntl.h>头文件中):

    O_RDONLY 只读打开。  (互斥)

                 O_WRONLY 只写打开。 (互斥)

    O_RDWR 读、写打开。   (互斥)

    O_APPEND 每次写时都加到文件的尾端。

    O_CREAT 若此文件不存在则创建它。使用此选择项时,需同时说明第三个参数mode,用其说明该新文件的存取许可权位。

    O_EXCL 如果同时指定了O_CREAT,而文件已经存在,则出错。这可测试一个文件是否存在,如果不存在则创建此文件成为一个原子操作。

    O_TRUNC 如果此文件存在,则将其长度截短为0。

    O_NOCTTY 如果pathname指的是终端设备,则不将此设备分配作为此进程的控制终端。

    O_NONBLOCK 如果pathname指的是一个FIFO、一个块特殊文件或一个字符特殊文件,则此选择项为此文件的本次打开操作和后续的I/ O操作设置非阻塞方式。

    O_SYNC 使每次write都等到物理I / O操作完成。

     

    上面三个头文件是用open这个系统调用时用到的从这儿也能区分出标准C和系统调用的区别,头文件不一样。

           mode对应的文件权限宏:

    S _ IS U ID          执行时设置-用户-I D

    S _ IS G ID          执行时设置-组-I D

    S _ IS V TX         保存正文

    S _IRWXU           用户(所有者)读、写和执行

    S _ IRSR              用户(所有者)读

    S _IWUSR            用户(所有者)写

    S _IXUSR            用户(所有者)执行

    S _IRWXG           组读、写和执行

    S _IRGRP             组读

    S _IWGRP            组写

    S _IXGRP            组执行

    S _IRWXO           其他读、写和执行

    S _IROTH            其他读

    S _ IWOTH          其他写

    S _ IXOTH           其他执行

    Open不仅可以打开一个文件,也可以去创建一个文件,这一点要注意下,其实在系统调用函数里面,还有一个真正的创建文件调用函数,creat函数。

    #include <sys/types.h>

    #include <sys/stat.h>

    #include <fcntl.h>

    int creat(const char * pathname, mode_t mode) ;

    功能:创建一个新的文件。

    返回值:若成功为只写打开的文件描述符,若出错为- 1。

    注意,此函数等效于:

    open (pathname, O_WRONLY | O_CREAT | O_TRUNC, mode) ;

    creat的一个不足之处是它以只写方式打开所创建的文件不能读

    read函数

    #include <unistd.h>

    ssize_t read(int fd, void *buf, size_t count);

    功能: 从打开文件中读数据

    返回:读到的字节数,读不到字节返回0,若count 为0返回0,若出错为- 1。

    有多种情况可使实际读到的字节数少于要求读字节数:

    —        读普通文件时,在读到要求字节数之前已到达了文件尾端。例如,若在到达文件尾端之前还有30个字节,而要求读1 0 0个字节,则read返回3 0,下一次再调用read时,它将返回0 (文件尾端)。

    —        当从终端设备读时,通常以行为单位,读到换行符就返回。

    —        当从网络读时,网络中的缓冲机构可能造成返回值小于所要求读的字节数。

    —        读操作从文件的当前位移量处开始,在成功返回之前,该位移量增加实际读得的字节数。

    wirte函数

    #include <unistd.h>

    ssize_t write(int fd, const void *buf, size_t count);

    功能;向打开文件写数据。

    返回:若成功为已写的字节数,若出错为- 1。

    其返回值通常与参数count的值不同,否则表示出错。write出错的一个常见原因是:磁盘已写满,或者超过了对一个给定进程的文件长度限制。

     

    对于普通文件,写操作从文件的当前位移量处开始。如果在打开该文件时,指定了O_APPEND选择项,则在每次写操作之前,将文件位移量设置在文件的当前结尾处。在一次成功写之后,该文件位移量增加实际写的字节数。

    lseek函数

     

    每个打开文件都有一个与其相关联的“当前文件偏移量”。它是一个非负整数,用以度量从文件开始处计算的字节数。通常,读、写操作都从当前文件偏移量处开始,并使偏移量增加所读或写的字节数。按系统默认,当打开一个文件时,除非指定O_APPEND选择项,否则该位移量被设置为0。

    #include <sys/types.h>

    #include <unistd.h>

    off_t lseek(int filesdes, off_t offset, int whence) ;

    功能:设置文件内容读写位置

    返回:若成功为新的文件位移,若出错为- 1。

    对参数offset 的解释与参数whence的值有关。

    —        若whence是SEEK_SET,则将该文件的文件位移指针设置为距文件开始处offset 个字节。如果offset是0,就是回到文件首,返回值是0

    —        若whence是SEEK_CUR ,则将该文件的位移量设置为其当前值加offset,offset可为正或负。如果offset是0,就是返回当前文件位移指针位置。

    —        若whence是SEEK_END ,则将该文件的文件位移指针设置为文件长度加offset,offset可为正或负。如果offset是0,就是返回当前文件位移尾指针位置。

    注意:

    可以调用lseek显式地定位一个打开文件。

    lseek仅记录当前文件的偏移量,而不会对文件进行I/O操作。

    lseek的偏移量可以超过当前文件的字节总数,从而在文件中产生一个hole

    看下面的例子:

          #include <sys/types.h>

           #include<unistd.h>

           #include<stdlib.h>

           #include<sys/stat.h>

           #include<fcntl.h>

           charbuf1[] = "0123456789";

           charbuf2[] = "ABCDEFGHIJ";

           intmain(void)

           {

                   intfd;

                   if((fd= creat("file.hole", O_RDWR | O_APPEND)) < 0)

                           perror("Createrror");

                   if(write(fd,buf1, 10) != 10)

                           perror("buf1write error");

                   if(lseek(fd,30, SEEK_CUR) == -1)

                           perror("lseekerror");

                   if(write(fd,buf2, 10) != 10)

                           perror("buf2write error");

                   exit(0);

           }

       先创建一个新文件file.hole,然后写入10个字节,再用lseek向后移动文件位置指针30个字节,这样,中间的这30个字节就是没有任何数据的,然后在当前文件位置指针处写入10个字节。这样就产生了一个文件空洞。我们来看下它占有多少磁盘空间。

     

    我们通过ls–hl 命令可以看到它占有50个字节的磁盘空间,通过od命令(以8进制形式查看文件内容)看出,中间30个字节是0,而我们用cat命令来查看,中间的30个字节没有显示出来。这说明,空洞文件是产生了,中间的30个字节是不可见字符,没有被显示出来,而其在硬盘里面却真正的占用了30个字节。

     

    close函数

    #include <unistd.h>

    int close (int filedes);

    功能:关闭一个打开文件

    返回:若成功为0,若出错为- 1

    当一个进程终止时,它所有的打开文件都由内核自动关闭。很多程序都使用这一功能而不显式地用close关闭打开的文件。

    上面几个系统调用的函数在我们的标准C里基本上都有对应的函数实现,比如fope对应open, fclose对应close,fread对应read, fwrite对应wirte。

           下面再看本节最后一个例子,标准C,与系统调用的区别:

    #include <stdio.h>

    #include <fcntl.h>

    #include <errno.h>

    int main(void)

    {

            

            intfd;

            fd= open("noexit.txt", O_RDONLY);

            perror("open");

            printf("fd:%d/n",fd);

            printf("errno:%d/n",errno);

     

            

            FILE* fp;

            fp= fopen("noexit.txt", "r");

            perror("fopen");

            printf("fp:%d/n",fp);

            printf("errno:%d/n",errno);

            return0;

    }

    分别用标准C的库fopen和系统调用的open打开两个相同的文件,这个文件在我这儿是不存在的,分别打印出它们的出错信息和出错号,和它们的文件描述符和文件指针。下面是结果;

     

     

    系统调用open打开出错返回-1,而fopen返回类型是指针,因此返回是NULL,其类型是(void*)0,也就是0, 注意它们的出错信息,和错误号,都是一样的,因为标准C的函数最终也是调用的系统调用实现其功能的。


    展开全文
  • 彻底弄懂 Linux 下的文件描述(fd)

    千次阅读 多人点赞 2020-08-14 17:01:52
    Linux下 文件描述(fd)

    目录

    1、从一个最常见的例子说起

    2、Linux中的文件描述符(file descriptor)

    3、Linux上打开文件举例

    4、C语言中文件描述符的使用

    5、Python中文件描述符的使用

    6、Linux配置系统最大打开文件描述符个数

    7、参考链接


    1、从一个最常见的例子说起

    在使用Linux的过程中, 我们平时经常看到下面这样的用法:

    echo log > /dev/null 2>&1
    •  :表示将输出结果重定向到哪里,例如:echo "123" > /home/123.txt
    • /dev/null :表示空设备文件

    所以 echo log > /dev/null 表示把日志输出到空文件设备,也就是将打印信息丢弃掉,屏幕上什么也不显示。

    •  :表示stdout标准输出
    •  :表示stderr标准错误
    •  :表示等同于的意思

    所以  2>&1 表示2的输出重定向等同于1,也就是标准错误输出重定向到标准输出。因为前面标准输出已经重定向到了空设备文件,所以标准错误输出也重定向到空设备文件。

    这个用法平时很常见,重点是为什么这里是用 和 1 ,不是3456什么的呢?这要从 Linux 中的文件描述符说起。

    2、Linux中的文件描述符(file descriptor)

     我们知道在Linux系统中一切皆可以看成是文件,文件又可分为:普通文件、目录文件、链接文件和设备文件。在操作这些所谓的文件的时候,我们每操作一次就找一次名字,这会耗费大量的时间和效率。所以Linux中规定每一个文件对应一个索引,这样要操作文件的时候,我们直接找到索引就可以对其进行操作了。

    文件描述符(file descriptor)就是内核为了高效管理这些已经被打开的文件所创建的索引,其是一个非负整数(通常是小整数),用于指代被打开的文件,所有执行I/O操作的系统调用都通过文件描述符来实现。同时还规定系统刚刚启动的时候,0是标准输入,1是标准输出,2是标准错误。这意味着如果此时去打开一个新的文件,它的文件描述符会是3,再打开一个文件文件描述符就是4......

    Linux内核对所有打开的文件有一个文件描述符表格,里面存储了每个文件描述符作为索引与一个打开文件相对应的关系,简单理解就是下图这样一个数组,文件描述符(索引)就是文件描述符表这个数组的下标,数组的内容就是指向一个个打开的文件的指针。

    上面只是简单理解,实际上关于文件描述符,Linux内核维护了3个数据结构

    • 进程级的文件描述符表
    • 系统级的打开文件描述符表
    • 文件系统的i-node表

    一个 Linux 进程启动后,会在内核空间中创建一个 PCB 控制块,PCB 内部有一个文件描述符表(File descriptor table),记录着当前进程所有可用的文件描述符,也即当前进程所有打开的文件。进程级的描述符表的每一条记录了单个进程所使用的文件描述符的相关信息,进程之间相互独立,一个进程使用了文件描述符3,另一个进程也可以用3。除了进程级的文件描述符表,系统还需要维护另外两张表:打开文件表、i-node 表。这两张表存储了每个打开文件的打开文件句柄(open file handle)。一个打开文件句柄存储了与一个打开文件相关的全部信息。

    系统级的打开文件描述符表:

    • 当前文件偏移量(调用read()和write()时更新,或使用lseek()直接修改)
    • 打开文件时的标识(open()的flags参数)
    • 文件访问模式(如调用open()时所设置的只读模式、只写模式或读写模式)
    • 与信号驱动相关的设置
    • 对该文件i-node对象的引用,即i-node 表指针

    文件系统的i-node表:

    • 文件类型(例如:常规文件、套接字或FIFO)和访问权限
    • 一个指针,指向该文件所持有的锁列表
    • 文件的各种属性,包括文件大小以及与不同类型操作相关的时间戳

    文件描述符、打开的文件句柄以及i-node之间的关系如下图:

    Linux文件描述符表示意图

    • 在进程 A 中,文件描述符 1 和 20 都指向了同一个打开文件表项,标号为 23(指向了打开文件表中下标为 23 的数组元素),这可能是通过调用 dup()、dup2()、fcntl() 或者对同一个文件多次调用了 open() 函数形成的。
    • 进程 A 的文件描述符 2 和进程 B 的文件描述符 2 都指向了同一个文件,这可能是在调用 fork() 后出现的(即进程 A、B 是父子进程关系),或者是不同的进程独自去调用 open() 函数打开了同一个文件,此时进程内部的描述符正好分配到与其他进程打开该文件的描述符一样。
    • 进程 A 的描述符 0 和进程 B 的描述符 3 分别指向不同的打开文件表项,但这些表项均指向 i-node 表的同一个条目(标号为 1976);换言之,它们指向了同一个文件。发生这种情况是因为每个进程各自对同一个文件发起了 open() 调用。同一个进程两次打开同一个文件,也会发生类似情况。 

    这就说明:同一个进程的不同文件描述符可以指向同一个文件;不同进程可以拥有相同的文件描述符;不同进程的同一个文件描述符可以指向不同的文件(一般也是这样,除了 0、1、2 这三个特殊的文件);不同进程的不同文件描述符也可以指向同一个文件。

    3、Linux上打开文件举例

    比如在Linux上用 vim test.py 打开一个文件,保持打开状态,再新打开一个新的shell,输入命令pidof vim 获取vim进程的pid号,然后 ll  /proc/$pid/fd 查看vim 进程所使用的文件描述符列表。

    /dev/pts是远程登陆(telnet,ssh等)后创建的控制台设备文件所在的目录。因为我是通过Xshell远程登录的,所以标准输入0,标准输出1,标准错误2的文件描述符都指向虚拟终端控制台 /dev/pts/6 。再看下面是新打开的 test.py 的文件描述符,竟然是4,说好的从3开始呢?

    这个我也困扰了好久,查了各种资料,终于在一个大佬的帮助下在一个论坛找到原因,有时候中文查不到还是要试试英文搜索啊。因为vim这种编辑器的原理是先打开源文件并拷贝,然后关闭源文件再打开自己的副本,修改完文件保存的时候直接将副本重命名覆盖源文件。所以打开源文件的时候用的文件描述符3,然后打开自己的副本是时候就该用文件描述符4了,然后关闭源文件,文件描述符3就被释放了,我们查看的时候就只剩下了4,这里它指向的是vim创建的副本文件。这里只是说个大概意思,具体深究要去深入了解一下 vim的实现原理——奥尔特星云大使,下面是当时我看到的论坛上的资料截图,链接在这:StackOverFlow

    如果不相信可以试一试别的进程,比如 tail。

    在Linux上用 tail -f test.py 打开一个文件,保持打开状态,再新打开一个新的shell,输入命令pidof tail 获取tail进程的pid号,然后 ll  /proc/$pid/fd 查看tail进程所使用的文件描述符列表,可以看到文件描述符确实是从3开始使用的。tail不是编辑器不存在修改文件的情况,所以直接文件描述符直接打开的源文件。实际上可以使用 ll  /proc/$pid/fd 命令获取当前运行的任意进程的文件描述符使用情况。

    4、C语言中文件描述符的使用

    C语言中可以通过 open 函数返回一个文件的文件描述符,首先创建一个 test.py 文件用于打开,然后创建一个 test.c 文件,输入下面代码保存。 编译后执行,发现新打开文件的文件描述符是3

    #include <stdio.h>
    #include <fcntl.h>
    #include <unistd.h>
    
    int main(int argc, char* argv[]) {
            int fd = open("test.py", O_RDONLY);
            if (fd == -1) {
                    return -1;
            }
            printf("test.py fd = %d \n", fd);
            close(fd);
            return 0;
    }
    

     

    5、Python中文件描述符的使用

    Python中通过 sys 模块封装了标准输入、标准输出和错误输出。通过我们平时常用的内建函数 open 可以获取一个文件的文件描述符,首先创建一个 test.py 文件用于打开,然后创建一个 test2.py 文件,输入下面代码保存。 执行,发现新打开文件的文件描述符是3

    import sys
    
    print('stdin fd = ', sys.stdin.fileno())
    print('stdout fd = ', sys.stdout.fileno())
    print('stderr fd = ', sys.stderr.fileno())
    
    with open("test.py", "w") as f:
        print('test.py fd = ', f.fileno())

    6、Linux配置系统最大打开文件描述符个数

    (1)系统级限制

    理论上系统内存有多少就可以打开多少的文件描述符,但是在实际中内核是会做相应的处理,一般最大打开文件数会是系统内存的10%(以KB来计算),称之为系统级限制。这个数字可以通过 cat /proc/sys/fs/file-max 或者 sysctl -a | grep fs.file-max 命令查看。

    更改系统级限制有临时更改和永久更改两种方式:

    • 临时更改:session断开或者系统重启后会恢复原来的设置值。使用命令 sysctl -w fs.file-max=xxxx,其中xxxx就是要设置的数字。

    • 永久更改:vim编辑 /etc/sysctl.conf 文件,在后面添加 fs.file-max=xxxx,其中xxxx就是要设置的数字。保存退出后还要使用sysctl -p 命令使其生效。

    (2)用户级限制

    同时为了控制每个进程消耗的文件资源,内核也会对单个进程最大打开文件数做默认限制,即用户级限制。32位系统默认值一般是1024,64位系统默认值一般是65535,可以使用 ulimit -n 命令查看。

    更改用户级限制也有临时更改和永久更改两种方式:

    • 临时更改:session断开或者系统重启后会恢复原来的设置值。使用命令 ulimit -SHn xxxx 命令来修改,其中xxxx就是要设置的数字。

    • 永久更改:vim编辑 /etc/security/limits.conf 文件,修改其中的 hard nofile xxxxsoft nofile xxxx,其中xxxx就是要设置的数字。保存后退出。关于hard和soft的区别,参照下面参考链接中的第5个。

    7、参考链接

    1. 每天进步一点点——Linux中的文件描述符与打开文件之间的关系——cywosp
    2. Linux文件描述符到底是什么?——C语言中文网
    3. 句柄和文件描述符(FD)——阳光丶不锈
    4. 带你破案:文件描述符到底是什么?——vran
    5. Linux配置调优:最大打开文件描述符个数——Idea Buffer
    6. 修改Linux系统下的最大文件描述符限制——BlueguyChui
    展开全文
  • 一、关于shapefile 关于shapefile的局限性,可以参考... Shapefile是创建于上个世纪90年代的数据格式,由于它开放易用至今仍然倍受欢迎。Shapefile文件是描述空间数据的几何和属性特征的非拓扑实体矢量数据结构的...

    一、关于shapefile

            关于shapefile的局限性,可以参考这篇文章:https://blog.csdn.net/yaoxiaochuang/article/details/52465335

            Shapefile是创建于上个世纪90年代的数据格式,由于它开放易用至今仍然倍受欢迎。Shapefile文件是描述空间数据的几何和属性特征的非拓扑实体矢量数据结构的一种格式,由ESRI公司开发。

    一个Shapefile文件最少包括三个文件:

            1.主文件(*.shp)、--存储地理要素的几何图形的文件。

            2.索引文件(*.shx)、--存储图形要素与属性信息索引的文件。

            3.dBASE表文件(*.dbf),--存储要素信息属性的dBase表文件。

           主文件是一个直接存取,变长记录的文件,其中每个记录描述一个实体的数据,称为shape。在索引文件中,每个记录包含对应主文件记录离主文件头开始的偏移量。dBASE表文件包含各个实体的属性特征记录。几何和属性间的一一对应关系是基于一个不重复的记录顺序代码来实现的,在dBASE表文件中的属性记录和主文件中的记录是相同顺序的。

    除此之外还有可选的文件包括:

            4.空间参考文件(*.prj)、

            5.几何体的空间索引文件(*.sbn 和 *.sbx)、

            6.只读的Shapefiles的几何体的空间索引文件(*.fbn 和*.fbx)、

            7.列表中活动字段的属性索引(*.ain 和 *.aih)、

            8.可读写Shapefile文件的地理编码索引(.ixs)、

            9.可读写Shapefile文件的地理编码索引(*.mxs)、

           10.dbf文件的属性索引(*.atx)、

           11.以XML格式保存元数据(*.shp.xml)、

            12.用于描述.dbf文件的代码页,指明其使用的字符编码的描述文件(*.cpg)。

    详情可以参考这篇文章:shapefile的数据结构

    二、Shapefile中文乱码问题

            ArcGIS10.2之后的桌面版本ArcMAP打开之前保存的Shapefile文件,总会不时遇到中文字符出现乱码现象,这是因为新旧版本的默认编码规则变化导致:

            ArcGIS10.2.1之前版本,Shapefile根据Locale进行编码,即注册表中的My Computer\HKEY_CURRENT_USER\Software\ESRI\Desktop 10.x\下的common—codepage—dbfDefault

            ArcGIS10.2.1及之后版本,Shapefile一般是utf-8编码,ArcGIS会先读取DBF头文件LDID中的编码,然后是CPG文件,最后是CodePage

    三、解决方法

            中文出现乱码的根本原因是读取文件使用的编码类型和文件实际存储的编码类型不一致。

            在ArcGIS Desktop 生产 shapefile 数据中,头文件(dBase Header)中,一般会包含shapefile使用的编码类型的信息,即 LDID ( Language Driver ID),它告诉应用程序用何种编码类型去正确读取它。

            在Shapefile的子文件中,有时我们还会发现同名 *.cpg 文件,文件中也存储了编码信息,用记事本打开,看到例如UTF-8。

            二者被ArcGIS 识别的优先顺序是,LDID 优先于 CPG文件

            shapefile是开放格式,只要了解了数据规范,完全可以脱离ArcGIS生产数据。在Windows中文语言设置下,假设你自己写代码或者使用第三方的程序生产了shapefile,默认使用 CP936(GBK)编码存储,忘记在数据头文件中约定—— “我用了936!”。如果是 ArcGIS 10.2之前的版本,那么没问题,ArcGIS 默认就是以这种方式识别,不会出现中文乱码。如果用高于 ArcGIS 10.2的版本打开这个shapefile,中文就会出现乱码,因为在缺失 LDID 和 CPG时,ArcGIS默认使用 UTF-8 来读取 shapefile。

            在shapefile文件里创建个记事本,修改为同名的*.cpg 文件,文本内容oem或者936。

    四、如何检测shapefile是用什么编码

            如果不知道Shapefile的编码类型,可以使用程序检测:

            共享别人写的一个python代码:

    import struct
    dbf = 'D:\tShapefiles\test.dbf'
    dat = open(dbf, 'rb').read(30)[29:]
    id = struct.unpack('B', dat)[0] 
    print(id, hex(id))
    
    例如,得到这样的打印结果:
    [b](77, '0x4d')[/b]

    通过这样的 ID      编码表     中查到就是 CodelPage 936。

    五、ArcGIS 10.3导出 Shapefile的字段名会被截断成3个汉字?低版本中不是至少可以存储4个汉字吗?

             这个问题仍然与编码类型有关。

            ArcGIS 10.2 以及更早的版本,ArcGIS写shapefile的时候,遇到中文默认使用Windows当前语言字符集编码(也称代码页/CodePage/OEM CodePage),例如中文一般使用的是CodePage936(GBK)。

            ArcGIS 10.2.1之后的版本,ArcGIS写shapefile的时候,默认使用的是 UTF-8 编码类型。

            这两种编码类型存储汉字所使用的字节数是不相同的, shapefile自身对字段的限制是9个字节,CP936编码的汉字通常为双字节,因此可以存储 9/2=4 个汉字;UTF-8 编码下汉字至少需要3个字节存储,因此最多只能存储 9/3=3 个汉字了。

            解决方法:

            一是使用地理数据库(GDB,SDE),放弃shapefile,避免各种截断问题。

            二是让arcgis默认用CP936编码,

        打开注册表,定位到 ‘My Computer\HKEY_CURRENT_USER\Software\ESRI\Desktop 10.x’<li>创建项 ‘Common‘, 接着在其下创建 ‘CodePage’ 项, 添加 ‘字符串’,名称: dbfDefault,健值:oem(或者 936)。

            修改完注册表之后,必须新建一个Shape文件或将已有的另存为(Export Data)新的Shape文件,才能让前面的修改生效。

            这样ArcGIS Desktop 读、写 shapefile的默认方式就将是Windows当前语言 OEM CodePage 936。

    展开全文
  • 不同数据库标志长度限制总结

    千次阅读 2015-07-21 15:23:40
    测试环境及数据库版本信息 操作系统:Win7 ...1、不同数据库标识符长度限制 长度单位:字符;     数据库名称 表名称 列名称 索引名称 别名   MySQL
  • cannot create directory `/home/master/jaytemp` too many links我发现是在一个目录下的一级子目录数量是有限制的,遂做了点实验和调查,结合网上其他人写的博客,得到如下的一些关于目录个数和文件个数限制的结论...
  • CFileDialog打开文件数量限制

    千次阅读 2012-03-14 18:48:50
    对于Explorer 风格对话框,目录和文件名字符串是被NULL分开的,在文件名之后有一个额外的NULL。对于旧风格对话框,字符串是被空格分开的并且函数为带有空格的文件名使用短文件名。你可以使用FindFirstFile函数在长短...
  •  ...下面我们就针对“段错误”来分析core文件的产生、以及我们 如何利用core文件找到出现崩溃的地方。 何谓core文件 当一个程序崩溃时,在进程当前工作目录的core文件中复制了该进程的存储图
  • 关于如何使用命令提示将CSV文件导入MySQL 1.建立数据库与创建table 看门见山, 首先打开cmd,键入 mysql -u root -p 后你会看到在 接着你需要输入你的root密码,输入密码之后 接下来是对数据库进行操作,...
  • 这里我使用的是springboot所以的 application.properties 文件增加 logging.config=classpath:logback-spring.xml // 指定日志配置文件 根目录增加 logback-spring.xml 配置文件 logback-spring.xml 配置文件 ...
  • 当我们的程序崩溃时,内核有可能把该程序当前内存映射到core文件里,方便程序员找到程序出现问题的地方。最常出 现的,几乎所有C程序员都出现过的错误就是“段错误”了。也是最难查出问题原因的一个错误。下面我们就...
  • asp.net 文件上传重设最大长度限制

    千次阅读 2016-12-21 14:34:15
    asp.net 默认上传最大文件长度为2M,如果想上传大于2M的文件则需修改web.config文件 如果报
  • 限制上传文件类型的两种方法

    千次阅读 2007-12-25 13:06:00
    通常,为了防止因用户上传有害文件(如木马、黑客程序)引发的安全性问题,Web程序都会对用户允许上传的文件类型加以限制。而本文将要介绍的就是如何在ASP.NET应用程序中利用Web Control的内置属性简单高效地实现...
  • 【Linux系统编程】文件IO操作

    千次阅读 2015-08-21 21:55:44
    文件描述 在 Linux 的世界里,一切设备皆文件。我们可以系统调用中 I/O 的函数(I:input,输入;O:output,输出),对文件进行相应的操作( open()、close()、write() 、read() 等)。 打开现存文件或新建...
  • ulimit -n 102400 #修改当前进程的最大文件数 网友共享的经验值: #修改文件 /etc/sysctl.conf ,在末尾追加这些文字 fs.file-max = 2097152  fs.nr_open = 2097152  net.core.s
  • Nginx配置文件(nginx.conf)配置详解

    万次阅读 多人点赞 2016-02-19 10:03:50
    Nginx的配置文件nginx.conf配置详解如下: usernginxnginx; Nginx用户及组:用户组。window下不指定 worker_processes8; 工作进程:数目。根据硬件调整,通常等于CPU数量或者2倍于CPU。 error_loglogs/error.log;...
  • WEB.XML(servlet的部署描述符文件)

    千次阅读 2006-08-10 09:10:00
    部署描述符文件就像所有XML文件一样,必须以一个XML头开始。这个头声明可以使用的XML版本并给出文件的字符编码。 DOCYTPE声明必须立即出现在此头之后。这个声明告诉服务器适用的servlet规范的版本(如2.2或2.3)并...
  • 查找文件

    千次阅读 2020-10-23 08:47:58
    因为我们已经浏览了 Linux 系统,所以一件事已经变得非常清楚:一个典型的 ...locate – 通过名字来查找文件 find – 在目录层次结构中搜索文件 我们也将看一个经常与文件搜索命令一起使用的命令,它用来处理搜索到
  • UE4类修饰

    千次阅读 2016-07-19 23:45:51
    这个类的配置信息将会根据对象进行存储,其中每个对象在.ini文件中都有一项,它以这个对象的名字命名,格式为[ObjectName ClassName]。此关键字被传递到子类。 Placeable 表明该类...
  • 文件I/O

    千次阅读 2016-11-12 20:10:51
    文件I/O简介 ##对UNIX系统来说,可用的文件I/O函数主要有:打开文件、读文件、写文件等。涉及到的函数主要有:open、read、write、lseek、close。而其中read和write函数受不同缓冲长度影响。...文件描述对内核而言,
  • Java web文件上传下载

    千次阅读 2016-07-27 19:37:16
    本文主要从javaweb上传文件到服务器中,并且在服务器端进行数据文件存储,主要分享了文件上传原理、使用第三方开源工具进行上传以及一些文件上传时需要注意的地方,文件的优化处理,还有简易分享了从我们刚才上传...
  • 索引-额外开销 每个索引占据一定的存储空间,在进行插入,更新和删除操作时也需要对索引进行操作。...如果索引的大小大于内存的限制,MongoDB会删除一些索引,这将导致性能下降。 索引-查询限制 索引不
  • 5-Python-文件操作、异常、模块

    万次阅读 2017-05-24 14:55:46
    在python,使用open函数,可以打开一个已经存在的文件,或者创建一个新文件 示例如下: open(文件名,访问模式) f = open('test.txt', 'w') 说明: 访问模式 说明 r 以只读方式打开文件文件的指针将...
  • Linux: 磁盘与文件系统管理

    万次阅读 2014-09-28 23:56:23
    du:评估文件系统的磁盘使用量(常用在推估目录所占容量)# df [-ahikHTm] [目录或文件名] 选项与参数: -a :列出所有的文件系统,包括系统特有的 /proc 等文件系统; -k :以 KBytes
  • Windows文件名长度限制

    万次阅读 2014-10-22 08:30:08
    win7x64位环境: 260个长度是作为总的文件名长度限制。 例如: 所在文件夹的长度为50 则文件名的长度被限制在210之下,超出的话会被...我手动在C:\建立一个文件,使用280个长度进行重命名,实际生成的却是文件名是256个
  • HTTP文件上传是做Web开发时的常见功能,例如上传图片、上传影片等。实现HTTP文件上传也比较简单,用任何Web端的脚本都可以轻松实现,例如PHP、JSP都有现成的函数或者类来调用。但笔者最近在做项目时遇到了一个大问题...
  • 文件解析漏洞

    千次阅读 2018-09-25 08:40:27
    文件解析漏洞 IIS解析漏洞 目录解析漏洞(/test.asp/1.jpg) 文件名解析漏洞(test.asp;.jpg) 畸形解析漏洞(test.jpg/*.php) 其他解析漏洞 Ngnix解析漏洞 畸形解析漏洞(test.jpg/*.php) %00空字节代码解析漏洞 ...
  • Redis_conf配置文件说明

    万次阅读 2015-07-10 17:24:18
    1. # Redis示例配置文件  2.  3. # 注意单位问题:当需要设置内存大小的时候,可以使用类似1k、5GB、4M这样的常见格式:  4. #  5. # 1k => 1000 bytes  6. # 1kb => 1024 bytes  7. # 1m =...
  • C++限定总结

    千次阅读 2013-05-27 11:47:18
    用内部链接,别的文件可以使用相同的标识符或全局变量,链接器不会发现冲突——也就是为每一个标识符创建单独的存储空间。在C和C++众内部链接由关键字static指定。 外部链接意味着为所有被编译

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 145,342
精华内容 58,136
关键字:

文件名字符限制