GVKun编程网logo

c# – FileStream.ReadByte:字节永远不是负数?(c#中以字节为单位进行文件读写的类是)

14

对于想了解c#–FileStream.ReadByte:字节永远不是负数?的读者,本文将是一篇不可错过的文章,我们将详细介绍c#中以字节为单位进行文件读写的类是,并且为您提供关于.NETFileStr

对于想了解c# – FileStream.ReadByte:字节永远不是负数?的读者,本文将是一篇不可错过的文章,我们将详细介绍c#中以字节为单位进行文件读写的类是,并且为您提供关于.NET FileStream文件流,StreamReader文本流,MemoryStream内存流几种流的实例、2019.04.19 读书笔记 比较File.OpenRead()和File.ReadAllBytes()的差异、ASP.NET Core – Byte, Stream, File 基础、C# .net core StreamReader读文件流改为FileStream的有价值信息。

本文目录一览:

c# – FileStream.ReadByte:字节永远不是负数?(c#中以字节为单位进行文件读写的类是)

c# – FileStream.ReadByte:字节永远不是负数?(c#中以字节为单位进行文件读写的类是)

从 msdn开始:

FileSystem.ReadByte
The byte,cast to an Int32,or -1 if the end of the stream has been reached.

所以-1基本上是一个“神奇的价值”.这是否意味着从流返回的字节永远不会是负数?如果没有,为什么不呢?

解决方法

在C#中,字节的值是0到255之间的数字,因此字节永远不会为负数.

sbyte数据类型是有符号字节,因此它的值介于-128和127之间.

(在某些其他语言中,例如Java,字节数据类型已签名.)

.NET FileStream文件流,StreamReader文本流,MemoryStream内存流几种流的实例

.NET FileStream文件流,StreamReader文本流,MemoryStream内存流几种流的实例

一、FileStream文件流

1.读取数据

 1    public class ReadFile
 2     {
 3         /// <summary>
 4         /// 读取文件
 5         /// FileMode.Create  创建一个新文件,如果文件已经存在则改写旧文件
 6         /// FileMode.CreateNew 创建一个文件,如果文件存在会发生异常,提示文件已经存在
 7         /// FileMode.Open  打开文件,如果文件不存在则异常
 8         /// FileMode.OpenOrCreate  打开文件,如果文件不存在,则创建一个新的文件并且打开文件
 9         /// FileMode.Append   打开现有文件,并且在现有文件内容后面追加,如果文件不存在则异常
10         /// FileMode.Truncate 根据现有操作系统,截取文件里面的内容,如果文件不存在则异常
11         /// </summary>
12         public static void Read(string FilePath)
13         {
14             FileStream fileStream = null;
15             try
16             {
17               fileStream = new FileStream(FilePath, FileMode.Truncate);
18                 byte[] bytes = new byte[fileStream.Length];
19                 int read = fileStream.Read(bytes, 0, bytes.Length);
20                 var result = Encoding.UTF8.GetString(bytes);
21             }
22             catch (Exception e)
23             {
24                 if (fileStream != null)
25                 {
26                     fileStream.Dispose();
27                 }
28                 Console.WriteLine(e.Message);
29             }
30             finally
31             {
32                 if (fileStream != null)
33                 {
34                     fileStream.Close();
35                     fileStream.Dispose();
36                 }
37             }
38         }
39     }

2.写入数据

 1    public class WriteFile
 2     {
 3         public static void WriteText(string FilePath,string writeString)
 4         {
 5             FileStream fileStream = null;
 6             try
 7             {
 8                 //根据路径打开文件
 9                 fileStream = new FileStream(@"C:\Users\Administrator\source\repos\OperatFile\OperatFile\1.txt", FileMode.Append);
10                 //把字符串转化成字节
11                 byte[] bytes = Encoding.UTF8.GetBytes(writeString);
12                 //写入到文件
13                 fileStream.Write(bytes, 0, bytes.Length);
14             }
15             catch (Exception e)
16             {
17           if (fileStream != null)
18                 {
19                     fileStream.Dispose();
20                 }
21                 Console.WriteLine(e.Message);
22             }
23             finally
24             {
25                 //关闭和释放
26                 if (fileStream != null)
27                 {
28                     fileStream.Close();
29                     fileStream.Dispose();
30                 }
31             }
32         }
33     }

二、StreamReader文本流

1.读取数据

 1    public class SteamReadFile
 2     {
 3         /// <summary>
 4         /// 读取文件
 5         /// </summary>
 6         /// <param name="filePath">文件路径</param>
 7         public static void ReadFile(string FilePath)
 8         {
 9             try
10             {
11                 using (StreamReader sr = new StreamReader(FilePath))
12                 {
13                     var result = sr.ReadToEnd();
14                     Console.WriteLine(result);
15                 }
16             }
17             catch (Exception e)
18             {
19 
20                 throw new Exception(e.Message);
21             }
22         }
23     }

2.写入数据

 1    public class StreamWriteFile
 2     {
 3         /// <summary>
 4         /// 写入文件
 5         /// </summary>
 6         /// <param name="FilePath">文件路径</param>
 7         /// <param name="WriteString">待写入字符串</param>
 8         public static void WriteFile(string FilePath,string WriteString)
 9         {
10             try
11             {
12                 using (StreamWriter sr = new StreamWriter(FilePath))
13                 {
14                     sr.WriteLine(WriteString);
15                 }
16             }
17             catch (Exception e)
18             {
19                 throw new Exception(e.Message);
20             }
21         }
22     }

3.写入日志实例

 1    public class LogHelper
 2     {
 3         /// <summary>
 4         /// 文件路径
 5         /// </summary>
 6         public static string FilePath = @"C:\Users\Administrator\source\repos\OperatFile\OperatFile\Files";
 7         static LogHelper()
 8         {
 9             //判断文件夹是否存在,如果不存在,则重新创建
10             if (!Directory.Exists(FilePath))
11             {
12                 Directory.CreateDirectory(FilePath);
13             }
14         }
15      /// <summary>
16         /// 日志写入
17         /// Path.Combine(str1,str2,str3)  把传入的参数拼接起来,然后返回新的字符串
18         /// File.AppendText(fullPath) 根据文件路径,把新写入的内容,拼接到文本后面
19         /// </summary>
20         public static void WriteLog()
21         {
22             try
23             {
24                 var sb = BindData();
25                 string fullPath = Path.Combine(FilePath, $"{DateTime.Now.ToString("yyyy-MM-dd")}.txt");
26                 //判断文件是否存在,如果不存在,则新建文件
27                 if (!File.Exists(fullPath))
28                 {
29                     File.Create(fullPath);
30                 }
31                 using (StreamWriter sw = File.AppendText(fullPath))
32                 {
33                     sw.WriteLine(sb.ToString());
34                 }
35             }
36             catch (Exception e)
37             {
38                 throw new Exception(e.Message);
39             }
40 
41         }
42      /// <summary>
43         /// 绑定日志信息
44         /// </summary>
45         /// <returns></returns>
46         private static StringBuilder BindData()
47         {
48             StringBuilder sb = new StringBuilder();
49             DateTime operatDateTime = DateTime.Now;
50             string content = "读写文件功能";
51             string operators = "小明";
52             sb.AppendLine($"操作时间:{operatDateTime}");
53             sb.AppendLine($"操作内容:{content}");
54             sb.AppendLine($"操作人:{operators}");
55             sb.AppendLine("------------------------------------------------------------------------------------------");
56             return sb;
57         }
58     }

