Форум программистов, компьютерный форум, киберфорум
Visual Basic .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/8: Рейтинг темы: голосов - 8, средняя оценка - 4.50
 Аватар для jugger_off
13 / 13 / 3
Регистрация: 21.12.2013
Сообщений: 225

Как правильно открыть и сохранять файлы, которые используются текущим приложением

30.01.2015, 22:49. Показов 1718. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть программа, результаты её работы я могу сохранять в текстовый файл и потом открывать его. Всё полностью работает, за исключением одной вещи. Поясню:
Во всех приложениях где есть возможность открытия какого-либо файла, сделано так что открытый файл нельзя перемещать, копировать, удалять, переименовывать вручную и т.д., когда он открыт в программе. Я для открытия файла использовал класс File и его методы WriteAllLines и ReadAllLines, но они закрывают файл после работы с ним и с файлом пользователь может делать, что угодно. А я не хочу что бы он этого делал. Если пользователь пытается напр. удалить файл, то перед ним windows показывает окно с текстом: "Действие не может быть выполнено, так как это файл открыть в "Имя_приложения". Закройте файл и повторите попытку." Чтобы у фалов моей проги было такое же сообщения я стал использовать класс StreamWriter и StreamReader. Вот процедуры записи и чтения файла:
VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
'Сохранить как
Private Sub SaveAsMenuButton_Click(sender As Object, e As EventArgs) Handles SaveAsMenuButton.Click
        Dim A(,), B(,) As Double
        Dim Result As DialogResult
        DGV1.EndEdit()
        DGV2.EndEdit()
        A = ReadFromDGV(DGV1) 'функция читает из DataGridView1 и пишет в двумерный массив
        B = ReadFromDGV(DGV2) 'функция читает из DataGridView2 и пишет в двумерный массив
        Result = SFD1.ShowDialog()
        Try
            If Result = Windows.Forms.DialogResult.OK Then
                Dim FileFromTable As New StreamWriter(SFD1.FileName)
                SaveFileStream(A, B, FileFromTable) 'фун-ия пишет массивы A и B в файл
                CurrentOpenFileName = SFD1.FileName
                Me.SaveMenuButton.Enabled = True
                MatrixUnsavedChangesDone = False
            End If
        Catch ex As Exception
            MsgBox(ex.Message, MsgBoxStyle.OkOnly Or MsgBoxStyle.Exclamation, "Ошибка!")
            Me.Cursor = Cursors.Arrow
        End Try
    End Sub
'Открыть
    Private Sub OpenMenuButton_Click(sender As Object, e As EventArgs) Handles OpenMenuButton.Click
        Dim Result As DialogResult
        DGV1.EndEdit()
        Try
            Result = OFD1.ShowDialog()
            If Result = Windows.Forms.DialogResult.OK Then
                Dim FileToOpen As New StreamReader(OFD1.FileName)
                OpenFileStream(FileToOpen) 'Функция которая считывает из файла строки с числами матрицы и записывает их в двумерный массив
                CurrentOpenFileName = OFD1.FileName 'Имя открытого файла
                TextBox1.Text = DGV1.RowCount : TextBox2.Text = DGV1.ColumnCount
                Me.SaveAsMenuButton.Enabled = True
                Me.SaveMenuButton.Enabled = True
            End If
        Catch ex As Exception
            MsgBox(ex.Message, MsgBoxStyle.OkOnly Or MsgBoxStyle.Exclamation, "Ошибка!")
            Me.Cursor = Cursors.Arrow
        End Try
    End Sub
предположим я открыл файл, поле этого я не могу его сохранить под тем же именем, т.к. выпадает исключение:

Необработанное исключение типа "System.IO.IOException" в mscorlib.dll
Дополнительные сведения: Процесс не может получить доступ к файлу "C:\Users\Иван\Desktop\Матрица A.mtrx", так как этот файл используется другим процессом.

Если я создам матрицу и сохраню её при помощи при помощи "Сохранить как..." (т.е. при помощи SaveFileDialog), то после этого я могу сохранять при помощи этой же кнопки (процедуры и того же StreamWriter) в файл с тем же именем, а вот при помощи кнопки Сохранить (без SaveFileDialog) я уже не могу сохранить файл, т.к. он сохраняется под тем же именем, что был сохранен через "Сохранить как...". Проблема в том что в каждой кнопке (процедуре) свой StreamWriter или StreamReader. Это можно исправить тем что прописать Имя_СтримРидера.Close(), но тогда пользователь сможет вручную удалять, перемещать ил переименовывать файлы, чего я не хочу ему позволять как было упомянуто выше.

Я не знаю что делать!!! Как закрыть перед сохранением StreamReader, с помощью которого был открыть файл, ведь он же в другой процедуре и к нему нет доступа??? Остаётся только объявить все эти Стримы как глобальные, но тогда я не смогу указать имя имя файла, .т.к. оно становится известно только после запуска процедуры на сохранение или открытие файла, а глобальные переменные создаются при запуске приложения.

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

