Где и как сохранять файлы?


Автор: Аарон Маргозис.
Оригинал статьи: FAQ: Where Do I Save Files, and How Exactly Do I Do That?

Правильные способы определения папок для хранения файлов зависят от используемой технологии программирования. Данная статья показывает, как это сделать в C++, C# и VB. NET, PowerShell, Windows Script Host (VBScript и JScript), и с помощью переменных среды.

Одна из распространённых ошибок программирования, ведущая к проблемам совместимости, – неправильное задание путей к папкам.  Например, программы нередко полагают, что профиль пользователя находится в папке “C:\Documents and Settings”.  Пути по умолчанию могут меняться в разных версиях Windows. Сначала профили пользователей хранились в %SystemDrive%\WINNT\Profiles, затем в “%SystemDrive%\Documents and Settings”, а теперь в %SystemDrive%\Users. Профиль “All Users” теперь называется “Public”, и то, что было в папке “%USERPROFILE%\Local Settings\Application Data”, теперь находится в “%USERPROFILE%\AppData\Local”. К тому же часть того, что было в профиле “All Users”, теперь размещается в отдельной папке (по умолчанию, C:\ProgramData).

Как программам сохранить правильную работу, когда пути продолжают меняться? Корректно написанным приложениям не требуется правка для определения путей к папкам во всех версиях Windows. Необходимо выполнять следующие правила:

  • Не задавайте пути константами.
  • Не предполагайте, что Windows установлена на диске C:, а также, что есть папки “Documents and Settings”, “Users” или “Program Files”.
  • Используйте символические константы, Windows API или переменные среды, чтобы определить подходящее место для хранения файлов.
  • Различайте пользовательское и общее содержимое.
  • Различайте пользовательские файлы, которые должны быть видны в «Проводнике» (например, документы, создаваемые пользователем) и файлы, не предназначенные для прямого пользовательского доступа (например, настройки приложения). Эти типы файлов хранятся в разных местах.

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

C++

Используйте функцию SHGetSpecialFolderPath с константами CSIDL. В программах для Windows Vista и более новых версий используйте функцию SHGetKnownFolderPath с константами KNOWNFOLDERID. Подробности по ссылкам:

Эти два примера демонстрируют получение путей к папке «Документы» текущего пользователя и к общей папке «Документы»:

HRESULT hr;
TCHAR szPath[MAX_PATH];
hr = SHGetFolderPath(NULL, CSIDL_MYDOCUMENTS, NULL, SHGFP_TYPE_CURRENT, szPath);
if (SUCCEEDED(hr))
{
    ...
}
hr = SHGetFolderPath(NULL, CSIDL_COMMON_DOCUMENTS, NULL, SHGFP_TYPE_CURRENT, szPath);
if (SUCCEEDED(hr))
{
    ...
}

C#/VB .NET (управляемый код)

Используйте метод Environment.GetFolderPath, передавая перечисление Environment.SpecialFolder. Для формирования путей можно воспользоваться методом System.IO.Path.Combine. Например, следующий код C# возвращает путь к подпапке “MyData” в папке «Документы» текущего пользователя:

string sPath;
sPath = System.IO.Path.Combine(
  Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
  "MyData");

Этот же код на VB .NET:

Dim sPath As String
sPath = System.IO.Path.Combine( _
  Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), _
  "MyData")

Ссылки:

PowerShell

Windows PowerShell базируется на .NET и может вызывать многие методы .NET из командной строки PowerShell или файла сценария. Вот как выглядит предыдущий пример на PowerShell:

$sPath = [System.IO.Path]::Combine(
  [Environment]::GetFolderPath([Environment+SpecialFolder]::MyDocuments),
  "MyData")

C#/VB .NET с использованием неуправляемых методов (P/Invoke)

В коде C# или VB .NET можно вызывать неуправляемый метод SHGetFolderPath, используя Platform Invoke (P/Invoke). Это может быть полезным, так как неуправляемое перечисление CSIDL содержит больше папок, чем перечисление .NET SpecialFolder до версии 4.0.

Windows Script Host – JScript и VBScript

Windows Script Host определяет коллекцию SpecialFolders, которую можно использовать на VBScript или JScript. Следующий пример на JScript выводит путь к общему (“all users”) рабочему столу:

var oWsh = WScript.CreateObject("WScript.Shell");
var sDesk = oWsh.SpecialFolders("AllUsersDesktop");
WScript.Echo(sDesk);

Этот же код на VBScript:

Dim oWsh, sDesk
Set oWsh = WScript.CreateObject("WScript.Shell")
sDesk = oWsh.SpecialFolders("AllUsersDesktop")
WScript.Echo sDesk

Ссылки:

Переменные среды и пакетные файлы

Если ни один из описанных интерфейсов недоступен (например, из пакетного файла), Windows определяет относительно небольшое количество переменных среды, которые содержат некоторые пути. Использование переменных среды, по крайней мере, для части пути, лучше, чем задание путей константами. Следующая таблица содержит значения переменных среды на моей 64-разрядной Windows 7 SP1. Это всего лишь примеры значений на отдельном компьютере. Не предполагайте, что пути будут совпадать на разных компьютерах.

Переменная среды Значение
ALLUSERSPROFILE C:\ProgramData
APPDATA C:\Users\username\AppData\Roaming
CommonProgramFiles C:\Program Files\Common Files
CommonProgramFiles(x86) C:\Program Files (x86)\Common Files
CommonProgramW6432 C:\Program Files\Common Files
ComSpec C:\Windows\system32\cmd.exe
HOMEDRIVE C:
HOMEPATH \Users\username
LOCALAPPDATA C:\Users\username\AppData\Local
ProgramData C:\ProgramData
ProgramFiles C:\Program Files
ProgramFiles(x86) C:\Program Files (x86)
ProgramW6432 C:\Program Files
PSModulePath C:\Windows\system32\WindowsPowerShell\v1.0\Modules\
PUBLIC C:\Users\Public
SystemDrive C:
SystemRoot C:\Windows
TEMP C:\Users\username\AppData\Local\Temp
TMP C:\Users\username\AppData\Local\Temp
USERPROFILE C:\Users\username
windir C:\Windows

Ссылки:

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

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s