.NET делает копию встроенного файлового ресурса на локальный диск

Я новичок в области работы с файлами в .NET

Я создаю приложение WPF в VB.NET с помощью 3.5 Framework. (Если вы приведете пример на C #, это прекрасно.)

В моем проекте у меня есть шаблон для базы данных MS Access. Мое желаемое поведение состоит в том, что когда пользователи нажимают «Файл» -> «Новый», они могут создать новую копию этого шаблона, дать ей имя файла и сохранить ее в своем локальном каталоге.

В базе данных уже есть таблицы и некоторые начальные данные, необходимые для взаимодействия с моим приложением (удобный редактор данных).

Я думаю, что подход состоит в том, чтобы включить этот файл "template.accdb" в качестве ресурса в проект и как-то записать его в файл во время выполнения?

Мы будем очень, очень признательны за любое руководство.

Спасибо!


person Matt H.    schedule 08.04.2010    source источник


Ответы (7)


обязательно передайте полное имя пространства имен в ResourceName

Public Function ExtractResourceToDisk(ByVal ResourceName As String, ByVal FileToExtractTo As String) As Boolean

    Dim s As System.IO.Stream = System.Reflection.Assembly.GetExecutingAssembly.GetManifestResourceStream(ResourceName)
    Dim ResourceFile As New System.IO.FileStream(FileToExtractTo, IO.FileMode.Create)

    Dim b(s.Length) As Byte

    s.Read(b, 0, s.Length)
    ResourceFile.Write(b, 0, b.Length - 1)
    ResourceFile.Flush()
    ResourceFile.Close()

    ResourceFile = Nothing
End Function
person Greg Bogumil    schedule 08.04.2010

Что ж, «проще всего» было бы просто включить его в качестве выходного файла в установку вашей программы, чтобы он устанавливался где-нибудь вместе с вашим приложением (возможно, в каталоге вашего приложения или в подкаталоге за его пределами). Затем вы можете просто использовать File.Copy, когда вам нужно создать новый шаблон. Я не утверждаю, что это лучшее решение, просто минимум работы. Вы можете прочитать о методе File.Copy здесь.

person NebuSoft    schedule 08.04.2010

public static void WriteResourceToFile(Assembly assembly, Type scope, string resname, string path)
{
    Stream res = assembly.GetManifestResourceStream(scope, resname);
    using (FileStream file = new FileStream(path, FileMode.Create))
    {
        byte[] buffer = new byte[4096];
        int bytesRead;
        while ((bytesRead = res.Read(buffer, 0, buffer.Length)) > 0)
        {
            file.Write(buffer, 0, bytesRead);
        }
    }   
}

Должен сделать свое дело. Где область видимости будет областью пространства имен для имени ресурса, которая позволяет вам сократить имя ресурса, которое является полностью определенным.

person Todd    schedule 08.04.2010


Я изменил ответ Грега Богумила сверху, чтобы создать метод расширения. Теперь с любым файлом ресурсов двоичного типа я могу просто сделать что-то вроде этого ...

My.Resources.some_resource_file.ExtractResourceToDisk(newpath)

Обратите внимание, что вам нужно будет добавить следующую функцию в модуль, вы не можете создавать методы расширения внутри класса.

''' <summary>
''' Extracts the binary resource file and saves it to the specified location.
''' </summary>
''' <param name="Resource">[Byte()] The binary resource file byte array.</param>
''' <param name="FileToExtractTo">[String] The full file path of the new file to be saved.</param>
''' <returns>[Boolean] Returns True on success.</returns>
<Extension>
Public Function ExtractResourceToDisk(ByVal Resource As Byte(), ByVal FileToExtractTo As String) As Boolean
    Try
        Using ms As New MemoryStream(Resource)
            Using ResourceFile As New FileStream(FileToExtractTo, FileMode.Create)
                Dim b(ms.Length) As Byte
                ms.Read(b, 0, ms.Length)
                ResourceFile.Write(b, 0, b.Length - 1)
                ResourceFile.Flush()
                ResourceFile.Close()
            End Using
        End Using
        Return True
    Catch ex As Exception
        Return False
    End Try
End Function
person Fütemire    schedule 24.08.2016

Во-первых, убедитесь, что для Build Action соответствующего файла установлено значение Embedded resource.

Затем, основываясь на ответе @Greg Bogumil, вы запускаете этот метод:

public static bool ExtractResourceToDisk(string ResourceName, string FileToExtractTo) {
  //Choose any one assembly that matches your needs.
  var asm = System.Reflection.Assembly.GetEntryAssembly();
  //var asm = System.Reflection.Assembly.GetExecutingAssembly();
  //var asm = System.Reflection.Assembly.GetCallingAssembly();
  var s = asm.GetManifestResourceStream(ResourceName);
  var resFile = new System.IO.FileStream(FileToExtractTo, System.IO.FileMode.Create);
  if (resFile == null) return false;
  s.CopyTo(resFile);
  return true;
}

Вместо этого я использую метод CopyTo, потому что он более краткий.

person Fandi Susanto    schedule 28.07.2017

Я получил эту работу с копированием файлов в целевой каталог из встроенного файла.

Dim FilePath As String = Application.StartupPath & "\testing.txt" 'file name and its extension
            Using MsiFile As New FileStream(FilePath , FileMode.Create)
                MsiFile.Write(My.Resources.testing, 0, My.Resources.testing.Length)
            End Using
            My.Computer.FileSystem.CopyFile(FilePath , "C:\destination", Microsoft.VisualBasic.FileIO.UIOption.AllDialogs, Microsoft.VisualBasic.FileIO.UICancelOption.DoNothing)
            MsgBox("done copy")
person Jing Xian    schedule 17.10.2020