三、MemoryStream内存流

 1      /// <summary>
 2         /// 根据URL读取内容到内存流
 3         /// </summary>
 4         /// <param name="url"></param>
 5         /// <returns></returns>
 6         public static string DownLoadByUrl(string url)
 7         {
 8             string result = string.Empty;
 9             MemoryStream ms = null;
10             HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
11             HttpWebResponse response = request.GetResponse() as HttpWebResponse;
12             using (var stream = response.GetResponseStream())
13             {
14           byte[] buffer = new byte[response.ContentLength];
15                 int actuallyRead = 0, offset = 0;
16                 do
17                 {
18                     actuallyRead = stream.Read(buffer, offset, buffer.Length - offset);
19                     offset += actuallyRead;
20 
21                 } while (actuallyRead > 0);
22                 ms = new MemoryStream(buffer);
23                 ms.Seek(0, SeekOrigin.Begin);
24                 var byteArray = new byte[ms.Length];
25                 ms.Read(byteArray, 0, byteArray.Length);
26                 result = Encoding.UTF8.GetString(byteArray);
27             }
28             response.Close();
29             response.Dispose();
30             return result;
31         }

 

2019.04.19 读书笔记 比较File.OpenRead()和File.ReadAllBytes()的差异

2019.04.19 读书笔记 比较File.OpenRead()和File.ReadAllBytes()的差异

最近涉及到流的获取与转化,终于要还流的债了。

百度了一下,看到这样的两条回复,于是好奇心,决定看看两种写法的源码差异。

先来看看OpenRead()

public static FileStream OpenRead(string path) => 
    new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);

//构造函数又调用了其他构造函数,继续深入
[SecuritySafeCritical]
public FileStream(string path, FileMode mode, FileAccess access, FileShare share) : this(path, mode, access, share, 0x1000, FileOptions.None, Path.GetFileName(path), false)
{
}
//调用了Init 初始化
[SecurityCritical]
internal FileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options, string msgPath, bool bFromProxy)
{
    Win32Native.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(share);
    this.Init(path, mode, access, 0, false, share, bufferSize, options, secAttrs, msgPath, bFromProxy, false, false);
}

