zoukankan      html  css  js  c++  java
  • C# 判断文件是否文本文件【转载】

    原文地址:http://www.cnblogs.com/criedshy/archive/2010/05/24/1742918.html 
     

    今天fix bugs时,碰到一个关于上传文件格式的问题。系统要求上传.txt,.csv格式的,这个可以根据文件后缀名来过滤。但是如果用户修改了后缀名来欺骗系统的话又该怎么解决?比如a.jpg格式的改成a.txt,我现在的程序就无法识别了,虽然在后台可以弹出错误,但这个错误已经不是FS上定义的错误了。

        怎么解决呢?

        在网上查了好多资料,大部分都是通过将文件读成二进制流,取前两个字节判断,比如.jpg的是255216.代码如下:

     /// <summary>
            
    /// Checks the file is textfile or not.
            
    /// </summary>
            
    /// <param name="fileName">Name of the file.</param>
            
    /// <returns></returns>
            public static FileExtension CheckTextFile(string fileName)
            {
                FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
                System.IO.BinaryReader br = new System.IO.BinaryReader(fs);
                string fileType = string.Empty; ;
                try
                {
                    byte data = br.ReadByte();
                    fileType += data.ToString();
                    data = br.ReadByte();
                    fileType += data.ToString();
                    FileExtension extension;
                    try
                    {
                        extension = (FileExtension)Enum.Parse(typeof(FileExtension), fileType);
                    }
                    catch 
                    { 

                        extension=FileExtension.VALIDFILE
                    }
                    return extension;
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                finally
                {
                    if (fs != null)
                    {
                        fs.Close();
                        br.Close();
                    }
                }
            }
        }
        public enum FileExtension
        {
            JPG = 255216,
            GIF = 7173,
            PNG = 13780,
            SWF = 6787,
            RAR = 8297,
            ZIP = 8075,
            _7Z = 55122,
            VALIDFILE=9999999
            // 255216 jpg;  

            
    // 7173 gif;  

            
    // 6677 bmp,  

            
    // 13780 png;  

            
    // 6787 swf  

            
    // 7790 exe dll,  

            
    // 8297 rar  

            
    // 8075 zip  

            
    // 55122 7z  

            
    // 6063 xml  

            
    // 6033 html  

            
    // 239187 aspx  

            
    // 117115 cs  

            
    // 119105 js  

            
    // 102100 txt  

            
    // 255254 sql   
         }   

       

       经过测试,可以很好的判断.jpg、.gif格式的文件,然而对于.txt文件却不是102100,每个.txt返回的值也不一样。显然,这个方法不能满足我的需要。

          后来看到一个delphi写的,这里有一个很简单的方法:把给定的那个文件看作是无类型的二进制文件,然后顺序地读出这个文件的每一个字节,如果文件里有一个字节的值等于0,那么这个文件就不是文本文件;反之,如果这个文件中没有一个字节的值是0的话,就可以判定这个文件是文本文件了。这是原理,下面看看在Delphi 中怎样编程来实现它-- 

    function IsTextFile(FileName:string):boolean; 
    var 
    Fs:TFileStream; 
    i,size:integer; 
    IsTextFile:boolean; 
    ByteData:Byte; 
    begin 
    if FileExists(FileName) then 
    begin 
    Fs:=TFileStream.Create(FileName,fmOpenRead); 
    IsTextFile:=true; 
    i:=0
    size:=Fs.Size; 
    While (i<size) and IsTextFile do 
    begin 
    Fs.Read(ByteData,1); 
    IsTextFile:=ByteData<>0
    inc(i) 
    end
    Fs.Free; 
    Result:=IsTextFile 
    end 
    else 
    Result:=false end

         我把它翻译成C#代码后是这样的:

     /// <summary>
            
    /// Checks the file is textfile or not.
            
    /// </summary>
            
    /// <param name="fileName">Name of the file.</param>
            
    /// <returns></returns>
            public static bool CheckIsTextFile(string fileName)
            {
                FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
                bool isTextFile=true;
                try
                {
                    int i = 0;
                    int length = (int)fs.Length;
                    byte data;
                    while (i < length && isTextFile)
                    {
                        data = (byte)fs.ReadByte();
                        isTextFile = (data != 0);
                        i++;
                    }
                    return isTextFile;
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                finally
                {
                    if (fs != null)
                    {
                        fs.Close();
                    }
                }
            } 

    后来经过测试,满足了我的需求。

      附测试代码:


                   bool isTextFile = Utility.CheckIsTextFile(this.openFile.FileName);

                    if (isTextFile)
                    {
                        this.richTxtContent.AppendText(openFile.FileName + "是文本文件");
                    }
                    else
                    {
                        this.richTxtContent.AppendText(openFile.FileName + "不是文本文件!");
                    }

  • 相关阅读:
    千年不曾看懂《道德经》,直至有了《道德图》!--作者:南山空同
    初探工作流的库表设计
    教你如何快速上手markdown语法,编写技术博客(史上最全最简,用MarkDown写博客)
    面试官:你连RESTful都不知道我怎么敢要你? 文章解析
    Dapper系列 作者:懒懒的程序员一枚
    为何要编写《元灵心经》养、和、消三篇 作者 南山空同
    南山空同《学经》前24章
    ASP.NET Core 2.2 WebApi 系列【九】使用SignalR (作者:tenghao510 ) 学习及内容补充
    Net Core 中WebAPI有关 Session的设置,及获取
    asp.net core系列 WebAPI 作者:懒懒的程序员一枚
  • 原文地址:https://www.cnblogs.com/zhuiyi/p/2432809.html
Copyright © 2011-2022 走看看