P.S.: Если попытаться удалить или переименовать файл открытый в моей программе, то вылезает сообщение:
"Действие не может быть выполнено, так как это файл открыт в "vshost32.exe". Закройте файл и повторите попытку." А моя программа называется matrixcalc.exe. Не знаю скажет ли Вам это о чем-либо, но думаю это важная информация, т.к. если попытаться закрыть файл, открытый в Word 2013, будет написано что файл открыт в "Word (классическое приложение)"
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
30.01.2015, 22:49
Ответы с готовыми решениями:

Как правильно вызывать функции, которые используются в строгом порядке?
Изучаю Python. Написал следующие функции, которые должны идти по порядку для правильного флова программы: 1) чтение json конфиг файла;...

Как правильно сохранять файлы на сервере. Spring MVC
Хелп ми!! Как правильно сохранить картинку в базе или в файловой системе? Сейчас я сохраняю по пути что мне дает getRealPath(), но при...

Как правильно сохранять файлы Аccess через SaveFileDialog()?
Stream myStream; SaveFileDialog saveFileDialog1 = new SaveFileDialog(); saveFileDialog1.Filter = "DB...

4
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18307 / 14231 / 5368
Регистрация: 17.03.2014
Сообщений: 28,903
Записей в блоге: 1
31.01.2015, 10:12
Лучший ответ Сообщение было отмечено jugger_off как решение

Решение

jugger_off, уверен ли ты что это действительно необходимо? Если все данные хранятся в памяти, то какая разница сможет ли пользователь удалить файл. При открытии ты его читаешь целиком в память, при сохранении записываешь. Что происходит с файлом в этом промежутке не наше дело.

