Visualizzazione dei risultati da 1 a 7 su 7
  1. #1

    [C++] Scrittura file in rete lentissima con ofstream

    Salve,
    ho piccolo problema di prestazioni per quanto riguarda la scrittura di un file attraverso la rete.
    Il mio codice legge i byte di un file e poi li scrive su un altro file, una sorta di copia incolla. Fin qui tutto bene, ma le prestazioni calano vistosamente quando il file di destinazione è su un percorso di rete e non riesco a capirne il motivo:

    codice:
    //path del file di destinazione
    string destinationFile="//cartella_di_rete/file.dati";
    //file di destinazione
    ofstream outfile(destinationFile, ios::binary | ios::out | ios::trunc);
    //crea il buffer di lettura
    mybuffer = new uint8[20480*512];
    //cicla per leggere il file diviso in diversi chunk
    for (int i = 1; i <= chunk; i++)
    {
         //funzione che legge il file originale e lo copia nel buffer(in realtà è molto più complessa, 
        // in quanto si tratta di una funzione di terzi ma non ci interessa in questa sede)
         bool ckok= ReadFile( mybuffer, i);
        if (ckok)
          outfile.write((char*)mybuffer, bufSize);
    }
    
    delete(mybuffer);
    outfile.close();
    cioè si parla di 10Mb/s se il file di destinazione è locale contro 2Mb/s se il file è in rete... una differenza piuttosto sensibile direi che in sistemi più performanti del mio di test si fa sentire ancora di più..

    qualcuno di voi ha qualche idea?
    Ultima modifica di Whitecrowsrain; 29-12-2017 a 17:26
    "Due cose riempiono l’animo di ammirazione e venerazione sempre nuova e crescente, quanto piú spesso e piú a lungo la riflessione si occupa di esse: il cielo stellato sopra di me, e la legge morale in me..." Immanuel Kant

  2. #2
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Prova a copiare un file delle stesse dimensioni con il file manager e vedi se hai risultati analoghi.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  3. #3
    Quote Originariamente inviata da shodan Visualizza il messaggio
    Prova a copiare un file delle stesse dimensioni con il file manager e vedi se hai risultati analoghi.
    Ho provato a copiarlo tramite quella funzione e poi a fare un semplice copia-incolla, velocità non comparabili proprio..
    ma ci sta pure che la funzione sia più lenta del semplice copia incolla, in quanto la funzione di lettura del file va ad estrarre dati da un disco virtuale, ma non è possibile che ci sia un divario se il file di destinazione è in locale piuttosto che in rete!
    "Due cose riempiono l’animo di ammirazione e venerazione sempre nuova e crescente, quanto piú spesso e piú a lungo la riflessione si occupa di esse: il cielo stellato sopra di me, e la legge morale in me..." Immanuel Kant

  4. #4
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Prova a utilizzare dei chunk e un buffer più piccolo (non sotto i 4096 bytes o potrebbe scattare il buffering), per non intasare troppo la rete. Del resto std:: ofstream si limita a usare le API del SysOp per l'IO su file.

    Se utilizzi windows puoi utilizzare CopyFile,
    https://msdn.microsoft.com/it-it/lib...(v=vs.85).aspx
    se è Linux puoi cercare qualcosa di simile.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  5. #5
    Quote Originariamente inviata da shodan Visualizza il messaggio
    Prova a utilizzare dei chunk e un buffer più piccolo (non sotto i 4096 bytes o potrebbe scattare il buffering), per non intasare troppo la rete. Del resto std:: ofstream si limita a usare le API del SysOp per l'IO su file.

    Se utilizzi windows puoi utilizzare CopyFile,
    https://msdn.microsoft.com/it-it/lib...(v=vs.85).aspx
    se è Linux puoi cercare qualcosa di simile.
    non posso usare CopyFile perché non devo salvare un file vero e proprio ma devo salvare una sequenza di byte ( che estraggo di volta in volta con la funzione di lettura ) che poi va a costituire il file di destinazione!
    In pratica ogni ciclo estraggo i settori utilizzati di un disco e li accodo ad un file, che poi mi servirà per il ripristino..
    Il problema è quando vado ad accodare questi byte al file di destinazione, che se non è in locale rallenta drasticamente la procedura.. (prima usavo un buffer più piccolo ed era molto peggio, ora uso un buffer "elastico" con un max di 10MB che regolo in base al numero di settori da estrarre del disco..)
    Ultima modifica di Whitecrowsrain; 29-12-2017 a 19:49
    "Due cose riempiono l’animo di ammirazione e venerazione sempre nuova e crescente, quanto piú spesso e piú a lungo la riflessione si occupa di esse: il cielo stellato sopra di me, e la legge morale in me..." Immanuel Kant

  6. #6
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Usa direttamente le API di Windows allora. Più in basso di così non si può andare.
    codice:
    //path del file di destinazione
    string destinationFile="\\\\cartella_di_rete\\file.dati";
    //file di destinazione
    
    // ofstream outfile(destinationFile, ios::binary | ios::out | ios::trunc);
    
    HANDLE hfile = CreateFile(
        destinationFile.c_str(),  
        (GENERIC_READ | GENERIC_WRITE), 
        (FILE_SHARE_READ | FILE_SHARE_WRITE), 
        nullptr,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        nullptr
    );
        
    if (hfile == INVALID_HANDLE_VALUE) 
        /* Errore */
        return;    
        
    DWORD wbytes = 0;    
    //crea il buffer di lettura
    mybuffer = new uint8[20480*512];
    //cicla per leggere il file diviso in diversi chunk
    for (int i = 1; i <= chunk; i++) // perché da 1? E' voluto?
    {
         //funzione che legge il file originale e lo copia nel buffer(in realtà è molto più complessa, 
        // in quanto si tratta di una funzione di terzi ma non ci interessa in questa sede)
         bool ckok= ReadFile( mybuffer, i);
        if (ckok)
          WriteFile(hfile, mybuffer, bufSize, &wbytes, nullptr);
    }
    
    delete[] mybuffer; 
    CloseHandle(hfile);
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  7. #7
    Quote Originariamente inviata da shodan Visualizza il messaggio
    Usa direttamente le API di Windows allora. Più in basso di così non si può andare.
    codice:
    //path del file di destinazione
    string destinationFile="\\\\cartella_di_rete\\file.dati";
    //file di destinazione
    
    // ofstream outfile(destinationFile, ios::binary | ios::out | ios::trunc);
    
    HANDLE hfile = CreateFile(
        destinationFile.c_str(),  
        (GENERIC_READ | GENERIC_WRITE), 
        (FILE_SHARE_READ | FILE_SHARE_WRITE), 
        nullptr,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        nullptr
    );
        
    if (hfile == INVALID_HANDLE_VALUE) 
        /* Errore */
        return;    
        
    DWORD wbytes = 0;    
    //crea il buffer di lettura
    mybuffer = new uint8[20480*512];
    //cicla per leggere il file diviso in diversi chunk
    for (int i = 1; i <= chunk; i++) // perché da 1? E' voluto?
    {
         //funzione che legge il file originale e lo copia nel buffer(in realtà è molto più complessa, 
        // in quanto si tratta di una funzione di terzi ma non ci interessa in questa sede)
         bool ckok= ReadFile( mybuffer, i);
        if (ckok)
          WriteFile(hfile, mybuffer, bufSize, &wbytes, nullptr);
    }
    
    delete[] mybuffer; 
    CloseHandle(hfile);
    ho provato ed in effetti per quanto riguarda il trasferimento via rete (mentre su una cartella locale è invariato) è quasi due volte più veloce!!
    Grazie
    "Due cose riempiono l’animo di ammirazione e venerazione sempre nuova e crescente, quanto piú spesso e piú a lungo la riflessione si occupa di esse: il cielo stellato sopra di me, e la legge morale in me..." Immanuel Kant

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.