C++ 在使用VS 2015的DirectX12应用程序中,_open()是否始终为false

C++ 在使用VS 2015的DirectX12应用程序中,_open()是否始终为false,c++,ofstream,directx-12,C++,Ofstream,Directx 12,我已经试了几个小时了,但我一辈子都无法让我的DirectX12应用程序编写一个简单的文件 关于我的设置: Windows 10已更新 DirectX12默认的“旋转立方体”应用程序。DirectX 12应用程序(通用Windows) Visual Studio 2015 我正在这样做: ofstream outFile; // I have even tried with \\ slashes... outFile.open("c://Users//pookie//Documents//WH

我已经试了几个小时了,但我一辈子都无法让我的DirectX12应用程序编写一个简单的文件

关于我的设置:

  • Windows 10已更新
  • DirectX12默认的“旋转立方体”应用程序。DirectX 12应用程序(通用Windows)
  • Visual Studio 2015
我正在这样做:

ofstream outFile;
// I have even tried with \\ slashes...
outFile.open("c://Users//pookie//Documents//WHERETHEFISMYFILE.txt");
if (outFile.is_open())
{
    outFile << "Writing this to a file.\n";
    outFile.close();
}
结果是一样的:
is_open()==false
。伙计们,我在这里不知所措

更新2:

根据要求,我正在更新此问题,以显示我正在处理的确切项目。我正在使用默认的DirectX12应用程序—旋转立方体。我

在我的项目中,有一个名为
void DX::DeviceResources::Present()
的方法,我正是在这个方法中尝试写入文件(尽管我在这个项目的许多其他地方也尝试过这个方法)

这是:

// Present the contents of the swap chain to the screen.
void DX::DeviceResources::Present()
{
    // The first argument instructs DXGI to block until VSync, putting the application
    // to sleep until the next VSync. This ensures we don't waste any cycles rendering
    // frames that will never be displayed to the screen.
    HRESULT hr = m_swapChain->Present(1, 0);

    try
    {
        wfstream  outFile;
        std::string 
         //This has been done numerous ways, but ultimately, I believe that 
         //ios_base::out is required if the file does not yet exist.
        name("c:\\Users\\pookie\\Documents\\WHERETHEFISMYFILE.txt");
        outFile.open(name.c_str(), ios_base::out);
        if (outFile.is_open())
        {
            outFile << "Writing this to a file.\n";
            outFile.close();
        }
        else
        {
            cout << "sdsadsdsd";
        }
    }
    catch (const std::exception& ex)
    {
        cout << ex.what();
    }


    // If the device was removed either by a disconnection or a driver upgrade, we 
    // must recreate all device resources.
    if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
    {
        m_deviceRemoved = true;
    }
    else
    {
        DX::ThrowIfFailed(hr);

        MoveToNextFrame();
    }
}
注意
ios\u base::out

这很好。但是,这在默认的DirectX12应用程序中仍然不起作用

这绝对是一个与DirectX相关的问题。请看。我已经尝试按照那篇文章中建议的解决方案来做,但我仍然无法让它工作

我还可以确认一个全新的DirectX12项目也有同样的问题。试试看

解决方案

多亏了ebyrob,我才得以工作。事实证明,这些新的Windows应用程序只能写入某些文件夹……更具体地说,这是:

auto platformPath = ApplicationData::Current->RoamingFolder->Path;
不幸的是,路径不是标准字符串…因此必须首先转换它:

auto platformPath = ApplicationData::Current->RoamingFolder->Path;
std::wstring platformPathW(platformPath->Begin());
std::string convertedPlatformPath(platformPathW.begin(), platformPathW.end());
然后只需添加文件名:

std::string path = convertedPlatformPath + "\\WHERETHFISMYFILE.txt";
最后:

