2015-04-29 3 views
-3

Я программирую приложение, которое должно сохранять .txt-файл на ПК пользователя. В настоящее время я использую этот код:Как пропустить недоступные буквы диска

Dim filepath As String = "G:\Username.txt" 
    If Not System.IO.File.Exists(filepath) Then 
     System.IO.File.Create(filepath) 
    End If 

И использовал этот код для других локальных дисков, F:\ и E:\ и D:\. Как в этом примере

Dim filepath2 As String = "D:\Username.txt" 
If Not System.IO.File.Exists(filepath2) Then 
    System.IO.File.Create(filepath2) 
End If 

Dim filepath4 As String = "F:\Username.txt" 
If Not System.IO.File.Exists(filepath4) Then 
    System.IO.File.Create(filepath4) 
End If 

Этот код работает, но я столкнулся с проблемой Если пользователь ПК только имеет 2 локальные диски, кроме привода C:\, таких как G:\ и D:\. Когда код, который пытается сохранить файл .txt на диске F:\, код не может быть выполнен с помощью System.IO.DirectoryNotFoundException. Я хочу каким-то образом пропустить код, если диск недоступен и только выполнить код, когда доступен этот локальный диск (например, F:\).

+0

Вы видели [ 'DriveInfo.GetDrives()'] (https://msdn.microsoft.com/en-us/library/system.io.driveinfo.getdrives%28v=vs.110% 29.aspx)? –

+1

Примечание: Ваш текущий код * не работает, как ожидалось. Метод 'Create' не только создает файл, но и оставляет его открытым и возвращает объект FileStream, который вы можете использовать для его записи. Когда вы игнорируете возвращенный объект, код оставит файл открытым до тех пор, пока сборщик мусора не удалит объект и не закроет файл. – Guffa

+0

Спасибо, но мне нужен простой код, чтобы пропустить его? –

ответ

1

Как указано в комментариях к вашему вопросу, ваш код может создавать файл на указанных дисках, однако он оставляет дескриптор открытым в файлах. Когда появляется сборка мусора, открытые дескрипторы файлов удаляются. однако, если вы попытаетесь изменить эти файлы, пока приложение откроет их, вы обнаружите, что файл заблокирован. Метод, который вы используете, IO.File.Create возвращает объект FileStream. Этот объект поддерживает IDisposable, и поэтому вы должны либо очищаться после себя, либо выполнять директиву Using.

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

Option Strict On 
Option Explicit On 

Imports System.IO 

Module Module1 
    Sub Main() 
     Dim fleName As String = "Username.txt" 
     For Each drvInfo As DriveInfo In DriveInfo.GetDrives 
      If drvInfo.DriveType = DriveType.Fixed AndAlso drvInfo.Name <> "C:\" Then 
       Try 
        Dim fleStream As FileStream = File.Open(drvInfo.Name & fleName, FileMode.Create, FileAccess.Write) 
        ' Do some stuff here 
        fleStream.Close() 
        fleStream.Dispose() 

        ' Or implement the 'Using' directive 

        Using fleStream As FileStream = File.Open(drvInfo.Name & fleName, FileMode.Create, FileAccess.Write) 
         'do some stuff here 
        End Using 
       Catch ex As Exception 
        Console.WriteLine(ex.Message) 
       End Try 
      End If 
     Next 
    End Sub 
End Module 
+0

Извините, но я нахожусь в форме окна, и ваш код не работает. Можете ли вы объяснить, как использовать или просто простой код, который работает на форме Windows –

+0

@AmirJobs в консольном приложении, 'Main()' sub вызывается при запуске программы. Код, который я предоставил, не будет точно копировать/вставлять droppable в ваше приложение winforms.Я предлагаю создать тестовое консольное приложение, а затем скопировать/вставить вышеуказанный код в файл 'Module1' по умолчанию, а затем использовать контрольные точки, чтобы выяснить, как работает код. Как только вы поймете, что делает код, вы можете реализовать то, что вам нужно, в свой собственный проект, где вам это нужно. –

+0

@AmirJobs - Код, который я предоставил, будет делать именно то, что вы описали в своем вопросе, но здесь, на SO, мы не являемся сообществом «Помощь, сделайте мою работу для меня», поэтому не все ответы являются прямыми решениями. –

0

Отсюда:

If Not System.IO.File.Exists(filepath2) Then 

Похоже, что вы говорите (псевдо-код):

IF 'path including drive' does NOT exist, THEN create file 

Если вы читали, что внимательно, думая, что это до конца, вы увидите:

Если диск не существует, он будет классифицирован как этот путь, не существующий. Поэтому он будет пытаться создать там файл и, очевидно, выйти из строя.

Смежные вопросы