将文件从资产文件夹复制到外部android存储单元

时间:2019-07-16 07:54:59

标签: c# unity3d

我想将我的资产文件夹中的某些文件复制到android设备。你怎么做呢?

我尝试了几种方法,例如通过调试打开文件,它可以在PC上运行。但是,当我将其转移到android设备后,它不起作用或将其复制了。

    public void OpenPDF(string filename) //this opens the file I have in my pc. Via debugging in Unity.
    {
        TextAsset pdfTem = Resources.Load("PDFs/" + filename, typeof(TextAsset)) as TextAsset;

        System.IO.File.WriteAllBytes(Application.persistentDataPath + "/" + filename + ".pdf", pdfTem.bytes);

        Application.OpenURL(Application.persistentDataPath + "/" + filename + ".pdf");

    }

    public void openPDFfromSD()
    {
        Application.OpenURL("/mnt/sdcard/openme.pdf"); //this doesn't open the PDF file I have in my sd card.
    }

    public void legitOpen(string nameOfFile) //this opens the file I have in my pc. Via debugging in Unity.
    {
        string realPath = Application.persistentDataPath + "/" + nameOfFile + ".pdf";
        if (!System.IO.File.Exists(realPath))
        {
            if (!System.IO.Directory.Exists(Application.persistentDataPath + "/PDFs/"))
            {
                System.IO.Directory.CreateDirectory(Application.persistentDataPath + "/PDFs/");
            }
            WWW reader = new WWW(Application.streamingAssetsPath + "/PDFs/" + realPath);
            while (!reader.isDone) { }
            System.IO.File.WriteAllBytes(realPath, reader.bytes);
        }
        Application.OpenURL(realPath);
    }

1 个答案:

答案 0 :(得分:0)

通常,您不应该直接使用字符串连接来构建系统路径。

请始终使用Path.Combine,它会根据您的目标平台自动使用正确的路径分隔符(/\)。

稍后在new WWW中,您已经在Application.streamingAssetsPath中添加了前导Application.persistentDataPathrealPath

public void OpenPDF(string filename)
{
    TextAsset pdfTem = Resources.Load("PDFs/" + filename, typeof(TextAsset)) as TextAsset;

    var filePath = Path.Combine(Application.persistentDataPath, filename + ".pdf";

    System.IO.File.WriteAllBytes(filePath), pdfTem.bytes);

    Application.OpenURL(filePath);

}

public void legitOpen(string nameOfFile)
{
    string realPath = Path.Combine(Application.persistentDataPath, nameOfFile + ".pdf");
    if (!System.IO.File.Exists(realPath))
    {
        if (!System.IO.Directory.Exists(Path.Combine(Application.persistentDataPath, "PDFs"))
        {
            System.IO.Directory.CreateDirectory(Path.Combine(Application.persistentDataPath, "PDFs"));
        }
        WWW reader = new WWW(Path.Combine(Application.streamingAssetsPath, "PDFs", nameOfFile + ".pdf");
        while (!reader.isDone) { }
        System.IO.File.WriteAllBytes(realPath, reader.bytes);
    }
    Application.OpenURL(realPath);
}

如果要防止应用程序在加载完成之前完全冻结,我建议使用CoroutineUnityWebRequest.Get之类的

public void legitOpen(string nameOfFile)
{
    StartCoroutine(legitOpenRoutine(nameOfFile));
}

private IEnumerator legitOpenRoutine(string nameOfFile)
{
    string realPath = Path.Combine(Application.persistentDataPath, nameOfFile + ".pdf");
    if (!System.IO.File.Exists(realPath))
    {
        if (!System.IO.Directory.Exists(Path.Combine(Application.persistentDataPath, "PDFs"))
        {
            System.IO.Directory.CreateDirectory(Path.Combine(Application.persistentDataPath, "PDFs"));
        }
        using (var reader = new UnityWebRequest.Get(Path.Combine(Application.streamingAssetsPath, "PDFs", nameOfFile + ".pdf"))
        {
            yield return reader.SendWebRequest();

            if (webRequest.isNetworkError)
            {
                Debug.Log(pages[page] + ": Error: " + webRequest.error);
                return;
            }                

            System.IO.File.WriteAllBytes(realPath, reader.bytes);
        }
    }
    Application.OpenURL(realPath);
}

甚至使用CopyToAsync

完全使用异步方法
public void legitOpen(string nameOfFile)
{
    legitOpenAsync(nameOfFile);
}

private async void legitOpenAsync(string nameOfFile)
{
    var realPath = Path.Combine(Application.persistentDataPath, nameOfFile + ".pdf");

    var pdfPath = Path.Combine(Application.persistentDataPath, "PDFs");

    if (!System.IO.File.Exists(realPath))
    {
        if (!System.IO.Directory.Exists(pdfPath)
        {
            System.IO.Directory.CreateDirectory(pdfPath);
        }

        using(var sourceFile = File.Open(Path.Combine(Application.streamingAssetsPath, "PDFs", nameOfFile + ".pdf"), FileMode.Open, FileAccess.Read, FileShare.Read)
        {
            using(var targetFile = File.Open(realPath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write))
            {
                await sourceFile.CopyToAsync(targetFile);
            }
        }
    }

    Application.OpenURL(realPath);
}

但是

请注意,Application.OpenURL

  

Android :由于Android 7.0(More information),Application.OpenURL中的安全性更改,不能再用于打开本地应用文件,您需要使用FileProvider来允许您与其他应用程序共享文件。

  

iOS Application.OpenURL 不能用于打开本地文件

因此,这根本不起作用

public void openPDFfromSD()
{
    Application.OpenURL("/mnt/sdcard/openme.pdf");
}