Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Загрузка файла и обработка в памяти


Автор: Div 27.6.2005, 20:35
Люди помогите! Возникла такая проблемма: надо загрузить файл в отведенную под него память и редактировать его там же. Чтобы можно было указать смещение и записать в переменную типа int байт, который находиться по этому смещению. Помогите плз. Буду очень благодарен!

Автор: Nuzur 27.6.2005, 21:09
А в чем проблема? Можно в подробностях?
Дело в том что у тебе есть кусок памяти, значит на него есть указатель, следовательно ты можеш его использовать...
1-е что я могу так сказать...да ничего не могу, порверь у тебя этот участок не онли рид случайно.

Автор: Div 27.6.2005, 21:16
Проблемма в том, что я новичек! Я не умею выделять память и загружать туда файл. Если можешь скинь код!

Автор: Nuzur 27.6.2005, 23:16
Цитата(Div @ 27.6.2005, 21:16)
Проблемма в том, что я новичек! Я не умею выделять память и загружать туда файл. Если можешь скинь код!

Конкретное решение зависит от поставленых задач.
Ты поставил общюю проблему, короче уточни, что именно тебе нужно, в духе типа это считываю изменя. так-то и кладу сюда.

Автор: Nuzur 27.6.2005, 23:27
Цитата(Div @ 27.6.2005, 21:16)
Проблемма в том, что я новичек! Я не умею выделять память и загружать туда файл. Если можешь скинь код!

Конкретное решение зависит от поставленых задач.
Ты поставил общюю проблему, короче уточни, что именно тебе нужно, в духе типа это считываю изменя. так-то и кладу сюда.

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

1 Буффер, масив или что там теде нуна думаю создаш са smile
2. Считываем:

FILE *stream;

//Открываем файл
stream = fopen(Path + Name, "r" )

//Читаем из него
fgets(Str.GetBuffer(fSize),fSize, stream)

После чего выполняем все необходимые мат. операции или что там надо.
//записываем в файл
помоему fputs, почитай в МСДН, щас нет под рукой

//Закрываем
fclose(stream);

Вот пример. Хотя все может быть иначе, и как я писал раньше, все зависит от того что тебе надобно.
Что неясно пиши, попробую помочь.

Автор: codelord 28.6.2005, 01:39
Держи, надеюсь то, что тебе нужно.
Писал в духе Си для одаренных. smile

Код

//для того чтобы выделить память нужно знать сколько ее нужно  а посему надо сначала определить вес твоего файла.
#include<stdio.h>
#include <shlobj.h>
void main()
     {
      FILE *in;
      in=fopen("begin.txt","rb"); // думаю понятно что этот файл должен находиться в одной папке с программой
      int i=0;  // ею мы посчитаем размер твоего файла в байтах
      int c; //это переменная доступа к байтам.
      while((c=getc(in))!=EOF) i++;
      int *mas=new int[i]; //создали массив данных в памяти.
      fseek(in,0l,SEEK_SET); //возвращаем поток в начало.
      i=0;
      while((c=getc(in))!=EOF) 
                              {
                              mas[i]=c; // закидываем файл в массив в памяти.
                              i++;
                              }
      fclose(in); //закрываем поток т.к. больше не нужен.
      // все готово чтобы использовать эту память файл весь в памяти
 
     //например обратиться к 1 байту нашего массива
     printf("%d\n ",mas[0]);
     //или так
          Sleep(2000); // чтобы было видно результат, можно убрать
     i=mas[0]+mas[1]+mas[2]+mas[3];
     printf("%d\n ",i);
        Sleep(5000);
    }



Автор: sergejzr 28.6.2005, 01:59
codelord,

вот так можно узнать имя файла smile

filelength(fileno(in));