//读取数据到流中,过程就没什么可以看的了
[SecuritySafeCritical]
private unsafe void Init(string path, FileMode mode, FileAccess access, int rights, bool useRights, FileShare share, int bufferSize, FileOptions options, Win32Native.SECURITY_ATTRIBUTES secAttrs, string msgPath, bool bFromProxy, bool useLongPath, bool checkHost)
{
    int num;
    if (path == null)
    {
        throw new ArgumentNullException("path", Environment.GetResourceString("ArgumentNull_Path"));
    }
    if (path.Length == 0)
    {
        throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
    }
    FileSystemRights rights2 = (FileSystemRights) rights;
    this._fileName = msgPath;
    this._exposedHandle = false;
    FileShare share2 = share & ~FileShare.Inheritable;
    string paramName = null;
    if ((mode < FileMode.CreateNew) || (mode > FileMode.Append))
    {
        paramName = "mode";
    }
    else if (!useRights && ((access < FileAccess.Read) || (access > FileAccess.ReadWrite)))
    {
        paramName = "access";
    }
    else if (useRights && ((rights2 < FileSystemRights.ListDirectory) || (rights2 > FileSystemRights.FullControl)))
    {
        paramName = "rights";
    }
    else if ((share2 < FileShare.None) || (share2 > (FileShare.Delete | FileShare.ReadWrite)))
    {
        paramName = "share";
    }
    if (paramName != null)
    {
        throw new ArgumentOutOfRangeException(paramName, Environment.GetResourceString("ArgumentOutOfRange_Enum"));
    }
    if ((options != FileOptions.None) && ((options & 0x3ffbfff) != FileOptions.None))
    {
        throw new ArgumentOutOfRangeException("options", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
    }
    if (bufferSize <= 0)
    {
        throw new ArgumentOutOfRangeException("bufferSize", Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
    }
    if (((!useRights && ((access & FileAccess.Write) == 0)) || (useRights && ((rights2 & FileSystemRights.Write) == 0))) && (((mode == FileMode.Truncate) || (mode == FileMode.CreateNew)) || ((mode == FileMode.Create) || (mode == FileMode.Append))))
    {
        if (!useRights)
        {
            object[] objArray1 = new object[] { mode, access };
            throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFileMode&AccessCombo", objArray1));
        }
        object[] values = new object[] { mode, rights2 };
        throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFileMode&RightsCombo", values));
    }
    if (useRights && (mode == FileMode.Truncate))
    {
        if (rights2 != FileSystemRights.Write)
        {
            object[] objArray3 = new object[] { mode, rights2 };
            throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFileModeTruncate&RightsCombo", objArray3));
        }
        useRights = false;
        access = FileAccess.Write;
    }
    if (!useRights)
    {
        num = (access == FileAccess.Read) ? -2147483648 : ((access == FileAccess.Write) ? 0x40000000 : -1073741824);
    }
    else
    {
        num = rights;
    }
    int maxPathLength = useLongPath ? 0x7fff : (AppContextSwitches.BlockLongPaths ? 260 : 0x7fff);
    string fullPath = Path.NormalizePath(path, true, maxPathLength);
    this._fileName = fullPath;
    if ((!CodeAccessSecurityEngine.QuickCheckForAllDemands() || AppContextSwitches.UseLegacyPathHandling) && fullPath.StartsWith(@"\\.\", StringComparison.Ordinal))
    {
        throw new ArgumentException(Environment.GetResourceString("Arg_DevicesNotSupported"));
    }
    bool flag = false;
    if ((!useRights && ((access & FileAccess.Read) != 0)) || (useRights && ((rights2 & FileSystemRights.ReadAndExecute) != 0)))
    {
        if (mode == FileMode.Append)
        {
            throw new ArgumentException(Environment.GetResourceString("Argument_InvalidAppendMode"));
        }
        flag = true;
    }
    if (CodeAccessSecurityEngine.QuickCheckForAllDemands())
    {
        FileIOPermission.EmulateFileIOPermissionChecks(fullPath);
    }
    else
    {
        FileIOPermissionAccess noAccess = FileIOPermissionAccess.NoAccess;
        if (flag)
        {
            noAccess |= FileIOPermissionAccess.Read;
        }
        if (((!useRights && ((access & FileAccess.Write) != 0)) || (useRights && ((rights2 & (FileSystemRights.TakeOwnership | FileSystemRights.ChangePermissions | FileSystemRights.Delete | FileSystemRights.Write | FileSystemRights.DeleteSubdirectoriesAndFiles)) != 0))) || ((useRights && ((rights2 & FileSystemRights.Synchronize) != 0)) && (mode == FileMode.OpenOrCreate)))
        {
            if (mode == FileMode.Append)
            {
                noAccess |= FileIOPermissionAccess.Append;
            }
            else
            {
                noAccess |= FileIOPermissionAccess.Write;
            }
        }
        AccessControlActions control = ((secAttrs != null) && (secAttrs.pSecurityDescriptor != null)) ? AccessControlActions.Change : AccessControlActions.None;
        string[] fullPathList = new string[] { fullPath };
        FileIOPermission.QuickDemand(noAccess, control, fullPathList, false, false);
    }
    share &= ~FileShare.Inheritable;
    bool flag2 = mode == FileMode.Append;
    if (mode == FileMode.Append)
    {
        mode = FileMode.OpenOrCreate;
    }
    if ((options & FileOptions.Asynchronous) != FileOptions.None)
    {
        this._isAsync = true;
    }
    else
    {
        options &= ~FileOptions.Asynchronous;
    }
    int dwFlagsAndAttributes = (int) options;
    dwFlagsAndAttributes |= 0x100000;
    int newMode = Win32Native.SetErrorMode(1);
    try
    {
        string str3 = fullPath;
        if (useLongPath)
        {
            str3 = Path.AddLongPathPrefix(str3);
        }
        this._handle = Win32Native.SafeCreateFile(str3, num, share, secAttrs, mode, dwFlagsAndAttributes, IntPtr.Zero);
        if (this._handle.IsInvalid)
        {
            int errorCode = Marshal.GetLastWin32Error();
            if ((errorCode == 3) && fullPath.Equals(Directory.InternalGetDirectoryRoot(fullPath)))
            {
                errorCode = 5;
            }
            bool flag4 = false;
            if (!bFromProxy)
            {
                try
                {
                    FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, this._fileName, false, false);
                    flag4 = true;
                }
                catch (SecurityException)
                {
                }
            }
            if (flag4)
            {
                __Error.WinIOError(errorCode, this._fileName);
            }
            else
            {
                __Error.WinIOError(errorCode, msgPath);
            }
        }
    }
    finally
    {
        Win32Native.SetErrorMode(newMode);
    }
    if (Win32Native.GetFileType(this._handle) != 1)
    {
        this._handle.Close();
        throw new NotSupportedException(Environment.GetResourceString("NotSupported_FileStreamOnNonFiles"));
    }
    if (this._isAsync)
    {
        bool flag5 = false;
        new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();
        try
        {
            flag5 = ThreadPool.BindHandle(this._handle);
        }
        finally
        {
            CodeAccessPermission.RevertAssert();
            if (!flag5)
            {
                this._handle.Close();
            }
        }
        if (!flag5)
        {
            throw new IOException(Environment.GetResourceString("IO.IO_BindHandleFailed"));
        }
    }
    if (!useRights)
    {
        this._canRead = (access & FileAccess.Read) > 0;
        this._canWrite = (access & FileAccess.Write) > 0;
    }
    else
    {
        this._canRead = (rights2 & FileSystemRights.ListDirectory) > 0;
        this._canWrite = ((rights2 & FileSystemRights.CreateFiles) != 0) || ((rights2 & FileSystemRights.AppendData) > 0);
    }
    this._canSeek = true;
    this._isPipe = false;
    this._pos = 0L;
    this._bufferSize = bufferSize;
    this._readPos = 0;
    this._readLen = 0;
    this._writePos = 0;
    if (flag2)
    {
        this._appendStart = this.SeekCore(0L, SeekOrigin.End);
    }
    else
    {
        this._appendStart = -1L;
    }
}

从上面的源码可以看出,OpenRead会把无论多大的文件都读取到FileStream中,能有多大呢?FileStream.Length可是long型的,就是2的63次方了,2的40次方是1T,大约就是8MT吧,我们的常用硬盘是没这么大的了,可以说能读出天荒地老了。那么图片中的第一中写法,读取没错,但是转换int就留下了隐患,int的最大限制是2G,如果文件超过2G,那么转换就会被截取,导致读到data里的数据就不完整了。所以一定不要偷懒,由于FileStream.Read的参数是int型的,一定要判断流的长度,如果超过了int最大值,要循环read。

再来看看File.ReadAllBytes(),上源码:

[SecurityCritical]
private static byte[] InternalReadAllBytes(string path, bool checkHost)
{
    byte[] buffer;
    using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 0x1000, FileOptions.None, Path.GetFileName(path), false, false, checkHost))//这里也是和OpenRead一样,把文件全部读取进来了
    {
        int offset = 0;
        long length = stream.Length;
        if (length > 0x7fffffffL)//这里才是关键,对长度做了一个判断,如果超过了2G,就抛异常了,所以决定了这个方法的文件不能超过2G
        {
            throw new IOException(Environment.GetResourceString("IO.IO_FileTooLong2GB"));
        }
        int count = (int) length;
        buffer = new byte[count];
        while (count > 0)
        {
            int num4 = stream.Read(buffer, offset, count);
            if (num4 == 0)
            {
                __Error.EndOfFile();
            }
            offset += num4;
            count -= num4;
        }
    }
    return buffer;
}

第二种写法会导致在读取文件超过2G后抛出异常,所以使用时要确定文件的大小,否则就用OpenRead()。

所以图中两种写法都可能存在隐患的BUG。

当然,在确定了不可能超过2G的情况下,还是可以自由使用的。

 

ASP.NET Core – Byte, Stream, File 基础

ASP.NET Core – Byte, Stream, File 基础

前言

以前的文章: Stream 基础和常用 和 IO 常用.

这篇主要是做一个整理, 方便要用的时候 warm up.

 

基本术语和概念

先过一边基本术语和概念:

Bits

Bits 就是比特. 它是最小的单位, 1 bit = 1 个二进制, 0 或者 1.

通信的时候就是通过电压高低, 来表示 0 或 1. 在由二进制来表达万物 (就好比摩斯密码一样啦) 

Bytes

Bytes 是字节. 1 byte = 8 bits. 它也是一个单位.

Stream

Stream 是流的概念. 如果 bytes 是鱼, 那么 stream 就是河流. 通信的时候就好像建立了河流. 然后上面有很多鱼游来游去.

Bytes encode

通信用的是二进制, 那自然是需要 encode 咯, 比如把 0 和 1 变成 alphabet (英文字母). 

1 个 alphabet 需要 1 byte 来表示, 而汉字需要 2 bytes 来表示 (也要 依据 encode 手法, 但大概可以这样去理解).

还有很多种 encode 的方式, 比如: ASCII, Unicode, UTF, Base64

char, char[], string

char 是 C# 中用来装字母的, 1 char = 2 bytes, 所以它也可以撞汉字.

char[] 就是很多字母咯.

string 是 char[] 的封装. 它包含了对 char[] 的操作, 比如 char[] 的 length 是不可以变的, 但 string 可以.

 

ASP.NET Core Stream 结构

ASP.NET Core build-in 了许多 Class 来处理 Bytes, Stream 这些冬冬. 

Stream(抽象类) > TextReader(抽象类) > StreamReader(实体类) > MemoryStream(实体类), FileStream(实体类) 等等

顾名思义, MemoryStream 是负责缓存的, FileStream 是文件的. 

 

串起来理解 & 运用场景

万物都是二进制

在数码世界里, 万物都是二进制 (bits) 0 或 1 来表示的, 1 个文件它储存在磁盘里就是二进制, 2 台电脑通信传输的依然是二进制.

这个是最底层的逻辑.

二进制如果表达万物?

0 和 1 对电脑来说 ok, 对人来说可不行, 所以需要转换. 二进制转换成英文字母, 汉字是有规范的, 这就是所谓的 ASCII, Unicode, UTF, 等等.

运用场景

假设, 系统的需求是让用户输入一段字母, 然后生成 1 个 word.txt 文件. 

当获取到 user input (string), 先把它转换成 bytes. 然后创建文件, 并把 bytes 写进去.

在开发种我们需要掌握好, encode (清楚如何 decode/encode bytes), file type (文件的类型), 读写 stream 的 bytes.

    

 

C# .net core StreamReader读文件流改为FileStream

C# .net core StreamReader读文件流改为FileStream

见Stackoverflow的提问.

原先在NET Framework下,StreamReader中提供重载的方式直接读取文件流.但是在.net core中已经取消了该重载方法,为了移植到.net core只需添加一行代码即可.

string fileName = "xxxx";
...
//原来只用这一句
//StreamReader mysr = new StreamReader(fileName, Encoding.UTF8);
//现在需要添加FileStream.
var sw = new FileStream(fileName, FileMode.Open);
StreamReader mysr = new StreamReader(sw);
...

关于c# – FileStream.ReadByte:字节永远不是负数?c#中以字节为单位进行文件读写的类是的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于.NET FileStream文件流,StreamReader文本流,MemoryStream内存流几种流的实例、2019.04.19 读书笔记 比较File.OpenRead()和File.ReadAllBytes()的差异、ASP.NET Core – Byte, Stream, File 基础、C# .net core StreamReader读文件流改为FileStream等相关知识的信息别忘了在本站进行查找喔。

本文标签: