Realizar E/S de archivos básicos en Visual C++

En este artículo se describe cómo realizar operaciones básicas de entrada y salida de archivos (E/S) en Microsoft Visual C++ o en Visual C++ .NET.

Versión original del producto: Visual C++
Número de KB original: 307398

Resumen

Si no está familiarizado con .NET Framework, verá que el modelo de objetos para las operaciones de archivos en .NET Framework es similar al FileSystemObject que es popular entre muchos desarrolladores de Visual Studio.

En este artículo se hace referencia a los siguientes espacios de nombres de biblioteca de clases de .NET Framework:

  • System::ComponentModel
  • System::Windows::Forms
  • System::Drawing

Todavía puede usar en FileSystemObject .NET Framework. FileSystemObject Dado que es un componente del modelo de objetos de componente (COM), .NET Framework requiere que el acceso al objeto sea a través de la capa de interoperabilidad. .NET Framework genera un contenedor para el componente si desea usarlo. Sin embargo, la File clase , la FileInfo clase , las Directoryclases , DirectoryInfo y otras clases relacionadas de .NET Framework ofrecen funcionalidad que no está disponible con FileSystemObject, sin la sobrecarga de la capa de interoperabilidad.

Operaciones de E/S de archivo demostradas

En los ejemplos de este artículo se describen las operaciones básicas de E/S de archivo. En la sección ejemplo paso a paso se describe cómo crear un programa de ejemplo que muestre las seis operaciones de E/S de archivo siguientes:

Leer un archivo de texto

El código de ejemplo siguiente usa una StreamReader clase para leer un archivo de texto. El contenido del archivo se agrega a un control ListBox. El try...catch bloque se usa para alertar al programa si el archivo está vacío. Hay muchas maneras de determinar cuándo se alcanza el final del archivo; en este ejemplo se usa el Peek método para examinar la siguiente línea antes de leerla.

listBox1->Items->Clear();
try
{
    String* textFile = String::Concat(windir, (S"\\mytest.txt"));
    StreamReader *reader=new  StreamReader(textFile);
    do
    {
        listBox1->Items->Add(reader->ReadLine());
    } while(reader->Peek() != -1);
}

catch (System::Exception *e)
{
    listBox1->Items->Add(e);
}

En Visual C++, debe agregar la opción del compilador de compatibilidad con Common Language Runtime (/clr:oldSyntax) para compilar correctamente el ejemplo de código anterior como C++ administrado. Para agregar la opción del compilador de compatibilidad con Common Language Runtime, siga estos pasos:

  1. Haga clic en Proyectoy, a continuación, haga clic en <Propiedades de> NombreDeProyecto.

    Nota:

    <ProjectName> es un marcador de posición para el nombre del proyecto.

  2. Expanda Propiedades de configuracióny, a continuación, haga clic en General.

  3. En el panel derecho, haga clic para seleccionar Compatibilidad con Common Language Runtime, Sintaxis antigua (/clr:oldSyntax) en la configuración del proyecto de soporte técnico de Common Language Runtime.

  4. En el cuadro Plan de marcado (contexto telefónico), haga clic en Examinar para buscar el plan de marcado del usuario.

Escribir un archivo de texto

Este código de ejemplo usa una StreamWriter clase para crear y escribir en un archivo. Si tiene un archivo existente, puede abrirlo de la misma manera.

StreamWriter* pwriter = new StreamWriter(S"c:\\KBTest.txt");
pwriter->WriteLine(S"File created using StreamWriter class.");
pwriter->Close();
listBox1->Items->Clear();
String *filew = new String(S"File Written to C:\\KBTest.txt");
listBox1->Items->Add(filew);

Visualización de la información del archivo

Este código de ejemplo usa una FileInfo clase para acceder a las propiedades de un archivo. Notepad.exe se usa en este ejemplo. Las propiedades aparecen en un control ListBox.

listBox1->Items->Clear();
String* testfile = String::Concat(windir, (S"\\notepad.exe"));
FileInfo *pFileProps =new FileInfo(testfile);

