unity C# IO 分段写入与读取
本人测试的一个压缩文件, 为3.31G
下面提供了三种方法分别对文件进行分段操作,功能不同,坑也不同。
第一种读取的方法代码比较少,但是确实最好的一种方法.
因为我们用的byte数组, 数组是有长度的,而且长度是整数,整数是有界限的,所以在读取和操作的时候就会造成越界的情况。
第一种方法:在读取的时候采用分次读入和分次读取,这样的话,只要合理的划分分段写入得大小就不会有问题
第二种方法:在读取的时候, 因为是直接读取,所以文件不能太大(大概2G),太大就读取不了
第三种方法:其实跟第二种一样,只不过只是写入byte[];这种的方法在程序中也有可能会用到,所以也就研究了一下。比如网络传输,一个大文件会分几次发送,但是每次发送接受到的都是字节,这时候就需要用到这个方法了
1 using System.Collections; 2 using System.Collections.Generic; 3 using UnityEngine; 4 using System.IO; 5 6 public class IOTest : MonoBehaviour 7 { 8 public static int segWriteSize 9 { 10 get 11 { 12 return 1024 * 1024 * 5; //每次五兆 13 } 14 } 15 16 private void Start() 17 { 18 string path = @"E:\1.zip"; 19 string outpath = @"E:\all.zip"; 20 StartCoroutine(SegWrite(path, outpath)); 21 22 //byte[] bs = File.ReadAllBytes(path); 23 //Debug.Log(bs.Length); 24 //StartCoroutine(SegWrite(bs, outpath)); 25 26 27 //StartCoroutine(SegRead(path, outpath)); 28 } 29 30 public static IEnumerator SegRead(string filepath, string outpath) //第一种 31 { 32 FileStream fswrite = File.OpenWrite(outpath); 33 FileStream fsread = new FileStream(filepath, FileMode.Open, FileAccess.Read); 34 BinaryReader r = new BinaryReader(fsread); 35 byte[] bs = r.ReadBytes(segWriteSize); 36 while(bs.Length != 0) 37 { 38 fswrite.Write(bs, 0, bs.Length); 39 fswrite.Flush(); 40 yield return null; 41 Debug.Log("write......."); 42 bs = r.ReadBytes(segWriteSize); 43 } 44 fswrite.Close(); 45 46 } 47 48 public static IEnumerator SegWrite(string filepath, string outpath) //分段写入 第2种 49 { 50 FileStream fsRead = File.OpenRead(filepath); //打开 51 byte[] buffer = new byte[segWriteSize]; //一次分段写入的大小 52 int segsize = buffer.Length; //分段的长度 53 int copied = 0; //标记长度 54 int filesize = 0; //一次写入的文件大小 55 56 FileStream fswrite = File.OpenWrite(outpath); 57 if (segsize < (int)fsRead.Length) //如果文件比分段写入的大,说明需要分段 58 { 59 while (copied + segsize <= (int)fsRead.Length) //分段写入 60 { 61 yield return null; 62 filesize = fsRead.Read(buffer, 0, buffer.Length); //一次读入的大小 63 fsRead.Flush(); 64 fswrite.Write(buffer, 0, buffer.Length); //分次写入 65 fswrite.Flush(); 66 copied += filesize; 67 Debug.Log("write........"); 68 } //剩下的在写入 69 int left = (int)fsRead.Length - copied; 70 fsRead.Read(buffer, 0, left); 71 fsRead.Flush(); 72 fswrite.Write(buffer, 0, left); 73 fswrite.Flush(); 74 Debug.Log("write........"); 75 } 76 else 77 { 78 buffer = new byte[(int)fsRead.Length]; 79 fsRead.Read(buffer, 0, buffer.Length); 80 fsRead.Flush(); 81 fswrite.Write(buffer, 0, buffer.Length); 82 fswrite.Flush(); 83 } 84 fsRead.Close(); 85 fsRead.Dispose(); 86 fswrite.Close(); 87 fswrite.Dispose(); 88 Debug.Log("write finish"); 89 } 90 91 public static IEnumerator SegWrite(byte[] bs, string outpath) //第三种 92 { 93 byte[] buffer = new byte[segWriteSize]; //一次分段写入的大小 94 int segsize = buffer.Length; //分段的长度 95 int copied = 0; //标记长度 96 97 FileStream fswrite = File.OpenWrite(outpath); 98 if (segsize < bs.Length) //如果文件比分段写入的大,说明需要分段 99 { 100 while (copied + segsize <= bs.Length) 101 { 102 buffer = new byte[segWriteSize]; 103 for (int i = 0; i < segWriteSize; i++) 104 { 105 int index = copied + i; 106 buffer[i] = bs[index]; 107 } 108 copied += segWriteSize; 109 fswrite.Write(buffer, 0, buffer.Length); //分次写入 110 fswrite.Flush(); 111 yield return null; 112 Debug.Log("write........"); 113 } 114 int left = bs.Length - copied; 115 buffer = new byte[left]; 116 for (int i = 0; i < left; i++) 117 { 118 int index = copied + i; 119 buffer[i] = bs[index]; 120 } 121 copied += left; 122 Debug.Log(copied); 123 fswrite.Write(buffer, 0, left); 124 fswrite.Flush(); 125 yield return null; 126 Debug.Log("write........"); 127 } 128 else 129 { 130 fswrite.Write(bs, 0, bs.Length); 131 fswrite.Flush(); 132 } 133 134 fswrite.Close(); 135 fswrite.Dispose(); 136 Debug.Log("write finish"); 137 } 138 139 140 }