try
{
    wofstream  outFile;
    char buff[256]; 
    outFile.open(path.c_str(), ios_base::out);
    if (outFile.is_open())
    {
        outFile << "Writing this to a file.\n";
        outFile.close();
    }
    else
    {
        cout << "Cannot open file " << name << ": " << strerror_s(buff,0) << endl;
    }
}
catch (const std::exception& ex)
{
    cout << ex.what();
}
试试看
{
wofstream输出文件;
字符buff[256];
open(path.c_str(),ios_base::out);
if(outFile.is_open())
{
outFile见以下答案:

要创建新文件,您需要为
wfstream::open()
指定正确的选项。
::in
不带
::trunc
将需要现有文件

例如:

outFile.open("C:\\Users\\pookie\\Documents\\WHERETHEFISMYFILE.txt", ios_base::out);
在这种情况下,似乎还有另一个问题。该应用程序是Windows 10应用商店的一部分,因此它只能访问几个位置的文件

请参阅此线程:


了解如何在应用程序实际访问的本地或漫游用户配置文件目录中打开文件。

我不知道到底出了什么问题,但我希望此代码将帮助您诊断问题:

#include <iostream>
#include <fstream>
#include <string>
#include <string.h>

using namespace std;

int main()
{
    ofstream outFile;
    std::string name("c://Users//pookie//Documents//WHERETHEFISMYFILE.txt");
    outFile.open(name.c_str());
    if(outFile.is_open()) {
        outFile << "Writing this to a file.\n";
        outFile.close();
    } else {
        cout << "Cannot open file " << name << ": " << strerror(errno) << endl;
    }
}
#包括
#包括
#包括
#包括
使用名称空间std;
int main()
{
出流孔的直径;
std::string name(“c://Users//pookie//Documents//WHERETHEFISMYFILE.txt”);
outFile.open(name.c_str());
if(outFile.is_open()){

outFile这里的根本问题是海报正在编写UWP,而不是Win32桌面应用程序,这意味着应用程序没有对文件系统任意部分的读写权限,特别是
C:\\Users\\pookie\\Documents\\WHERETHEFISMYFILE.txt

是否使用DirectX 12与问题无关

UWP可以直接访问的文件系统的唯一部分是:

  • 以只读方式访问已安装的打包目录。
    Windows::ApplicationModel::Package::Current->InstalledLocation

  • 对独立临时文件目录的读写访问。
    Windows::Storage::ApplicationData::Current->TemporaryFolder

  • 对本地或漫游的每个用户/每个应用程序的独立文件目录进行读写访问。
    Windows::Storage::ApplicationData::Current->LocalFolder
    RoamingFolder

在UWP中访问用户文档文件夹需要使用Windows运行时文件选择器在代码> Windows .Sturtual.P采ks或通过<代码> SturaGeFLILE < /Cult>功能,并具有适当的声明能力。对于这些受保护的文件,您也不能直接使用C++ IoSoW操作,因为它们可能甚至不是本地F上的文件。您可以使用Windows运行时API将文件复制到上面的某个位置,然后在那里的副本上使用传统的C/C++函数

以下是使用C/C++函数读取位于受保护区域中的用户文件(如UWP中的用户文档)的示例:

#include <ppltasks.h>
using namespace concurrency;

using Windows::Storage;
using Windows::Storage::Pickers;

create_task(openPicker->PickSingleFileAsync()).then([](StorageFile^ file)
{
    if (file)
    {
        auto tempFolder = Windows::Storage::ApplicationData::Current->TemporaryFolder;
        create_task(file->CopyAsync(tempFolder, file->Name, NameCollisionOption::GenerateUniqueName)).then([](StorageFile^ tempFile)
        {
            if (tempFile)
            {
                ifstream inFile(tempFile->Path->Data())
                ...
            }
        });
    });
}
#include <ppltasks.h>
using namespace concurrency;

using Windows::Storage;
using Windows::Storage::Pickers;

auto folder = Windows::Storage::ApplicationData::Current->TemporaryFolder;

WCHAR fname[ _MAX_PATH ];
wcscpy_s( fname, folder->Path->Data() );
wcscat_s( fname, L"\\MYFILE.txt" );

ofstream outFile;
outFile.open(fname, ios_base::out);

...

outFile.close();

create_task(savePicker->PickSaveFileAsync()).then([](StorageFile^ file)
{
    if ( file )
    {
        auto folder = Windows::Storage::ApplicationData::Current->TemporaryFolder;
        auto task = create_task( folder->GetFileAsync("MYFILE.txt") );
        task.then([file](StorageFile^ tempFile) ->IAsyncAction^
        {
            return tempFile->MoveAndReplaceAsync( file );
        });
    }
});
#包括
使用名称空间并发;
使用Windows::Storage;
使用Windows::Storage::Pickers;
创建任务(openPicker->PickSingleFileAsync())。然后([](存储文件^file)
{
如果(文件)
{
auto tempFolder=Windows::Storage::ApplicationData::Current->Temporary文件夹;
创建任务(文件->复制异步(tempFolder,文件->名称,名称冲突选项::GenerateUniqueName))。然后([](存储文件^tempFile)
{
如果(临时文件)
{
ifstream infle(tempFile->Path->Data())
...
}
});
});
}
以下是使用C/C++函数编写位于受保护区域的用户文件(如UWP中的用户文档)的示例:

#include <ppltasks.h>
using namespace concurrency;

using Windows::Storage;
using Windows::Storage::Pickers;

create_task(openPicker->PickSingleFileAsync()).then([](StorageFile^ file)
{
    if (file)
    {
        auto tempFolder = Windows::Storage::ApplicationData::Current->TemporaryFolder;
        create_task(file->CopyAsync(tempFolder, file->Name, NameCollisionOption::GenerateUniqueName)).then([](StorageFile^ tempFile)
        {
            if (tempFile)
            {
                ifstream inFile(tempFile->Path->Data())
                ...
            }
        });
    });
}
#include <ppltasks.h>
using namespace concurrency;

using Windows::Storage;
using Windows::Storage::Pickers;

auto folder = Windows::Storage::ApplicationData::Current->TemporaryFolder;

WCHAR fname[ _MAX_PATH ];
wcscpy_s( fname, folder->Path->Data() );
wcscat_s( fname, L"\\MYFILE.txt" );

ofstream outFile;
outFile.open(fname, ios_base::out);

...

outFile.close();

create_task(savePicker->PickSaveFileAsync()).then([](StorageFile^ file)
{
    if ( file )
    {
        auto folder = Windows::Storage::ApplicationData::Current->TemporaryFolder;
        auto task = create_task( folder->GetFileAsync("MYFILE.txt") );
        task.then([file](StorageFile^ tempFile) ->IAsyncAction^
        {
            return tempFile->MoveAndReplaceAsync( file );
        });
    }
});
#包括
使用名称空间并发;
使用Windows::Storage;
使用Windows::Storage::Pickers;
自动文件夹=Windows::Storage::ApplicationData::Current->Temporary文件夹;
WCHAR fname[_MAX_PATH];
wcscpy_s(fname,folder->Path->Data());
wcscat_s(fname,L“\\MYFILE.txt”);
出流孔的直径;
outFile.open(fname,ios_base::out);
...
outFile.close();
创建任务(savePicker->PickSaveFileAsync())。然后([](存储文件^file)
{
如果(文件)
{
自动文件夹=Windows::Storage::ApplicationData::Current->Temporary文件夹;
自动任务=创建任务(文件夹->GetFileAsync(“MYFILE.txt”);
然后([file](存储文件^tempFile)->IAsyncAction^
{
返回tempFile->moveandresplaceasync(文件);
});
}
});
看到和

请注意,任何遵循Windows Vista era指南的人都应该熟悉此模型,其中您的安装目录应该是只读的(即在
C:\Prog下)