listBox1->Items->Add(String::Concat(S"File Name = ", (pFileProps->get_FullName())));
listBox1->Items->Add(String::Concat(S"Creation Time = ", (pFileProps->get_CreationTime()).ToString()));
listBox1->Items->Add(String::Concat(S"Last Access Time = " ,(pFileProps->get_LastAccessTime()).ToString()));
listBox1->Items->Add(String::Concat(S"Last Write Time = ", (pFileProps->get_LastWriteTime()).ToString()));
listBox1->Items->Add(String::Concat(S"Size = ", (pFileProps->get_Length()).ToString()));

Enumeración de unidades de disco

Este código de ejemplo usa las Directory clases y Drive para enumerar las unidades lógicas de un sistema. En este ejemplo, los resultados aparecen en un control ListBox.

listBox1->Items->Clear();
String* drives[] = Directory::GetLogicalDrives();
int numDrives = drives->get_Length();
for (int i=0; i<numDrives; i++)
{
    listBox1->Items->Add(drives[i]);
}

Enumerar subcarpetas

Este código de ejemplo usa el GetDirectories método de la Directory clase para obtener una lista de carpetas.

listBox1->Items->Clear();
String* dirs[] = Directory::GetDirectories(windir);
int numDirs = dirs->get_Length();
for (int i=0; i<numDirs; i++)
{
    listBox1->Items->Add(dirs[i]);
}

Enumerar archivos

Este código de ejemplo usa el GetFiles método de la Directory clase para obtener una lista de archivos.

listBox1->Items->Clear();
String* files[]= Directory::GetFiles(this->windir);
int numFiles = files->get_Length();
for (int i=0; i<numFiles; i++)
{
    listBox1->Items->Add(files[i]);
}

Muchas cosas pueden salir mal cuando un usuario obtiene acceso a los archivos. Es posible que los archivos no existan, que los archivos estén en uso o que los usuarios no tengan derechos sobre los archivos de carpetas a los que están intentando acceder. Tenga en cuenta estas posibilidades al escribir código para controlar las excepciones que se pueden generar.

