1. 在Unity 中,使用ICSharpCode.SharpZipLib 压缩,解压时,如果遇到中文文件或文件夹时,就会出现乱码问题, 那么只需在代码中加上如下两句话,其中Enconding,GetEncoding("GB18030"),还可以换成Enconding,GetEncoding("GBK")等等,本人没深入了解,只是发现多种情况都适用。
Encoding gbk = Encoding.GetEncoding("GB18030");
ZipConstants.DefaultCodePage = gbk.CodePage;
public class ZIPHelper {
///
///
///
/// 要压缩的文件夹
/// 压缩的文件路径
public void CreateZip(string sourceFilePath, string destinationZipFilePath) {
if (sourceFilePath[sourceFilePath.Length - 1] != System.IO.Path.DirectorySeparatorChar)
sourceFilePath += System.IO.Path.DirectorySeparatorChar;
ZipOutputStream zipStream = new ZipOutputStream(File.Create(destinationZipFilePath));
Encoding gbk = Encoding.GetEncoding("GB18030");
ZipConstants.DefaultCodePage = gbk.CodePage;
zipStream.SetLevel(0); // 压缩级别 0-9
CreateZipFiles(sourceFilePath, zipStream);
zipStream.Finish();
zipStream.Close();
}
//
// 压缩文件夹
//
// 源目录 param >
//< param name="s">ZipOutputStream对象
public void CreateZipFiles(string sourceFilePath, ZipOutputStream zipStream) {
Crc32 crc = new Crc32();
string[] filesArray = Directory.GetFileSystemEntries(sourceFilePath);
foreach (string file in filesArray) {
if (Directory.Exists(file)) //如果当前是文件夹,递归
{
CreateZipFiles(file, zipStream);
} else //如果是文件,开始压缩
{
FileStream fileStream = File.OpenRead(file);
byte[] buffer = new byte[fileStream.Length];
fileStream.Read(buffer, 0, buffer.Length);
string tempFile = file.Substring(sourceFilePath.LastIndexOf("\\") + 1);
ZipEntry entry = new ZipEntry(tempFile);
entry.DateTime = DateTime.Now;
entry.Size = fileStream.Length;
fileStream.Close();
crc.Reset();
crc.Update(buffer);
entry.Crc = crc.Value;
zipStream.PutNextEntry(entry);
zipStream.Write(buffer, 0, buffer.Length);
}
}
}
///
///
///
/// 要解压的文件
/// 解压路径
/// 是否覆盖已存在的文件
public void UnZipFiles(string ZipFile, string TargetDirectory, bool OverWrite = true) {
using (ZipInputStream zipfiles = new ZipInputStream(File.OpenRead(ZipFile))) {
Encoding gbk = Encoding.GetEncoding("GB18030");
ZipConstants.DefaultCodePage = gbk.CodePage;
ZipEntry theEntry;
while ((theEntry = zipfiles.GetNextEntry()) != null) {
string directoryName = "";
string pathToZip = "";
pathToZip = theEntry.Name;
if (pathToZip != "")
directoryName = Path.GetDirectoryName(pathToZip) + "\\";
string fileName = Path.GetFileName(pathToZip);
Directory.CreateDirectory(TargetDirectory + directoryName);
if (fileName != "") {
if ((File.Exists(TargetDirectory + directoryName + fileName) && OverWrite) || (!File.Exists(TargetDirectory + directoryName + fileName))) {
using (FileStream streamWriter = File.Create(TargetDirectory + directoryName + fileName)) {
int size = 2048;
byte[] data = new byte[2048];
while (true) {
size = zipfiles.Read(data, 0, data.Length);
if (size > 0)
streamWriter.Write(data, 0, size);
else
break;
}
streamWriter.Close();
}
}
}
}
zipfiles.Close();
}
}
}
2.问题二,在电脑上运行时,解压,压缩中文文件,几乎完美,但是当把软件打包发布以后,发现代码在执行这两句代码时就会报错,
Encoding gbk = Encoding.GetEncoding("GB18030");
ZipConstants.DefaultCodePage = gbk.CodePage;
经过本人一天的苦苦搜查,终于发现了解决办法,只需将Unity 安装目录下的
两个动态库 I18N.dll I18N.CJK.dll放到Asset里面就可以,(Unity安装的目录例(UNITY64\Unity\Editor\Data\Mono) 在Mono下搜索(I18N.dll)( I18N.CJK.dll)2个动态库)Unity引用dll 文件需要放在Plugins 目录下,没有可以自己建一个。到此完美解决了中文文件压缩和解压问题。
3.问题3,使用Node.js 搭建了一个服务器,使用www 上传文件,发现上传中文文件是乱码,因此,本人做了一下操作,总算解决了,不知道算不算麻烦。
第一步:将上传的中文文件名编码成uft8
string zipname = Application.persistentDataPath + "/" + "Avatar" + ".zip";
FileStream fm = File.OpenRead(zipname);
byte[] bs = new byte[fm.Length];
fm.Read(bs, 0, (int)fm.Length);
fm.Close();
WWWForm form = new WWWForm();
string filename = (username + ".zip");
string code = "";
foreach (byte b in Encoding.UTF8.GetBytes(filename)) {
code += '%' + b.ToString("X");
}
form.AddField("enctype", "multipart/form-data");
form.AddBinaryData("info", bs, code);
string ip = PlayerPrefs.GetString("IP");
// string ip = "192.168.1.104";
string ippath = "http://" + ip + ":8800/upload";
WWW www = new WWW(ippath, form);
yield return www;
if (www.error != null) {
var gameobject = GameObject.Find("TrayCanvas").transform.Find("UploadHint");
gameObject.SetActive(true);
gameObject.GetComponent().text = "上传失败!";
yield return new WaitForSeconds(1.0f);
GameObject.Find("TrayCanvas").transform.Find("UploadHint").gameObject.SetActive(false);
} else {
GameObject.Find("TrayCanvas").transform.Find("UploadHint").gameObject.SetActive(true);
yield return new WaitForSeconds(1.0f);
GameObject.Find("TrayCanvas").transform.Find("UploadHint").gameObject.SetActive(false);
}
第二部:在Node.js 服务器上解码,转成中文,然后重命名,使用了 iconv-lite
app.all("/upload", multipartMiddleware, function (req, res, next) {
var files = fs.readdirSync(publicPath);
if (files.length >4) {
var JTime = new Date().getTime() + 1000;
files.forEach(function (val, index) {
var stat = fs.statSync(publicPath + val);
var time = new Date(stat.ctime).getTime();
if (time < JTime) {
JTime = time;
}
});
files.forEach(function (val, index) {
if (fs.statSync(publicPath + val).ctime.getTime() == JTime) {
fs.rename(publicPath + val, "./Assets/all/" + new Date().getTime() + val, function (err) {
if (err) throw err;
})
}
})
}
res.setHeader('content-type','text/html; charset=UTF-8');
var str= iconv.decode(req.files.info.name,'gb2312');
//将接受的文件解码成utf8
var s=decodeURIComponent(str);
//转成中文。
console.log(s);
fs.rename(req.files.info.path, publicPath + s, function (err) {
if (err) throw err;
});
res.end();
});
问题4,下载中文文件, 我 将中文文关键件直接转成Utf8 编码,然后写入拼写地址中,就可以直接下载,关键代码还是
string filename = (username + ".zip");
string code = "";
foreach (byte b in Encoding.UTF8.GetBytes(filename)) {
code += '%' + b.ToString("X");
}
使用code 进行参数传递。
折磨了好几天中文编码问题到此完美解决。