http://www.unitymanual.com/thread-23491-1-1.html
今天,這篇文章其實是個老生常談的問題咯,在網上類似的文章也比比皆是,在此我只是做個詳細總結方便大家能夠更好、更快的掌握,當然,如有不足的地方 歡迎指正!!!
相信大家在開發過程中,難免會保存一些文件在客戶端進行本地化操作。
如:配置文件,狀態文件,Assetbundle文件等等...
最近總有人問我:
1.保存了一個xml在客戶端,能讀取里面的數據,可是不能修改,甚至一修改就報錯...
2.我在電腦上操作文件(xml、text、Assetbundle、json)都沒問題,可是生成打包生成apk、ipa運行就出現各種問題,
要么數據讀不到,要么數據不能操作...
這些問題的病症到底出現在什么地方?又該如何解決?
其實,就是對文件保存的路徑在平台間的適用性,有些路徑在各個平台上是不能通用的。
在此我對unity中路徑操作做以下幾種總結:
一.在項目根目錄中創建Resources文件夾來保存文件。
可以使用Resources.Load("文件名字,注:不包括文件后綴名");把文件夾中的對象加載出來。
注:此方可實現對文件實施“增刪查改”等操作,但打包后不可以更改了。
二.直接放在項目根路徑下來保存文件
在直接使用Application.dataPath來讀取文件進行操作。
注:移動端是沒有訪問權限的。
三.在項目根目錄中創建StreamingAssets文件夾來保存文件。
1.可使用Application.dataPath來讀取文件進行操作。
1
2
3
4
5
6
7
8
9
|
[/color][/font]
[font=微軟雅黑][color=#9acd32]#
if
UNITY_EDITOR
string
filepath = Application.dataPath +
"/StreamingAssets"
+
"/my.xml"
;
#elif UNITY_IPHONE
string
filepath = Application.dataPath +
"/Raw"
+
"/my.xml"
;
#elif UNITY_ANDROID
string
filepath =
"jar:file://"
+ Application.dataPath +
"!/assets/"
+"/my.xml;
#endif[/color][/font]
[font=微軟雅黑][color=#9acd32]
|
2.直接使用Application.streamingAssetsPath來讀取文件進行操作。
注:此方法在pc/Mac電腦中可實現對文件實施“增刪查改”等操作,但在移動端只支持讀取操作。
四.使用Application.persistentDataPath來操作文件(薦)
該文件存在手機沙盒中,因為不能直接存放文件,
1.通過服務器直接下載保存到該位置,也可以通過Md5碼比對下載更新新的資源
2.沒有服務器的,只有間接通過文件流的方式從本地讀取並寫入Application.persistentDataPath文件下,然后再通過Application.persistentDataPath來讀取操作。
注:在Pc/Mac電腦 以及Android跟Ipad、ipone都可對文件進行任意操作,另外在IOS上該目錄下的東西可以被iCloud自動備份。
五.使用Application.temporaryCachePath來操作文件
操作方式跟上面Application.persistentDataPath類似。除了在IOS上不能被iCloud自動備份。
下圖是幾種文件在Pc中路徑的具體位置
<ignore_js_op>
其實,在前面我已經發過一篇《Unity中的Path對應各平台中的Path》的文章,大家可以看看,詳細了解下unity在移動平台中的可操作的具體路徑。
有直接給出各平台對應路徑喲,方便調試查看。
好了,unity路徑的使用以及注意點都總結了,現在還是送點干料給大家吧,里面都有詳細注釋,都是開發中常用的東西
本帖隱藏的內容
1.對文件的操作類,主要就是文流讀取操作的一些東西(包括Assetbundle)FileHelper.cs
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
|
using
UnityEngine;
using
System.Collections;
using
System.IO;
using
System.Collections.Generic;
using
System;
/// <summary>
/// 使用Application.persistentDataPath方式來創建文件,讀寫Xml文件.
/// 注Application.persistentDataPath末尾沒有“/”符號
/// </summary>
public
class
FileHelper: MonoBehaviour
{
/// <summary>
/// 動態創建文件夾.
/// </summary>
/// <returns>The folder.</returns>
/// <param name="path">文件創建目錄.</param>
/// <param name="FolderName">文件夾名(不帶符號).</param>
public
string
CreateFolder(
string
path,
string
FolderName)
{
string
FolderPath = path+FolderName;
if
(!Directory.Exists(FolderPath))
{
Directory.CreateDirectory(FolderPath);
}
return
FolderPath;
}
/// <summary>
/// 創建文件.
/// </summary>
/// <param name="path">完整文件夾路徑.</param>
/// <param name="name">文件的名稱.</param>
/// <param name="info">寫入的內容.</param>
public
void
CreateFile(
string
path,
string
name,
string
info)
{
//文件流信息
StreamWriter sw;
FileInfo t =
new
FileInfo(path+name);
if
(!t.Exists)
{
//如果此文件不存在則創建
sw = t.CreateText();
}
else
{
//如果此文件存在則打開
sw = t.AppendText();
}
//以行的形式寫入信息
sw.WriteLine(info);
//關閉流
sw.Close();
//銷毀流
sw.Dispose();
}
/// <summary>
/// 讀取文件.
/// </summary>
/// <returns>The file.</returns>
/// <param name="path">完整文件夾路徑.</param>
/// <param name="name">讀取文件的名稱.</param>
public
ArrayList LoadFile(
string
path,
string
name)
{
//使用流的形式讀取
StreamReader sr =
null
;
try
{
sr = File.OpenText(path+name);
}
catch
(Exception e)
{
//路徑與名稱未找到文件則直接返回空
return
null
;
}
string
line;
ArrayList arrlist =
new
ArrayList();
while
((line = sr.ReadLine()) !=
null
)
{
//一行一行的讀取
//將每一行的內容存入數組鏈表容器中
arrlist.Add(line);
}
//關閉流
sr.Close();
//銷毀流
sr.Dispose();
//將數組鏈表容器返回
return
arrlist;
}
//寫入模型到本地
IEnumerator loadassetbundle(
string
url)
{
WWW w =
new
WWW(url);
yield
return
w;
if
(w.isDone)
{
byte
[] model = w.bytes;
int
length = model.Length;
//寫入模型到本地
CreateassetbundleFile(Application.persistentDataPath,
"Model.assetbundle"
, model,length);
}
}
/// <summary>
/// 獲取文件下所有文件大小
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
public
int
GetAllFileSize(
string
filePath)
{
int
sum = 0;
if
(!Directory.Exists(filePath))
{
return
0;
}
DirectoryInfo dti =
new
DirectoryInfo(filePath);
FileInfo[] fi = dti.GetFiles();
foreach
(FileInfo f
in
fi)
{
sum += Convert.ToInt32(f.Length / 1024);
}
DirectoryInfo[] di = dti.GetDirectories();
if
(di.Length > 0)
{
for
(
int
i = 0; i < di.Length; i++)
{
sum += GetAllFileSize(di[i].FullName);
}
}
return
sum;
}
/// <summary>
/// 獲取指定文件大小
/// </summary>
/// <param name="FilePath"></param>
/// <param name="FileName"></param>
/// <returns></returns>
public
int
GetFileSize(
string
FilePath,
string
FileName)
{
int
sum = 0;
if
(!Directory.Exists(FilePath))
{
return
0;
}
else
{
FileInfo Files =
new
FileInfo(@FilePath + FileName);
sum += Convert.ToInt32(Files.Length / 1024);
}
return
sum;
}
void
CreateassetbundleFile(
string
path,
string
name,
byte
[] info,
int
length)
{
//文件流信息
//StreamWriter sw;
Stream sw;
FileInfo t =
new
FileInfo(path +
"//"
+ name);
if
(!t.Exists)
{
//如果此文件不存在則創建
sw = t.Create();
}
else
{
//如果此文件存在則打開
//sw = t.Append();
return
;
}
//以行的形式寫入信息
sw.Write(info, 0, length);
//關閉流
sw.Close();
//銷毀流
sw.Dispose();
}
//讀取本地AssetBundle文件
IEnumerator LoadAssetbundleFromLocal(
string
path,
string
name)
{
print(
"file:///"
+ path +
"/"
+ name);
WWW w =
new
WWW(
"file:///"
+path +
"/"
+ name);
yield
return
w;
if
(w.isDone)
{
Instantiate(w.assetBundle.mainAsset);
}
}
/// <summary>
/// 刪除文件.
/// </summary>
/// <param name="path">刪除完整文件夾路徑.</param>
/// <param name="name">刪除文件的名稱.</param>
public
void
DeleteFile(
string
path,
string
name)
{
File.Delete(path + name);
}
/// <summary>
/// 刪除文件
/// </summary>
/// <param name="path"></param>
/// <param name="filesName"></param>
/// <returns></returns>
public
bool
DeleteFiles(
string
path,
string
filesName)
{
bool
isDelete =
false
;
try
{
if
(Directory.Exists(path))
{
if
(File.Exists(path +
"\\"
+ filesName))
{
File.Delete(path +
"\\"
+ filesName);
isDelete =
true
;
}
}
}
catch
{
return
isDelete;
}
return
isDelete;
}
}
|
2.隨機操作類
RandomHelper.cs
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
using
UnityEngine;
using
System.Collections;
/// <summary>
/// 隨機操作類
/// </summary>
public
class
RandomHelper
{
private
static
char
[] constant = {
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
,
'a'
,
'b'
,
'c'
,
'd'
,
'e'
,
'f'
,
'g'
,
'h'
,
'i'
,
'j'
,
'k'
,
'l'
,
'm'
,
'n'
,
'o'
,
'p'
,
'q'
,
'r'
,
's'
,
't'
,
'u'
,
'v'
,
'w'
,
'x'
,
'y'
,
'z'
,
'A'
,
'B'
,
'C'
,
'D'
,
'E'
,
'F'
,
'G'
,
'H'
,
'I'
,
'J'
,
'K'
,
'L'
,
'M'
,
'N'
,
'O'
,
'P'
,
'Q'
,
'R'
,
'S'
,
'T'
,
'U'
,
'V'
,
'W'
,
'X'
,
'Y'
,
'Z'
};
/// <summary>
/// 字符串隨機
/// </summary>
/// <param name="Length">要隨機的位數</param>
/// <returns></returns>
public
string
GenerateRandomNumber(
int
Length)
{
System.Text.StringBuilder newRandom =
new
System.Text.StringBuilder(62);
for
(
int
i = 0; i < Length; i++)
{
newRandom.Append(constant[Random.Range(0,62)]);
}
return
newRandom.ToString();
}
private
static
char
[] constant1 = {
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
};
/// <summary>
/// 數字隨機
/// </summary>
/// <param name="Length">要隨機的位數</param>
/// <returns></returns>
public
string
GenerateNumber(
int
Length)
{
System.Text.StringBuilder newRandom =
new
System.Text.StringBuilder(10);
for
(
int
i = 0; i < Length; i++)
{
newRandom.Append(constant1[Random.Range(0, 10)]);
}
return
newRandom.ToString();
}
/// <summary>
/// 字符串數組隨機
/// </summary>
/// <param name="chars">數組</param>
/// <param name="Length">隨機的位數</param>
/// <returns></returns>
public
string
GetStrRandomSurname(
string
[] chars,
int
Length)
{
int
count = chars.Length;
System.Text.StringBuilder newRandom =
new
System.Text.StringBuilder(count);
for
(
int
i = 0; i < Length; i++)
{
newRandom.Append(chars[Random.Range(0, count)]);
}
return
newRandom.ToString();
}
/// <summary>
/// 字符串*截取
/// </summary>
/// <param name="str">字符串</param>
/// <returns></returns>
public
string
[] getStringToList(
string
str)
{
return
str.Split(
'*'
);
}
}
|