Ejemplo paso a paso

  1. Inicie Visual Studio .NET.

  2. En el menú Archivo, elija Nuevo y, a continuación, haga clic en Proyecto.

  3. En Tipos de proyecto, haga clic en Proyectos de Visual C++. En la sección Plantillas, haga clic en Windows Forms aplicación (.NET).

  4. Escriba KB307398 en el cuadro Nombre , escriba C:\ en el cuadro Ubicación y haga clic en Aceptar.

  5. Abra el formulario Form1 en la vista Diseño y presione F4 para abrir la ventana Propiedades .

  6. En la ventana Propiedades , expanda la carpeta Tamaño . En el cuadro Ancho , escriba 700. En el cuadro Alto , escriba 320.

  7. Agregue un control ListBox y seis controles Button a Form1.

    Nota:

    Para ver el cuadro de herramientas, haga clic en Cuadro de herramientas en el menú Ver .

  8. En la ventana Propiedades , cambie las propiedades Ubicación, Nombre, Tamaño, TabIndex y Texto de estos controles de la siguiente manera:

    Id. de control Ubicación Nombre Size TabIndex Texto
    button1 500, 32 button1 112, 23 1 Leer archivo de texto
    button2 500, 64 button2 112, 23 2 Escribir archivo de texto
    button3 500, 96 button3 112, 23 3 Ver información de archivo
    button4 500, 128 button4 112, 23 4 Enumerar unidades
    button5 500, 160 button5 112, 23 5 Enumerar subcarpetas
    button6 500, 192 button6 112, 23 6 Enumerar archivos
    listBox1 24, 24 listBox1 450, 200 0 listBox1
  9. Abra el archivo Form1.h . En la declaración de Form1 clase, declare una variable privada String con el código siguiente:

    private:
    String *windir;
    
  10. En el constructor de Form1 clase, agregue el código siguiente:

    windir = System::Environment::GetEnvironmentVariable("windir");
    
  11. Para realizar operaciones de salida de entrada de archivo, agregue el espacio de System::IO nombres.

  12. Presione MAYÚS+F7 para abrir Form1 en la vista Diseño. Haga doble clic en el botón Leer archivo de texto y pegue el código siguiente:

    // How to read a text file:
    // Use try...catch to deal with a 0 byte file or a non-existant file.
    listBox1->Items->Clear();
    
    try
    {
        String* textFile = String::Concat(windir, (S"\\mytest.txt"));
        StreamReader *reader=new  StreamReader(textFile);
        do
        {
            listBox1->Items->Add(reader->ReadLine());
        } while(reader->Peek() != -1);
    }
    catch(FileNotFoundException *ex)
    {
        listBox1->Items->Add(ex);
    }  
    
    catch (System::Exception *e)
    {
        listBox1->Items->Add(e);
    }
    
  13. En la vista Diseño de Form1, haga doble clic en el botón Escribir archivo de texto y, a continuación, pegue el código siguiente:

    // This demonstrates how to create and to write to a text file.
    StreamWriter* pwriter = new StreamWriter(S"c:\\KBTest.txt");
    pwriter->WriteLine(S"The file was created by using the StreamWriter class.");
    pwriter->Close();
    listBox1->Items->Clear();
    String *filew = new String(S"File written to C:\\KBTest.txt");
    listBox1->Items->Add(filew);
    
  14. En la vista Diseño de Form1, haga doble clic en el botón Ver información de archivo y, a continuación, pegue el código siguiente en el método :

    // This code retrieves file properties. The example uses Notepad.exe.
    listBox1->Items->Clear();
    String* testfile = String::Concat(windir, (S"\\notepad.exe"));
    FileInfo *pFileProps =new FileInfo(testfile);
    
    listBox1->Items->Add(String::Concat(S"File Name = ", (pFileProps->get_FullName())));
    listBox1->Items->Add(String::Concat(S"Creation Time = ", (pFileProps->get_CreationTime()).ToString()));
    listBox1->Items->Add(String::Concat(S"Last Access Time = " ,(pFileProps->get_LastAccessTime()).ToString()));
    listBox1->Items->Add(String::Concat(S"Last Write Time = ", (pFileProps->get_LastWriteTime()).ToString()));
    listBox1->Items->Add(String::Concat(S"Size = ", (pFileProps->get_Length()).ToString()));
    
  15. En la vista Diseño de Form1, haga doble clic en el botón Unidades de lista y, a continuación, pegue el código siguiente:

    // This demonstrates how to obtain a list of disk drives.
    listBox1->Items->Clear();
    String* drives[] = Directory::GetLogicalDrives();
    int numDrives = drives->get_Length();
    for (int i=0; i<numDrives; i++)
    {
        listBox1->Items->Add(drives[i]);
    }
    
  16. En la vista Diseño de Formulario1, haga doble clic en el botón Enumerar subcarpetas y, a continuación, pegue el código siguiente:

    // This code obtains a list of folders. This example uses the Windows folder.
    listBox1->Items->Clear();
    String* dirs[] = Directory::GetDirectories(windir);
    int numDirs = dirs->get_Length();
    for (int i=0; i<numDirs; i++)
    {
        listBox1->Items->Add(dirs[i]);
    }
    
  17. En la vista Diseño de Formulario1, haga doble clic en el botón Archivos de lista y, a continuación, pegue el código siguiente:

    // This code obtains a list of files. This example uses the Windows folder.
    listBox1->Items->Clear();
    String* files[]= Directory::GetFiles(this->windir);
    int numFiles = files->get_Length();
    for (int i=0; i<numFiles; i++)
    {
        listBox1->Items->Add(files[i]);
    }
    
  18. Para compilar y ejecutar el programa, presione CTRL+F5.

Ejemplo de código completo

//Form1.h
#pragma once

namespace KB307398
{
    using namespace System;
    using namespace System::IO;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;

