与FileStream中的写入有什么不同?

What is different with the writing in FileStream?

我在搜索使用SharpZipLib解压文件的方法时,发现了很多这样的方法:

public static void TarWriteCharacters(string tarfile, string targetDir)
{
    using (TarInputStream s = new TarInputStream(File.OpenRead(tarfile)))
    {
        //some codes here

        using (FileStream fileWrite = File.Create(targetDir + directoryName + fileName))
        {                          
            int size = 2048;
            byte[] data = new byte[2048];
            while (true)
            {
                size = s.Read(data, 0, data.Length);
                if (size > 0)
                {
                    fileWrite.Write(data, 0, size);
                }
                else
                {
                    break;
                }
            }
            fileWrite.Close();
        }
    }
}

格式FileStream.Write是:

FileStream.Write(byte[] array, int offset, int count)

现在我尝试把读写部分分开,因为我想在write函数中使用线程来加快解压速度,我使用动态数组byte[]int[]存放文件的数据和大小如下

阅读:

public static void TarWriteCharacters(string tarfile, string targetDir)
{
    using (TarInputStream s = new TarInputStream(File.OpenRead(tarfile)))
    {
        //some codes here

        using (FileStream fileWrite= File.Create(targetDir + directoryName + fileName))
        {                          
            int size = 2048;

            List<int> SizeList = new List<int>();
            List<byte[]> mydatalist = new List<byte[]>();

            while (true)
            {
                byte[] data = new byte[2048];
                size = s.Read(data, 0, data.Length);

                if (size > 0)
                {
                    mydatalist.Add(data);
                    SizeList.Add(size);
                }
                else
                {
                    break;
                }
            }
            test = new Thread(() =>
                FileWriteFun(pathToTar, args, SizeList, mydatalist)
            );
            test.Start();
            streamWriter.Close();
        }
    }
}

写入:

public static void FileWriteFun(string pathToTar , string[] args, List<int> SizeList, List<byte[]> mydataList)
{
    //some codes here

    using (FileStream fileWrite= File.Create(targetDir + directoryName + fileName))
    {
        for (int i = 0; i < mydataList.Count; i++)
        {
            fileWrite.Write(mydataList[i], 0, SizeList[i]);
        }
        fileWrite.Close();
    }
}

编辑

(1)byte[] data = new byte[2048] into while loop to assign data to new array.

(2)change int[] SizeList = new int[2048] to List<int> SizeList = new List<int>() because of int range

由于流上的读取只保证 return 一个字节(通常会更多,但您不能每次都依赖完整请求的长度),理论上您的解决方案可能会在 2048 年后失败字节,因为您的 SizeList 只能容纳 2048 个条目。

您可以使用列表来保存尺寸。

或者使用 MemoryStream 而不是自己发明。

但主要有两个问题: 1)你继续读入同一个字节数组,覆盖之前读取的数据。将数据字节数组添加到 mydatalist 时,必须将数据分配给新的字节数组。 2) 在第二个线程完成写入之前关闭流。

一般来说,多线程是很困难的,应该只在您知道它会提高性能的地方使用。简单地读取和写入数据通常在性能上受 IO 限制,而不是 cpu 限制,因此引入第二个线程只会带来很小的性能损失,而不会提高速度。您可以使用多线程来确保并发 read/write 操作,但如果您坚持使用第一个解决方案,磁盘缓存很可能会为您执行此操作 - amd 如果不是,使用异步比多线程更容易实现此目的。