簡體   English   中英

將文件從程序集資源流寫入磁盤

[英]Write file from assembly resource stream to disk

我似乎找不到比以下更有效的方法將嵌入式資源“復制”到磁盤:

using (BinaryReader reader = new BinaryReader(
    assembly.GetManifestResourceStream(@"Namespace.Resources.File.ext")))
{
    using (BinaryWriter writer
        = new BinaryWriter(new FileStream(path, FileMode.Create)))
    {
        long bytesLeft = reader.BaseStream.Length;
        while (bytesLeft > 0)
        {
            // 65535L is < Int32.MaxValue, so no need to test for overflow
            byte[] chunk = reader.ReadBytes((int)Math.Min(bytesLeft, 65536L));
            writer.Write(chunk);

            bytesLeft -= chunk.Length;
        }
    }
}

似乎沒有更直接的方法來進行復制,除非我遺漏了什么......

我不知道你為什么要使用BinaryReader / BinaryWriter 我個人會從一個有用的實用方法開始:

public static void CopyStream(Stream input, Stream output)
{
    // Insert null checking here for production
    byte[] buffer = new byte[8192];

    int bytesRead;
    while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
    {
        output.Write(buffer, 0, bytesRead);
    }
}

然后調用它:

using (Stream input = assembly.GetManifestResourceStream(resourceName))
using (Stream output = File.Create(path))
{
    CopyStream(input, output);
}

當然,您可以更改緩沖區大小,或者將其作為方法的參數 - 但重點是這是更簡單的代碼。 它更有效率嗎? 不。 你確定你真的需要這個代碼來提高效率嗎? 您是否真的有數百兆字節的數據需要寫入磁盤?

我發現我很少需要超級高效的代碼,但我幾乎總是需要它是簡單的。 您可能會看到這種與“聰明”方法(如果有的話)之間的性能差異不太可能是復雜性改變的效果(例如 O(n) 到 O(log n))-這就是它真的可以值得追逐的性能增益的類型。

編輯:如評論中所述,.NET 4.0 具有Stream.CopyTo因此您無需自己編寫代碼。

如果資源(文件)是二進制的。

File.WriteAllBytes("C:\ResourceName", Resources.ResourceName);

如果資源(文件)是文本。

 File.WriteAllText("C:\ResourceName", Resources.ResourceName);

我實際上最終使用了這一行: Assembly.GetExecutingAssembly().GetManifestResourceStream("[Project].[File]").CopyTo(New FileStream(FileLocation, FileMode.Create)) 當然,這是針對 .Net 4.0

更新:我發現上面的行可能會鎖定一個文件,以便 SQLite 報告數據庫是只讀的。 因此,我最終得到了以下結果:

Using newFile As Stream = New FileStream(FileLocation, FileMode.Create)
    Assembly.GetExecutingAssembly().GetManifestResourceStream("[Project].[File]").CopyTo(newFile)
End Using

我個人會這樣做:

using (BinaryReader reader = new BinaryReader(
    assembly.GetManifestResourceStream(@"Namespace.Resources.File.ext")))
{
    using (BinaryWriter writer
        = new BinaryWriter(new FileStream(path, FileMode.Create)))
    {
        byte[] buffer = new byte[64 * 1024];
        int numread = reader.Read(buffer,0,buffer.Length);

        while (numread > 0)
        {
            writer.Write(buffer,0,numread);
            numread = reader.Read(buffer,0,buffer.Length);
        }

        writer.Flush();
    }
}

如果這是你的問題,你將不得不寫一個循環。 但是你可以不用讀寫器,因為基本的 Stream 已經處理了 byte[] 數據。

這是我能得到的最緊湊的:

using (Stream inStream = File.OpenRead(inputFile))
using (Stream outStream = File.OpenWrite(outputFile))
{
    int read;
    byte[] buffer = new byte[64 * 1024];

    while ((read = inStream.Read(buffer, 0, buffer.Length)) > 0)
    {
        outStream.Write(buffer, 0, read);
    }
}

這對我有用:

    using (MemoryStream input = new MemoryStream(Properties.Resources.*RESOURCE_NAME*))
    using (Stream output = File.Create(databasePath)){


                    input.CopyTo(output)
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM