Unity 多线程和IO流的使用及lock的使用
#介绍
线程和IO流的结合,读大文件时,要把读到数据先赋值给一个变量,然后再在循环中赋值(相当于一行一行的读,一行一行的赋值)
//读大文件时用这种方法
Thread thread = new Thread(Xc);
thread.Start();
Debug.Log("开启线程");
/// <summary>
/// 复制一张图片
/// </summary>
void Xc()
{
int size = 0;
using (FileStream read = new FileStream("C:\\Users\\vonstars\\Desktop\\项目UI\\111.jpg", FileMode.Open))
{
byte[] buffer = new byte[1024];
using (FileStream write = new FileStream("C:\\Users\\vonstars\\Desktop\\项目UI\\222.jpg", FileMode.Create))
{
while ((size = read.Read(buffer, 0, buffer.Length)) > 0)
{
write.Write(buffer, 0, size);
}
write.Close();
read.Close();
}
Debug.Log("写入完成");
}
}
#线程安全,lock锁的使用
保证所有数据都可以添加到字典中
使用多线程读文件与图片将多张图片合成并拆解,并使用Loom脚本在多线程中对UI进行操作
重点:lock的使用
private static readonly object Locker = new object();
lock (Locker)
{
dir.Add(index, buffer.Length);
}
using NUnit.Framework;
using System.IO;
using System.Linq;
using System.Threading;
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
public class Thread_Pictures : MonoBehaviour
{
string[] path;
//实例化对象
public GameObject imagePrefab;
//实例化父节点
public Transform locat;
List<string> list = new List<string>();
//实例化100合1张的进度条
GameObject img;
private Dictionary<string, GameObject> m_dict = new Dictionary<string, GameObject>();
//实例化1分100张进度条
GameObject img1;
Dictionary<string, GameObject> m_dict1 = new Dictionary<string, GameObject>();
//存放图片的索引和大小
Dictionary<int, int> dir = new Dictionary<int, int>();
//lock 多线程中给字典上锁
private static readonly object Locker = new object();
void Start()
{
path = Directory.GetFiles("C:\\Data\\Merr");
for (int i = 0; i < path.Count(); i++)
{
list.Add(path[i]);
}
//实例化Loom脚本
Loom.Initialize();
//创建线程
int num = list.Count / 100 + 1;
for (int i = 0; i < num; i++)
{
int index = i;
img = Instantiate(imagePrefab, locat);
img.name = index + "";
img.GetComponentInChildren<Text>().text = index + "";
m_dict.Add(index + "", img);
Thread thread = new Thread(() =>
{
if (((index + 1) * 100) < list.Count)
{
Pictures(list, (index * 100), ((index + 1) * 100) - 1, index);
}
else
{
Pictures(list, (index * 100), list.Count - 1, index);
}
});
thread.Start();
}
}
/// <summary>
/// 每一百张合成一张图片
/// </summary>
void Pictures(List<string> path, int mix, int max, int count)
{
float currSize = 0;
float progressValue = 0;
float fileSize = 0;
for (int i = mix; i <= max; i++)
{
using (FileStream fs = new FileStream(path[i], FileMode.Open))
{
fileSize += fs.Length;
}
}
string str = "C:\\Data\\Merr100合1\\" + count + ".tif";
using (FileStream fs1 = new FileStream("C:\\Data\\Merr100合1\\" + count + ".tif", FileMode.Create))
{
for (int i = mix; i <= max; i++)
{
int index = i;
//Debug.Log("mix:" + mix + " max:" + max);
using (FileStream fs = new FileStream(path[i], FileMode.Open))
{
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
fs1.Write(buffer, 0, buffer.Length);
//线程锁
lock (Locker)
{
dir.Add(index, buffer.Length);
}
currSize += fs.Length;
progressValue = currSize / fileSize;
}
Loom.QueueOnMainThread(() =>
{
m_dict[count + ""].GetComponent<Image>().fillAmount = progressValue;
});
}
}
//创建线程
Loom.QueueOnMainThread(() =>
{
img1 = Instantiate(imagePrefab, locat);
img1.name = count + "";
img1.GetComponentInChildren<Text>().text = count + "合";
m_dict1.Add(count + "", img1);
});
Thread thread = new Thread(() =>
{
Pics(mix, max, count, str);
});
thread.Start();
}
/// <summary>
/// 每张图分成100张
/// </summary>
void Pics(int mix, int max, int count, string path)
{
float currSize = 0;
float progressValue = 0;
using (FileStream fs1 = new FileStream(path, FileMode.Open))
{
float fileSize = fs1.Length;
for (int i = mix; i <= max; i++)
{
byte[] buffer = new byte[dir[i]];
fs1.Read(buffer, 0, buffer.Length);
//Debug.Log("mix:" + mix + " max:" + max);
using (FileStream fs = new FileStream("C:\\Data\\Merr1裁100\\" + i + ".tif", FileMode.Create))
{
fs.Write(buffer, 0, buffer.Length);
currSize += buffer.Length;
progressValue = currSize / fileSize;
Loom.QueueOnMainThread(() =>
{
m_dict1[count + ""].GetComponent<Image>().fillAmount = progressValue;
});
}
}
}
}
}