Visual C++: почему не сохраняется файл? :)
Типовое мучение новичков - загрузили картинку в PictureBox
, например,
Image ^ Img = gcnew Bitmap("123.jpg"); pictureBox1->Image = Img;
затем что-то с ней сделали и хотим сохранить обратно. Увы, ничего не выходит, а системное сообщение об ошибке гласит лишь:
В GDI+ возникла ошибка общего вида.
Ну и с другими компонентами бывает подобное же. Нетрудно догадаться, в чём состоит проблема - просто файл, который мы хотим переписать, всё ещё остаётся открытым и возникает ошибка совместного доступа. Многие упрощенные методы работы с файлами из GDI+ блокируют доступ к файлам. Такие методы имеет смысл использовать только для одноразовых файловых операций (когда нужно один раз прочитать или записать данные, и не более того).
Если вы собираетесь переписывать файл, то так, как показано ниже, делать не нужно, всё откроется, но при переписывании получите проблему:
openFileDialog1->ShowDialog(); if (openFileDialog1->FileName != "" && openFileDialog1->FileName != nullptr) { Image ^ Img; try { Img = gcnew Bitmap(openFileDialog1->FileName); } catch (Exception^ e) { System::Windows::Forms::MessageBox::Show(e->Message + "\nНе удалось открыть файл", "Ошибка", MessageBoxButtons::OK, MessageBoxIcon::Exclamation); return; } pictureBox1->Image = Img; }
Теперь попытка переписать файл обычными средствами
try { pictureBox1->Image->Save(openFileDialog1->FileName); //Сохраняем под именем из диалога открытия файла //или вместо этой строки 2 строки ниже: //Bitmap ^bitmap1 = gcnew Bitmap(pictureBox1->Image); //bitmap1->Save (openFileDialog1->FileName); } catch (Exception^ e) { MessageBox::Show(e->Message + "\nНе удалось сохранить файл", "Ошибка", MessageBoxButtons::OK, MessageBoxIcon::Exclamation); return; }
приведёт лишь к показанной выше ошибке. Часто рекомендуемое в инете
delete pictureBox1->Image; pictureBox1->Image = nullptr;
- аналог работающего в C#
pictureBox1.Image.Dispose();
на C++ не поможет.
А решение таково: для нормальных операций с файлами используйте FileStream, чтобы контролировать весь процесс.
Вот правильная версия кода для открытия файла:
openFileDialog1->ShowDialog(); if (openFileDialog1->FileName != "" && openFileDialog1->FileName != nullptr) { System::IO::FileStream ^ file; try { file = gcnew System::IO::FileStream(openFileDialog1->FileName, System::IO::FileMode::Open, System::IO::FileAccess::Read, System::IO::FileShare::Inheritable); } catch (Exception^ e) { System::Windows::Forms::MessageBox::Show(e->Message + "\nНе удалось открыть файл", "Ошибка", MessageBoxButtons::OK, MessageBoxIcon::Exclamation); return; } pictureBox1->Image = Image::FromStream(file); file->Close(); }
Теперь показанное выше сохранение файла под тем же именем, под которым он был открыт, работает в любой из 2 версий операторов сохранения.
07.10.2015, 16:24 [8018 просмотров]