Bootstrap

Unity 多线程和IO流的使用及lock的使用

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;
                    });
                }
            }
        }
    }
}
;