Автор: Mayk 28.6.2005, 09:33
Можно еще вот так, раз файл уже открыт, к тому же это портабельно(filelength нет в c99, в sus2. Не нашелся он в /usr/include'ах):
Код

long curpos = ftell(file);
fseek(f,0,SEEK_END);
fileLength = ftell(file);
fseek(f, curpos, SEEK_SET);


А еще можно GetFileSize в мастдаях.

а еще можно через scan, но это как-то.... слишком


Автор: sergejzr 28.6.2005, 12:49
Чтобы совсем портабельно, надо так:
Это точно идёт на WIN, Linux, Solaris, AIX, DIGITAL UNIX, SCO. Потомц что мне приходилось кроссплатформенно писать для них. А насчёт filelength, тоже на большинстве идёт без проблем. Просто я считаю не оптимальным бегать указателем по файлу, когда эта инфа давно вырешена и лежит, осталось только взять.
Код

#include <sys/stat.h>
long fileLength(const char* filename)
{
    struct stat buf;
 
    if(stat(filename, &buf) != 0)
    {
        /* Произошла проблема при получении информации */
        return -1;
    }
    return (buf.st_size);
}





Автор: Guest 29.6.2005, 20:00
Спасибушки большое smile Очень рад, что мне помогли. А то я к программированию под PC никак привыкнуть не могу! И литературы подходящей нет!

Автор: Div 29.6.2005, 20:03
Спасибо за разъяснения! Всё идет отлично! Разобрался как следует. СПАСИБО!

Автор: Div 29.6.2005, 22:15
Unregistred был я

Автор: Div 11.7.2005, 21:14
Немного поразбиравшись, я пришел к выводу, что загружать и далее работать с файлом в памяти лучше таким образом:

Код

#include <commdlg.h>

void                            SSOpenFile(HWND);

/*******************************************************\
|       Name: SSOpenFile()                              |
|       NOTE: Загружает файл в память                   |
\*******************************************************/
void SSOpenFile(HWND hwnd)
{
LPTSTR p;                                               //*
OPENFILENAME ofn;                               //*
TCHAR szBuffer[_MAX_PATH] ;               //*
TCHAR szFileName[_MAX_PATH];           //*
HANDLE  hFile;
HANDLE  hHeap;
LPVOID  MemoryBuffer;
DWORD   dwReadBytes;
DWORD dwFileSize;

//**
      szFileName[0] = 0;
      szBuffer[_MAX_PATH-1] = 0;
      ZeroMemory(&ofn, sizeof(OPENFILENAME)) ;
      ofn.lStructSize   = sizeof(OPENFILENAME) ;
      ofn.hwndOwner     = hwnd ;
      ofn.lpstrFilter   = TEXT("Мех (*.x)\0*.x\0\0");
      ofn.nFilterIndex  = 0 ;
      ofn.lpstrFile     = szFileName;
      ofn.nMaxFile      = sizeof(szFileName) ;
      ofn.lpstrFileTitle = NULL;
      ofn.lpstrTitle    = TEXT("Выберите файл меха:");
      ofn.nMaxFileTitle = 0 ;
      ofn.lpstrInitialDir = szBuffer;
      ofn.Flags = OFN_HIDEREADONLY | OFN_NOREADONLYRETURN | OFN_PATHMUSTEXIST ;
      GetOpenFileName(&ofn);
//**

      hFile = CreateFile( szFileName, GENERIC_READ,
                        FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);

      dwFileSize = GetFileSize( hFile, NULL);


        if (hHeap =     GetProcessHeap())
        {
                if (MemoryBuffer = HeapAlloc(hHeap, HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS, dwFileSize))
                {
                        ReadFile(hFile, MemoryBuffer, dwFileSize, &dwReadBytes, NULL);
                        CloseHandle(hFile);
                }
        }

        int i;
        __asm
        {
                xor eax,eax
                mov edi,MemoryBuffer
                mov al,byte ptr [edi]
                mov i,eax
        }
}


Кусок кода на асме записывает в переменную i байт содержащийся по адресу MemoryBuffer. Для изъятия других байтов надо лишь прибавить к MemoryBuffer смещение в памяти.
Путь выбирается в окне виндовоза. Чтобы указать имя файла в ручную, надо удалить строки со звездочками и программку заключенную между ними! Тогда CreateFile будет выглядеть так:

Код

      hFile = CreateFile( "name", GENERIC_READ,
                        FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);


name - путь до файла (н-р: "с:\\david\\coding\\filename.txt")

Главное в конце не забыть удалить участок памяти:

Код

       HeapFree(hHeap, NULL, MemoryBuffer);


Очень удобно, кстати. Сам сейчас юзаю такой метод! smile

Автор: Arush 13.7.2005, 18:26
Если тебе не нужны все данные файла, то быстрее всего использовать мапирование его в память используя CreateFileMapping.

ЗЫ. Твой код на асме аналогичен i=((PBYTE)MemoryBuffer)[0]. Или i=MemoryBuffer[0] если MemoryBuffer объявить как PBYTE smile

Автор: Div 13.7.2005, 21:32
Код

ЗЫ. Твой код на асме аналогичен i=((PBYTE)MemoryBuffer)[0]. Или i=MemoryBuffer[0] если MemoryBuffer объявить как PBYTE 


Не спорю. Но так быстрее smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)