Skip to content

Commit b9f9b1a

Browse files
author
ale
committed
加入FileDB的设计,用于多文件句柄开的过多的问题
1 parent 3f69403 commit b9f9b1a

File tree

7 files changed

+809
-118
lines changed

7 files changed

+809
-118
lines changed

CSharp/FileDB.cs

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.IO;
5+
using System.Linq;
6+
using System.Text;
7+
using UnityEngine;
8+
9+
namespace ATRI.Collection
10+
{
11+
public class FileDB : IDisposable
12+
{
13+
#region member
14+
// fileOffset, subFileLen, subFile isCopyTo File
15+
private Dictionary<string, ValueTuple<int, int, bool, string>> tableInfo = new Dictionary<string, (int, int, bool, string)>();
16+
private Dictionary<string, object> tableDict = new Dictionary<string, object>();
17+
private FileStream _fs;
18+
private string _path;
19+
private bool _inited = false;
20+
#endregion
21+
22+
public FileDB(string filePath)
23+
{
24+
_path = filePath;
25+
}
26+
27+
#region public
28+
29+
public bool TryGetValueByTableName<TKey, TValue>(string tableName, TKey key, out TValue value) where TKey : IEquatable<TKey>
30+
{
31+
Init();
32+
object dict;
33+
if (!tableDict.TryGetValue(tableName, out dict))
34+
{
35+
ValueTuple<int, int, bool, string> info;
36+
if (tableInfo.TryGetValue(tableName, out info))
37+
{
38+
// copy value to mergefile
39+
if (!info.Item3)
40+
{
41+
var tempBuff = FileDictionaryUtils.moveTempBuff;
42+
FileStream subFile = new FileStream(info.Item4, FileMode.Open, FileAccess.Read);
43+
int bytesRead;
44+
_fs.Seek(info.Item1, SeekOrigin.Begin);
45+
while ((bytesRead = subFile.Read(tempBuff, 0, tempBuff.Length)) > 0)
46+
{
47+
_fs.Write(tempBuff, 0, bytesRead);
48+
}
49+
}
50+
SubFileStream subFileStream = new SubFileStream(_fs, info.Item1, info.Item2);
51+
dict = new FileDictionary<TKey, TValue>(subFileStream);
52+
tableInfo.Remove(tableName);
53+
tableDict.Add(tableName, dict);
54+
}
55+
else
56+
{
57+
Debug.LogError("tableInfo not init");
58+
value = default(TValue);
59+
return false;
60+
}
61+
}
62+
63+
FileDictionary<TKey, TValue> fd = (FileDictionary<TKey, TValue>)dict;
64+
return fd.TryGetValue(key, out value);
65+
}
66+
67+
public void Dispose()
68+
{
69+
if (_fs != null)
70+
{
71+
_fs.Dispose();
72+
}
73+
}
74+
75+
public void MergeRuntime(params string[] paths)
76+
{
77+
if (File.Exists(_path))
78+
{
79+
File.Delete(_path);
80+
}
81+
82+
tableInfo.Clear();
83+
_inited = false;
84+
85+
int len = 0;
86+
foreach (var filePath in paths)
87+
{
88+
FileInfo fi = new FileInfo(filePath);
89+
if (!fi.Exists)
90+
{
91+
throw new Exception(filePath + " not exit! please check");
92+
}
93+
string fileName = Path.GetFileNameWithoutExtension(filePath);
94+
if (tableInfo.ContainsKey(fileName))
95+
{
96+
Debug.LogError(fileName + " already exit!plz check in:[\n"+ string.Concat(paths, "\n") +"]");
97+
return;
98+
}
99+
100+
tableInfo.Add(fileName, (len, (int)fi.Length, false, filePath));
101+
len += (int)fi.Length;
102+
}
103+
}
104+
105+
#if UNITY_EDITOR
106+
public void MergeEditor(params string[] paths)
107+
{
108+
if (File.Exists(_path))
109+
{
110+
File.Delete(_path);
111+
}
112+
113+
tableInfo.Clear();
114+
_inited = false;
115+
116+
FileStream fs = new FileStream(_path, FileMode.CreateNew, FileAccess.Write);
117+
BinaryWriter bfw = new BinaryWriter(fs);
118+
119+
MemoryStream headMs = new MemoryStream();
120+
BinaryWriter bw = new BinaryWriter(headMs);
121+
122+
int len = 0;
123+
bw.Write(paths.Length);
124+
Dictionary<string, string> closeSet = new Dictionary<string, string>();
125+
foreach (var filePath in paths)
126+
{
127+
FileInfo fi = new FileInfo(filePath);
128+
if (!fi.Exists)
129+
{
130+
throw new Exception(filePath + "not eixt! please check");
131+
}
132+
133+
string fileName = Path.GetFileNameWithoutExtension(filePath);
134+
if (closeSet.ContainsKey(fileName))
135+
{
136+
throw new Exception(filePath + "file name the same with path:" + closeSet[fileName]);
137+
}
138+
139+
byte[] strData = UTF8Encoding.UTF8.GetBytes(fileName);
140+
bw.Write(strData.Length);
141+
bw.Write(strData);
142+
bw.Write(len);
143+
bw.Write((int)fi.Length);
144+
145+
len += (int)fi.Length;
146+
}
147+
148+
int totalHeadLen = (int)headMs.Length;
149+
bw.Flush();
150+
bw.Close();
151+
152+
bfw.Write(totalHeadLen);
153+
bfw.Write(headMs.ToArray());
154+
155+
var tempBuff = FileDictionaryUtils.moveTempBuff;
156+
157+
foreach (var filePath in paths)
158+
{
159+
int bytesRead;
160+
FileStream subFile = new FileStream(filePath, FileMode.Open, FileAccess.Read);
161+
while ((bytesRead = subFile.Read(tempBuff, 0, tempBuff.Length)) > 0)
162+
{
163+
fs.Write(tempBuff, 0, bytesRead);
164+
}
165+
}
166+
167+
bfw.Flush();
168+
bfw.Close();
169+
170+
}
171+
#endif
172+
173+
#endregion
174+
175+
private void Init()
176+
{
177+
if (_inited) return;
178+
_inited = true;
179+
180+
// merge in runtime
181+
if (tableInfo.Count <= 0)
182+
{
183+
_fs = new FileStream(_path, FileMode.OpenOrCreate, FileAccess.Read);
184+
BinaryReader br = new BinaryReader(_fs);
185+
int totalHeadLen = br.ReadInt32();
186+
int fileLen = br.ReadInt32();
187+
188+
for (int i = 0; i < fileLen; i++)
189+
{
190+
int strLen = br.ReadInt32();
191+
byte[] datas = br.ReadBytes(strLen);
192+
string fileName = UTF8Encoding.UTF8.GetString(datas);
193+
int offset = br.ReadInt32();
194+
int onefileLen = br.ReadInt32();
195+
196+
tableInfo.Add(fileName, (offset + totalHeadLen + 4, onefileLen, true, ""));
197+
}
198+
}
199+
else
200+
{
201+
_fs = new FileStream(_path, FileMode.OpenOrCreate, FileAccess.ReadWrite);
202+
}
203+
}
204+
205+
}
206+
}

CSharp/FileDB.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)