Если это все-таки необходимо, то можно сделать так (.NET 4.5 и выше):
Кликните здесь для просмотра всего текста
VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
Class MyForm
    Inherits System.Windows.Forms.Form
    
    Private stream As FileStream
    
    Private Sub OpenFile(ByVal fileToOpen As String)
        If stream IsNot Nothing Then
            If stream.Name = fileToOpen Then
                ' Поток для указанного пути уже был открыт
                stream.Position = 0
            Else
                stream.Close()
                stream = New FileStream(fileToOpen, FileMode.Open, FileAccess.ReadWrite, FileShare.None)
            End If
        End If
        
        ' Используеи конструктор StreamReader с аргументом leaveOpen = True
        ' Это позволит закрыть StreamReader не закрывая нижележащий поток
        Using reader As New StreamReader(stream, Encoding.UTF8, True, 16*1024, True)
            ' Читаем данные
            ' ...
        End Using
    End Sub
    
    Private Sub SaveFile(ByVal fileToOpen As String)
        If stream IsNot Nothing Then
            If stream.Name = fileToOpen Then
                ' Поток для указанного пути уже был открыт
                stream.Position = 0
                stream.SetLength(0)
            Else
                stream.Close()
                stream = New FileStream(fileToOpen, FileMode.Create, FileAccess.ReadWrite, FileShare.None)
            End If
        End If
        
        ' Используеи конструктор StreamWriter с аргументом leaveOpen = True
        ' Это позволит закрыть StreamWriter не закрывая нижележащий поток
        Using writer As New StreamWriter(stream, Encoding.UTF8, 16*1024, True)
            ' Записываем данные
            ' ...
        End Using
    End Sub
    
    Private Sub HandleFormClosed(sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed
        If stream IsNot Nothing Then
            stream.Close()
        End If
    End Sub
End Class

Для более старых версий .NET делаем так:
Кликните здесь для просмотра всего текста
VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
Class MyForm
    Inherits System.Windows.Forms.Form
    
    Private stream As FileStream
    
    Private Sub OpenFile(ByVal fileToOpen As String)
        If stream IsNot Nothing Then
            If stream.Name = fileToOpen Then
                ' Поток для указанного пути уже был открыт
                stream.Position = 0
            Else
                stream.Close()
                stream = New FileStream(fileToOpen, FileMode.Open, FileAccess.ReadWrite, FileShare.None)
            End If
        End If
        
        Using reader As New StreamReader(stream)
            ' Читаем данные
            ' ...
        End Using
        
        ' Открываем поток заново
        stream = New FileStream(fileToOpen, FileMode.Open, FileAccess.ReadWrite, FileShare.None)
    End Sub
    
    Private Sub SaveFile(ByVal fileToOpen As String)
        If stream IsNot Nothing Then
            If stream.Name = fileToOpen Then
                ' Поток для указанного пути уже был открыт
                stream.Position = 0
                stream.SetLength(0)
            Else
                stream.Close()
                stream = New FileStream(fileToOpen, FileMode.Create, FileAccess.ReadWrite, FileShare.None)
            End If
        End If
        
        Using writer As New StreamWriter(stream)
            ' Записываем данные
            ' ...
        End Using
        
        ' Открываем поток заново
        stream = New FileStream(fileToOpen, FileMode.Open, FileAccess.ReadWrite, FileShare.None)
    End Sub
    
    Private Sub HandleFormClosed(sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed
        If stream IsNot Nothing Then
            stream.Close()
        End If
    End Sub
End Class

Обработчики SaveAsMenuButton_Click и OpenMenuButton_Click будут вызывать OpenFile и SaveFile соответственно. Таким образом ты отделишь логику работы с файлом от работы с UI.

Цитата Сообщение от jugger_off Посмотреть сообщение
P.S.: Если попытаться удалить или переименовать файл открытый в моей программе, то вылезает сообщение: "Действие не может быть выполнено, так как это файл открыт в "vshost32.exe". Закройте файл и повторите попытку." А моя программа называется matrixcalc.exe.
Это всего лишь говорит что ты запускаешь программу из под Visual Studio которая для работы отладчика запускает процесс vshost32. При запуске через проводник будет видно настоящее имя программы.
2
 Аватар для jugger_off
13 / 13 / 3
Регистрация: 21.12.2013
Сообщений: 225
31.01.2015, 10:54  [ТС]
уверен ли ты что это действительно необходимо?
Не уверен, т.к. все и так хорошо работало и даже если файл удалить, то он все равно создастся заново. Просто хотелось знать почему в других программа не так как у меня. Судя по вашему коду, мне еще есть чему учиться. Как же много всяких классов, конструкций (таких как Usning...). Просто боюсь что приду на работу через год как доучусь, а меня от туда пошлют на фиг. Сколько Вам лет? Вы всю жизнь этим занимаетесь? У меня есть учебник Алекс Макки - Введение в .NET 4.0 и Visual Studio 2010 для профессионалов. Я его когда первый раз открыл, у меня глаза на лоб залезли. Как думаете стоит начать его читать?
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18307 / 14231 / 5368
Регистрация: 17.03.2014
Сообщений: 28,903
Записей в блоге: 1
31.01.2015, 11:22
Цитата Сообщение от jugger_off Посмотреть сообщение
Не уверен, т.к. все и так хорошо работало и даже если файл удалить, то он все равно создастся заново. Просто хотелось знать почему в других программа не так как у меня.
Во-первых, не во всех. Во-вторых, не надо заниматься слепым копированием того что не понятно. Держать файл постоянно открытым есть смысл если он слишком большой чтобы хранить его в памяти. Или если он имеет сложную структуру и программе необходимо читать/записывать файл частями обеспечивая целостность данных. И т.д. и т.п. Раз твоя программа уже нормально работает, то и исправлять нечего.

Цитата Сообщение от jugger_off Посмотреть сообщение
Судя по вашему коду, мне еще есть чему учиться. Как же много всяких классов, конструкций (таких как Usning...)
Работа программиста связана с постоянной учебой. Только начинающие думают что знают всё. Опытный программист знает и умеет много и одновременно понимает что существует много еще неизученного. Посмотри например матрицу компетентности программиста.

Цитата Сообщение от jugger_off Посмотреть сообщение
Сколько Вам лет?
Много. Я помогал Ленину бревно на субботнике нести.

Цитата Сообщение от jugger_off Посмотреть сообщение
Вы всю жизнь этим занимаетесь?
Нет. Первые пару лет у меня были другие интересы.

Цитата Сообщение от jugger_off Посмотреть сообщение
У меня есть учебник Алекс Макки - Введение в .NET 4.0 и Visual Studio 2010 для профессионалов. Я его когда первый раз открыл, у меня глаза на лоб залезли. Как думаете стоит начать его читать?
Не читал эти книгу, но раз у тебя глаза полезли на лоб, то значит читать надо.
3
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
03.02.2015, 12:20
Чтобы нужно записать данные в открытый файл, его не нужно открывать заново, нужно лишь воспользоваться уже созданным файловым потоком.
Итак. Открываем файл файловым потоком FileStream. Из его основе создаём два текстовых потока StreamReader и StreamWriter, один для чтения, второй для записи.
Если нужно записать данные в файл с самого начала, можно использовать метод Seek ранее созданного объекта FileStream.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
03.02.2015, 12:20
Помогаю со студенческими работами здесь

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

Текстовые файлы. Вывести на экран все идентификаторы типов, которые используются в программе
Вывести на экран все идентификаторы типов ,которые используются в программе. В файл записываем любую программу на паскале, работающую...

Как сделать так чтобы число которое записано в файл проверялось с текущим месяцем и с текущим днём?
Как сделать так что бы число которое записано в файл проверялось с текущем месяцем и с текшим днём ?

Как открыть ссылку конкретным приложением?
нужно открывать ссылку конкретно приложением "Google Карты".... пытаюсь делать так: String linkCoor =...

Как правильно сохранять настройки?
Доброго времени суток бойцы ... Подскажите такую штуку Хочу в файл настроек сохранить массив int, а в выборе типа переменной нету...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru