zoukankan      html  css  js  c++  java
  • 简要介绍一下Dos/Windows格式文件和Unix/Linux格式文件(剪不断理还乱的 和 )

    DOS文件(windows格式文件)中,按一下ENTER就是输入了 ,这就是回车换行

    MAC文件里,用 换行

    UNIX文件里,用 换行

    自己尝试了一些 的组合,归纳了下规律:

    windows下用文本方式文件时

    缓冲区里的 或者 都会被自动替换为 写入文件,即使是连着的 ,也会被替换成 (但是msdn上面只说 被替换为 )

    windows下用文本方式文件时

    文件中的 自动替换为 存放到缓冲区里(这点和msdn是符合的)

    不会被替换。

     

    假设要读取的文件流长度小于缓冲区长度

    如果用fread文本模式读文件, 被替换为 读进缓存区里

    如果是fgets文本模式读文件,碰到第一个 (这里的 和 都是指经过转换后读入缓冲区的,即 被替换为 )后停止读取,缓存区里存放的是 之前的字符串(包括这个 以及之前所有的 )

     

    fread和fwrite的返回值问题

    文本模式写文件时, 或 自动替换成 ,但是fwrite的返回值里还是算写了一个字符(和msdn符合)

    文本模式读文件时, 被自动替换为 ,但是也算是读了一个字符(和msdn的不一样,msdn是说算读了2个)

     

    如果用UltraEdit打开文本文件有时候会碰到询问你是否要转换为DOS文件,其实就是回车换行符的问题了。做了如下表的尝试,但是规律不太好总结啊。

     

    要写入的字符

    实际写入的字符(即 被替换为 后)

    Ultraedit转换为DOS格式后的文件内的实际字符

    未提示转换为DOS文件

    未提示转换为DOS文件

    1.  linux上用vim写的文件test.txt拷贝到windows上, 结果所有的内容都显示在一行中。(当然, 如果你Windows上的编辑显示器够智能, 那就是另外一回事了)

     2. Windows上建立的test.txt拷贝到linux上, 结果linux程序运行异常。(当然, 如果你的linux程序足够健壮, 那就没有问题了)

            ps. 当你在Windows上写好linux shell script, 拷贝到linux下运行, 就会出问题。

            为什么会出现上面的问题呢? 这就需要我们了解 和 了。

            我们先以Windows为例来说明。 我们来新建一个dos.txt文件, 然后在第一行敲一下enter键, 然后保存文件。 此时, 我们查一下这个文件的大小, 结果发现是2个字节(而不是1个), 用UltraEdit查阅一下, 就知道文件中的两个字节是0x0d和0x0a, 也就是 和 .  但是, 如果用C程序来读取dos.txt文件, 发现又根本没有读取到 , 这是怎么回事呢? 原来: 在Windows上的dos.txt文件中, 按一下enter键, 实际上就相当于C程序写 字符,而由于历史原因, 写文件的时候, Windows系统会自动在 前面加上 , 这样, dos.txt文件中就有了 了, 在读取的时候, Windows系统会自动去掉 , 所以你的C程序根本读不到 , 还是 .

            实话实说, 我发现很多地方讲 和 , 都说得不太清楚, 下面我来说一下, 希望是更清楚, 而不是更模糊微笑

            Windows系统中有如下等价关系:

            用enter换行 <====> 程序写  <====> 真正朝文件中写 (0x0d0x0a) <====>程序真正读取的是

            linux系统中的等价关系:

            用enter换行 <====> 程序写   <====> 真正朝文件中写 (0x0a)  <====> 程序真正读取的是

            现在, 我们看看本文开头部分的问题。 假设有一个linux下的unix.txt文件,  那么, 它在文件中的换行标志是: , 现在把unix.txt拷贝靠Windows上, 那好啊, Windows那双犀利的眼神仿佛是在对unix.txt文件说: 别跟我整什么 , 我只认识文件中的 , 如果你这个unix.txt文件里面有 , 那我就认为是换行符, 否则, 我不认你。 如此一来, Windows压根就找不到unix.txt中的 , 所以, 对于Windows而言, 压根就没有发现unix.txt有任何换行, 所以, 我们从Windows上看到的unix.txt文件显示在一行里面。

           同理, 假设Windows上有一个dos.txt文件, 那么, 它在文件中的换行标志是 , 现在拷贝到linux下, 那好啊, 正如linus一样, linux这个倔强的家伙貌似在说: 别的我不管, 我遇到文件中的 , 我就认为是换行, 至于其他的, 我只认为是正常的字符。 如此一来, 就被当成了文件的正常部分, 也就是说, linux下的C程序不仅仅会读取到 , 也会读取到它前面的 .

           实际上Windows上的文件是dos格式的, 而linux上的文件是unix格式的, 我们可以通过linux上的dos2unix和unix2dos来实现转化, 当然, 有的linux环境下, 需要用busybox dos2unix和busybox unix2dos.

           下面, 我们用程序来简要验证一下上面的部分叙述。 现在Windows上创建一个dos.txt文件, 第一行写入12, 然后按enter, 然后在第二行写入3, 不按enter, 然后保存。 我们先来看看Windows上的程序:

    // VC++6.0
     
    #include <stdio.h>
    #include <string.h>
     
    int main()
    {
    	char szTest[100] = {0};
    	int len = 0;
     
    	FILE *fp = fopen("dos.txt", "r");
    	if(NULL == fp)
    	{
    		printf("failed to open dos.txt
    ");
    		return 1;
    	}
     
    	fgets(szTest, sizeof(szTest) - 1, fp);
    	len = strlen(szTest);
    	if('
    ' == szTest[len - 1])
    	{
    		printf("yes1
    ");
    	}
     
    	if('
    ' == szTest[len - 2])
    	{
    		printf("yes2
    ");
    	}
     
     
    	memset(szTest, 0, sizeof(szTest));
    	fgets(szTest, sizeof(szTest) - 1, fp);
    	len = strlen(szTest);
    	if('
    ' == szTest[len - 1])
    	{
    		printf("yes3
    ");
    	}
     
    	if('
    ' == szTest[len - 2])
    	{
    		printf("yes4
    ");
    	}
     
    	fclose(fp);
     
    	return 0;
    }
    

          程序结果为:

    yes1

          我们看到, 读取的时候 确实被去掉了。

         好, 我们把dos.txt拷贝到linux下, 然后运行下面相同的程序:

    // gcc
     
    #include <stdio.h>
    #include <string.h>
     
    int main()
    {
    	char szTest[100] = {0};
    	int len = 0;
     
    	FILE *fp = fopen("dos.txt", "r");
    	if(NULL == fp)
    	{
    		printf("failed to open dos.txt
    ");
    		return 1;
    	}
     
    	fgets(szTest, sizeof(szTest) - 1, fp);
    	len = strlen(szTest);
    	if('
    ' == szTest[len - 1])
    	{
    		printf("yes1
    ");
    	}
     
    	if('
    ' == szTest[len - 2])
    	{
    		printf("yes2
    ");
    	}
     
     
    	memset(szTest, 0, sizeof(szTest));
    	fgets(szTest, sizeof(szTest) - 1, fp);
    	len = strlen(szTest);
    	if('
    ' == szTest[len - 1])
    	{
    		printf("yes3
    ");
    	}
     
    	if('
    ' == szTest[len - 2])
    	{
    		printf("yes4
    ");
    	}
     
    	fclose(fp);
     
    	return 0;
    }
    
    结果:
    [taoge@localhost learn_c]$ xxd dos.txt 
    0000000: 3132 0d0a 33                             12..3
    [taoge@localhost learn_c]$ gcc test.c 
    [taoge@localhost learn_c]$ ./a.out 
    yes1
    yes2
    [taoge@localhost learn_c]$ 
    
        我们看到, 读取的时候, 
    还在。    OK, 至此, 
    和
    的问题基本算是清楚了, 以后再也不用纠结了。

    bash: ./a.sh: /bin/bash^M: bad interpreter: No such file or directory的解决方法------dos--->unix

     一些人喜欢用vim来写linux shell script, 但是, 有的人喜欢在Windows下用一些方便的编辑器(比如鼎鼎大名的Notepad++)写好, 然后拷贝文件到linux下, 结果呢, 在执行脚本a.sh的时候, 会出现如下问题:

    [taoge@localhost learn_shell]$ ./a.sh 
    bash: ./a.sh: /bin/bash^M: bad interpreter: No such file or directory
    [taoge@localhost learn_shell]$ 
    


         什么原因呢, 我们有理由怀疑是文件格式问题? 我们用vim a.sh进入a.sh这个文件, 然后在底部模式下, 执行:set ff查看一下, 结果发现fileformat=dos, 看看, 果然是文件格式问题, 那怎么解决呢?

         方法一:vim a.sh进入a.sh后, 在底部模式下, 执行:set fileformat=unix后执行:x或者:wq保存修改。 然后就可以执行./a.sh运行脚本了。(我亲自试过, 是ok的)

         方法二:直接执行sed -i "s/ //" a.sh来转化, 然后就可以执行./a.sh运行脚本了。(我亲自试过, 是ok的)

         方法三:直接执行dos2unix a.sh来转化, 然后就可以执行./a.sh运行脚本了。(我的linux上执行dos2unix ./a.sh失败, 但是不要放弃啊, 加个busybox就可以了), 如下:

    dos2unix a.sh 
    bash: dos2unix: command not found
    [taoge@localhost learn_shell]$ busybox dos2unix a.sh 
    [taoge@localhost learn_shell]$
    

        实际上, 经过上述三种方法修改后, 我们都可以再用:set ff再查一下, 发现a.sh的fileformat果然是unix了。   第三种方法最方便, 建议用第三种!

    原文链接:

    http://blog.sina.com.cn/s/blog_65db99840100kidc.html

    https://blog.csdn.net/stpeace/article/details/45767245

    https://blog.csdn.net/stpeace/article/details/45604015

  • 相关阅读:
    被@ResponseBoby注释的方法在拦截器的posthandle方法中设置cookie失效的问题
    python之异常处理
    python之url编码
    python之发送邮件
    python之使用request模块发送post和get请求
    python之小技巧积累
    python之sys.argv[]
    python之MD5加密
    python之os、sys和random模块
    python之time和datetime的常用方法
  • 原文地址:https://www.cnblogs.com/a3192048/p/12241329.html
Copyright © 2011-2022 走看看