    /// <summary>
    /// Summary for Form1
    /// WARNING: If you change the name of this class, you will need to change the
    ///          'Resource File Name' property for the managed resource compiler tool
    ///          associated with all .resx files this class depends on.  Otherwise,
    ///          the designers will not be able to interact properly with localized
    ///          resources associated with this form.
    /// </summary>
    public __gc class Form1 : public System::Windows::Forms::Form
    {
        private:
        String *windir;
        public:
        Form1(void)
        {
            windir = System::Environment::GetEnvironmentVariable("windir");
            InitializeComponent();
        }

        protected:
        void Dispose(Boolean disposing)
        {
            if (disposing && components)
            {
            components->Dispose();
            }
            __super::Dispose(disposing);
        }
        private: System::Windows::Forms::Button *  button1;
        private: System::Windows::Forms::Button *  button2;
        private: System::Windows::Forms::Button *  button3;
        private: System::Windows::Forms::Button *  button4;
        private: System::Windows::Forms::Button *  button5;
        private: System::Windows::Forms::Button *  button6;
        private: System::Windows::Forms::ListBox *  listBox1;

        private:
        /// <summary>
        /// Required designer variable.
        /// </summary>
        System::ComponentModel::Container * components;

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        void InitializeComponent(void)
        {
            this->button1 = new System::Windows::Forms::Button();
            this->button2 = new System::Windows::Forms::Button();
            this->button3 = new System::Windows::Forms::Button();
            this->button4 = new System::Windows::Forms::Button();
            this->button5 = new System::Windows::Forms::Button();
            this->button6 = new System::Windows::Forms::Button();
            this->listBox1 = new System::Windows::Forms::ListBox();
            this->SuspendLayout();
            // button1
            this->button1->Location = System::Drawing::Point(500, 32);
            this->button1->Name = S"button1";
            this->button1->Size = System::Drawing::Size(112, 23);
            this->button1->TabIndex = 1;
            this->button1->Text = S"Read Text File";
            this->button1->Click += new System::EventHandler(this, button1_Click);
            // button2
            this->button2->Location = System::Drawing::Point(500, 64);
            this->button2->Name = S"button2";
            this->button2->Size = System::Drawing::Size(112, 23);
            this->button2->TabIndex = 2;
            this->button2->Text = S"Write Text File";
            this->button2->Click += new System::EventHandler(this, button2_Click);
            // button3
            this->button3->Location = System::Drawing::Point(500, 96);
            this->button3->Name = S"button3";
            this->button3->Size = System::Drawing::Size(112, 23);
            this->button3->TabIndex = 3;
            this->button3->Text = S"View File Information";
            this->button3->Click += new System::EventHandler(this, button3_Click);
            // button4
            this->button4->Location = System::Drawing::Point(500, 128);
            this->button4->Name = S"button4";
            this->button4->Size = System::Drawing::Size(112, 23);
            this->button4->TabIndex = 4;
            this->button4->Text = S"List Drives";
            this->button4->Click += new System::EventHandler(this, button4_Click);
            // button5
            this->button5->Location = System::Drawing::Point(500, 160);
            this->button5->Name = S"button5";
            this->button5->Size = System::Drawing::Size(112, 23);
            this->button5->TabIndex = 5;
            this->button5->Text = S"List Subfolders";
            this->button5->Click += new System::EventHandler(this, button5_Click);
            // button6
            this->button6->Location = System::Drawing::Point(500, 188);
            this->button6->Name = S"button6";
            this->button6->Size = System::Drawing::Size(112, 23);
            this->button6->TabIndex = 6;
            this->button6->Text = S"List Files";
            this->button6->Click += new System::EventHandler(this, button6_Click);
            // listBox1
            this->listBox1->Location = System::Drawing::Point(24, 24);
            this->listBox1->Name = S"listBox1";
            this->listBox1->Size = System::Drawing::Size(450, 199);
            this->listBox1->TabIndex = 0;
            // Form1
            this->AutoScaleBaseSize = System::Drawing::Size(5, 13);
            this->ClientSize = System::Drawing::Size(692, 293);
            this->Controls->Add(this->listBox1);
            this->Controls->Add(this->button6);
            this->Controls->Add(this->button5);
            this->Controls->Add(this->button4);
            this->Controls->Add(this->button3);
            this->Controls->Add(this->button2);
            this->Controls->Add(this->button1);
            this->Name = S"Form1";
            this->Text = S"Form1";
            this->ResumeLayout(false);
        }
        private: System::Void button1_Click(System::Object *  sender, System::EventArgs *  e)
        {
            // This code shows how to read a text file.
            // The try...catch code is to deal with a 0 byte file or a non-existant file.
            listBox1->Items->Clear();

            try
            {
                String* textFile = String::Concat(windir, (S"\\mytest.txt"));
                StreamReader *reader=new  StreamReader(textFile);
                do
                {
                    listBox1->Items->Add(reader->ReadLine());
                }
                while(reader->Peek() != -1);
            }
            catch(FileNotFoundException *ex)
            {
                listBox1->Items->Add(ex);
            }

            catch (System::Exception *e)
            {
                listBox1->Items->Add(e);
            }
        }

        private: System::Void button2_Click(System::Object *  sender, System::EventArgs *  e)
        {
            // This code demonstrates how to create and to write to a text file.
            StreamWriter* pwriter = new StreamWriter(S"c:\\KBTest.txt");
            pwriter->WriteLine(S"The file was created by using the StreamWriter class.");
            pwriter->Close();
            listBox1->Items->Clear();
            String *filew = new String(S"The file was written to C:\\KBTest.txt");
            listBox1->Items->Add(filew);
        }

        private: System::Void button3_Click(System::Object *  sender, System::EventArgs *  e)
         {
            // This code retrieves file properties. This example uses Notepad.exe.
            listBox1->Items->Clear();
            String* testfile = String::Concat(windir, (S"\\notepad.exe"));
            FileInfo *pFileProps  =new FileInfo(testfile);

            listBox1->Items->Add(String::Concat(S"File Name = ", (pFileProps->get_FullName() )) );
            listBox1->Items->Add(String::Concat(S"Creation Time = ", (pFileProps->get_CreationTime() ).ToString()) );
            listBox1->Items->Add(String::Concat(S"Last Access Time = "  ,(pFileProps->get_LastAccessTime() ).ToString()) );
            listBox1->Items->Add(String::Concat(S"Last Write Time = ", (pFileProps->get_LastWriteTime() ).ToString()) );
            listBox1->Items->Add(String::Concat(S"Size = ", (pFileProps->get_Length() ).ToString()) );
        }

        private: System::Void button4_Click(System::Object *  sender, System::EventArgs *  e)
        {
            // The code demonstrates how to obtain a list of disk drives.
            listBox1->Items->Clear();
            String* drives[] = Directory::GetLogicalDrives();
            int numDrives = drives->get_Length();
            for (int i=0; i<numDrives; i++)
            {
                listBox1->Items->Add(drives[i]);
            }
        }

        private: System::Void button5_Click(System::Object *  sender, System::EventArgs *  e)
        {
            // This code obtains a list of folders. This example uses the Windows folder.
            listBox1->Items->Clear();
            String* dirs[] = Directory::GetDirectories(windir);
            int numDirs = dirs->get_Length();
            for (int i=0; i<numDirs; i++)
            {
                listBox1->Items->Add(dirs[i]);
            }
        }

        private: System::Void button6_Click(System::Object *  sender, System::EventArgs *  e)
        {
            // This code obtains a list of files. This example uses the Windows folder.
            listBox1->Items->Clear();
            String* files[]= Directory::GetFiles(this->windir);
            int numFiles = files->get_Length();
            for (int i=0; i<numFiles; i++)
            {
                listBox1->Items->Add(files[i]);
            }
        }
    };
}

//Form1.cpp
#include "stdafx.h"
#include "Form1.h"
#include <windows.h>

using namespace KB307398;

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
    System::Threading::Thread::CurrentThread->ApartmentState = System::Threading::ApartmentState::STA;
    Application::Run(new Form1());
    return 0;
}

Referencias

Para obtener más información, visite Soporte técnico de Microsoft. Para obtener más información sobre cómo crear formularios Windows Forms en extensiones administradas para C++, vea el ejemplo de la ManagedCWinFormWiz Ayuda de .NET de Visual Studio.