Как зайти в Даркнет?!
25th January, 01:11
5
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
893
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
948
0
Очень долго работает Update запрос Oracle
27th January, 09:58
912
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
905
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
938
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1724
0
период по дням
25th October, 10:44
3955
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3720
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4613
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4381
0
Помогите пожалуйста решить задачи
24th November, 23:53
6086
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4350
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4395
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Создание временных папок
Я работаю над программой, которая должна создать несколько временных папок для приложения. Они не будут видны пользователю. Приложение написано на языке VB.net. Я могу придумать несколько способов сделать это, таких как инкрементное имя папки или случайные нумерованные имена папок, но мне было интересно, как другие люди решают эту проблему?
Update: добавлена проверка File.Exists за комментарий (2012-Jun-19)
Вот то, что я использовал в VB.NET. По существу, то же самое, что и представлено, за исключением того, что я обычно не хотел создавать папку сразу.
Преимущество использования GetRandomFilename заключается в том, что он не создает файл, поэтому вам не нужно очищать его, если вы используете имя для чего-то другого, кроме файла. Например, использовать его для имени папки.
Private Function GetTempFolder() As String
Dim folder As String = Path.Combine(Path.GetTempPath, Path.GetRandomFileName)
Do While Directory.Exists(folder) or File.Exists(folder)
folder = Path.Combine(Path.GetTempPath, Path.GetRandomFileName)
Loop
Return folder
End Function
Пример Случайного Имени Файла:
C:\Documents и Settings\username\Local Settings\Temp\u3z5e0co.tvq
Вот вариант использования идентификатора Guid для получения имени временной папки.
Private Function GetTempFolderGuid() As String
Dim folder As String = Path.Combine(Path.GetTempPath, Guid.NewGuid.ToString)
Do While Directory.Exists(folder) or File.Exists(folder)
folder = Path.Combine(Path.GetTempPath, Guid.NewGuid.ToString)
Loop
Return folder
End Function
пример guid :
C:\Documents и Settings\username\Local Settings\Temp\2dbc6db7-2d45-4b75-b27f-0bd492c60496
Вы должны использовать System.IO.Path.GetTempFileName()
Создает на диске временный файл с уникальным именем и нулевым байтом и возвращает полный путь к этому файлу.
Вы можете использовать System.IO.Path.GetDirectoryName(System.IO.Path.GetTempFileName()) , чтобы получить только информацию о временной папке и создать там свои папки
Они создаются в папке windows temp, и это считается лучшей практикой
Существует возможное состояние гонки, когда:
- создание временного файла с
GetTempFileName(), его удаление и создание папки с тем же именем, или - использование
GetRandomFileName()илиGuid.NewGuid.ToStringдля присвоения имени папке и последующего ее создания
С GetTempFileName() после удаления происходит, другое приложение может успешно создать временный файл с тем же именем. Тогда CreateDirectory() потерпит неудачу.
Аналогично, между вызовом GetRandomFileName() и созданием каталога другой процесс может создать файл или каталог с тем же именем, снова приводя к сбою CreateDirectory() .
Для большинства приложений это OK для временного каталога, чтобы потерпеть неудачу из-за состояния гонки. В конце концов, это крайне редкий случай. Для них эти расы часто могут быть проигнорированы.
В мире сценариев Unix shell создание временных файлов и каталогов безопасным способом без гонки-это большое дело. Многие машины имеют несколько (враждебных) пользователей-например, общий веб-узел - и многие скрипты и приложения должны безопасно создавать временные файлы и каталоги в общем каталоге /tmp. См. раздел безопасное создание временных файлов в Shell скриптах для обсуждения того, как безопасно создавать временные каталоги из shell скриптов.
Как указал @JonathanWright, для решений существуют расовые условия:
- Создайте временный файл с
GetTempFileName(), удалите его и создайте папку с тем же именем - Используйте
GetRandomFileName()илиGuid.NewGuid.ToString, чтобы создать случайное имя папки, проверить, существует ли оно, и создать его, если нет.
Однако можно создать уникальный временный каталог атомарно, используя Транзакционный NTFS (TxF) API.
TxF имеет функцию CreateDirectoryTransacted(),которая может быть вызвана через вызов платформы. Для этого я адаптировал код Мохаммада Эльшейми для вызова CreateFileTransacted() :
// using System.ComponentModel;
// using System.Runtime.InteropServices;
// using System.Transactions;
[ComImport]
[Guid("79427a2b-f895-40e0-be79-b57dc82ed231")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IKernelTransaction
{
void GetHandle(out IntPtr pHandle);
}
// 2.2 Win32 Error Codes <http://msdn.microsoft.com/en-us/library/cc231199.aspx>
public const int ERROR_PATH_NOT_FOUND = 0x3;
public const int ERROR_ALREADY_EXISTS = 0xb7;
public const int ERROR_EFS_NOT_ALLOWED_IN_TRANSACTION = 0x1aaf;
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool CreateDirectoryTransacted(string lpTemplateDirectory, string lpNewDirectory, IntPtr lpSecurityAttributes, IntPtr hTransaction);
/// <summary>
/// Creates a uniquely-named directory in the directory named by <paramref name="tempPath"/> and returns the path to it.
/// </summary>
/// <param name="tempPath">Path of a directory in which the temporary directory will be created.</param>
/// <returns>The path of the newly-created temporary directory within <paramref name="tempPath"/>.</returns>
public static string GetTempDirectoryName(string tempPath)
{
string retPath;
using (TransactionScope transactionScope = new TransactionScope())
{
IKernelTransaction kernelTransaction = (IKernelTransaction)TransactionInterop.GetDtcTransaction(Transaction.Current);
IntPtr hTransaction;
kernelTransaction.GetHandle(out hTransaction);
while (!CreateDirectoryTransacted(null, retPath = Path.Combine(tempPath, Path.GetRandomFileName()), IntPtr.Zero, hTransaction))
{
int lastWin32Error = Marshal.GetLastWin32Error();
switch (lastWin32Error)
{
case ERROR_ALREADY_EXISTS:
break;
default:
throw new Win32Exception(lastWin32Error);
}
}
transactionScope.Complete();
}
return retPath;
}
/// <summary>
/// Equivalent to <c>GetTempDirectoryName(Path.GetTempPath())</c>.
/// </summary>
/// <seealso cref="GetTempDirectoryName(string)"/>
public static string GetTempDirectoryName()
{
return GetTempDirectoryName(Path.GetTempPath());
}
Вы можете использовать GetTempFileName для создания временного файла,а затем удалить и повторно создать этот файл в виде каталога.
Примечание: ссылка не работает, скопируйте / вставьте из: http://msdn.microsoft.com/en-us/library/aa364991(VS.85).aspx
@JonathanWright предполагает, что CreateDirectory не будет работать, когда уже есть папка. Если я читаю Directory.CreateDirectory, то он говорит: "этот объект возвращается независимо от того, существует ли каталог по указанному пути уже.- Это означает, что вы не обнаружите папку, созданную между проверкой существования и фактическим созданием.
Мне нравится CreateDirectoryTransacted(), предложенный @DanielTrebbien, но эта функция устарела.
Единственное решение, которое я вижу, что осталось, это использовать c api и вызвать там 'CreateDirectory', как это делает ошибка, если папка существует, если вам действительно нужно быть уверенным, что вы охватите все состояние гонки. Это привело бы к чему-то вроде этого:
Private Function GetTempFolder() As String
Dim folder As String
Dim succes as Boolean = false
Do While not succes
folder = Path.Combine(Path.GetTempPath, Path.GetRandomFileName)
success = c_api_create_directory(folder)
Loop
Return folder
End Function