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

    [c#]file .mdb creati da codice che rimangono in uso

    Salve a tutti.
    Sto creando un programma che legge una lista di file .txt in una cartella e crea un file .mdb (access) per ogni file inserendo come record i dati presenti nel file txt.
    Fin qui nessun problema, se non che oltre a creare i file .mdb spesso mi crea anche dei file .Idb (Informazioni di blocco record).
    Una volta creati questi file ho l'esigenza di zipparli (uno a uno, o meglio ancora tutti insieme).
    Il problema si verifica durante la fase di compressione, in quanto a volte mi viene detto che il file è in uso e viene generato un errore.
    Premetto che per zippare uso la SharpZipLib.
    Posto un po' di codice:

    codice:
    ...
    private Thread processo;
    ...
    processo = new Thread(AvviaProcesso);
    processo.Start();
    codice:
    protected void AvviaProcesso()
    {
    	DirectoryInfo dir = new DirectoryInfo(localFolder); //la cartella contenente i miei .txt
    	FileInfo[] rgFiles = dir.GetFiles("*.txt");
    	if (rgFiles.Length > 0)
    	{
    		if (!Directory.Exists(Application.StartupPath + "\\temp"))
    		{
    			try
    			{
    				Directory.CreateDirectory(Application.StartupPath + "\\temp"); //cartella in cui salvare i file .mdb
    			}
    			catch (Exception ex)
    			{
    				MessageBox.Show(ex.Message);
    			}
    		}
    
    		String db;
    		String line;
    		OleDbConnection conn;
    		OleDbCommand cmd;
    		ADOX.CatalogClass cat;
    		String name;
    
    		System.IO.StreamReader stream;
    
    		foreach (FileInfo fi in rgFiles)
    		{
    			name = fi.Name.Replace(".txt", ""); //solo il nome del file senza percorso ed estensione
    			db = Application.StartupPath + "\\temp\\" + name + ".mdb";
    			
    			try
    			{
    				cat = new ADOX.CatalogClass();
    				try
    				{
    					cat.Create("Provider=Microsoft.Jet.OLEDB.4.0;" +
    					"Data Source=" + db + ";" +
    					"Jet OLEDB:Engine Type=5");
    				}
    				catch (Exception ex)
    				{
    					return;
    				}
    
    				string connString = @"Provider=Microsoft.Jet.OLEDB.4.0 ;Data Source=" + db;
    				conn = new OleDbConnection(connString);
    				conn.Open();
    				string query = "CREATE TABLE prova (id AUTOINCREMENT, campo TEXT(30))";
    				cmd = new OleDbCommand(query, conn);
    				cmd.ExecuteNonQuery();
    
    				stream = new System.IO.StreamReader(fi.FullName);
    				while ((line = stream.ReadLine()) != null)
    				{
    					query = "INSERT INTO prova (campo) VALUES (\"" + line + "\")";
    					cmd = new OleDbCommand(query, conn);
    					cmd.ExecuteNonQuery();
    				}
    				stream.Close();
    				stream.Dispose();
    			}
    			catch (System.Data.OleDb.OleDbException ex)
    			{
    				timer.Enabled = false;
    				MessageBox.Show(ex.Message);
    				lblStatus.Text = "Stato: Errore - Stoppato";
    				return;
    			}
    
    			conn.Close();
    			conn.Dispose();
    
    			if (!Directory.Exists(Application.StartupPath + "\\zip"))
    			{
    				try
    				{
    					Directory.CreateDirectory(Application.StartupPath + "\\zip"); //cartella in cui salvare i file zippati
    				}
    				catch (Exception ex)
    				{
    					MessageBox.Show(ex.Message);
    				}
    			}
    
    			Zip.ZipFile(Application.StartupPath + "\\zip\\" + name + ".zip", db); //singolo gile
    			fi.Delete(); //elimino il .txt
    			File.Delete(db); //elimino .mdb
    		}
    	}
    	//Zip.ZipFolder(Application.StartupPath+"\\cartella.zip", Application.StartupPath + "\\temp"); //tutta la cartella
    }
    posto anche la classe Zip (ricordo che mi appogigo a SharpZipLib:
    codice:
    using System;
    using System.IO;
    using ICSharpCode.SharpZipLib.Zip;
    using ICSharpCode.SharpZipLib.Checksums;
    
    namespace FtpTransferDB_V2
    {
        /// <summary>
        /// Zip
        /// </summary>
        public class Zip
        {
            #region public methods
    
    /// <summary>
            /// Comprime il contenuto di un file in formato ZIP
            /// </summary>
            /// <param name="ZipFilePath">Path del file compresso da creare</param>
            /// <param name="OriginalFilePath">Path del file da comprimere</param>
            public static void ZipFile(string ZipFilePath, string OriginalFilePath)
            {
                try
                {
                    FileInfo fi = new FileInfo(OriginalFilePath);
                    ZipOutputStream zip = new ZipOutputStream(File.Create(ZipFilePath));
                    zip.SetLevel(6);    // 0 - store only to 9 - means best compression
                    AddFile2Zip(zip, fi, "");
                    zip.Finish();
                    zip.Close();
                }
                catch (Exception ex)
                {
                    throw ex; //VIENE GENERATA QUI
                }
            }
    
            /// <summary>
            /// Comprime il contenuto di una cartella in formato ZIP, ricorsivamente e preservandone la struttura
            /// </summary>
            /// <param name="ZipFilePath">Path del file compresso da creare</param>
            /// <param name="OriginalFolderPath">Path della cartella da comprimere</param>
            public static void ZipFolder(string ZipFilePath, string OriginalFolderPath)
            {
                try
                {
                    DirectoryInfo di = new DirectoryInfo(OriginalFolderPath);
                    ZipOutputStream zip = new ZipOutputStream(File.Create(ZipFilePath));
                    zip.SetLevel(6);    // 0 - store only to 9 - means best compression
                    AddFolder2Zip(zip, di, "");
                    zip.Finish();
                    zip.Close();
                }
                catch (Exception ex)
                {
                    throw ex; //VIENE GENERATA QUI
                }
            }
    #endregion
    
            #region private methods
    
            private static void AddFolder2Zip(ZipOutputStream zip, DirectoryInfo di, string internalzippath)
            {
                string izp = internalzippath + di.Name + "/";    // A directory is determined by an entry name with a trailing slash "/"
                Crc32 crc = new Crc32();
                ZipEntry entry = new ZipEntry(izp);
                entry.Crc = crc.Value;
                zip.PutNextEntry(entry);
                foreach (FileInfo fi in di.GetFiles())
                    AddFile2Zip(zip, fi, izp);
                foreach (DirectoryInfo sdi in di.GetDirectories())
                    AddFolder2Zip(zip, sdi, izp);
            }
            private static void AddFile2Zip(ZipOutputStream zip, FileInfo fi, string internalzippath)
            {
                Crc32 crc = new Crc32();
                FileStream fs = File.OpenRead(fi.FullName);
                byte[] buffer = new byte[fs.Length];
                fs.Read(buffer, 0, buffer.Length);
                ZipEntry entry = new ZipEntry(internalzippath + fi.Name);
                entry.DateTime = DateTime.Now;
                entry.Size = fs.Length;
                fs.Close();
                crc.Reset();
                crc.Update(buffer);
                entry.Crc = crc.Value;
                zip.PutNextEntry(entry);
                zip.Write(buffer, 0, buffer.Length);
            }
    
            #endregion
        }
    }
    Spero che qualcuno abbia la pazienza di leggere e di darmi una mano.
    Saluti

  2. #2
    Utente di HTML.it L'avatar di gibra
    Registrato dal
    Apr 2008
    residenza
    Italy
    Messaggi
    4,244
    Prima devi chiudere la connessione al file MDB da comprimere;
    una volta chiusa la connessione, il file LDB viene eliminato.

    Dopo di ciò puoi 'zippare' i file.

    Ciao

  3. #3
    Ciao, grazie per la risposta.
    Non è quello che già faccio con:
    codice:
    conn.Close();
    conn.Dispose();
    
    //dove conn era:
    conn = new OleDbConnection(connString);
    ?

    Fammi sapere

  4. #4
    Utente di HTML.it L'avatar di gibra
    Registrato dal
    Apr 2008
    residenza
    Italy
    Messaggi
    4,244
    Beh, se il file LDB non viene eliminato, evidentemente qualcosa non funziona nel codice, ma potrebbe anche non essere un errore del codice, ma un problema di 'ritardo' nell'aggiornamento dei dati. Per impostazione predefinita del JET, la cache viene aggiornata dopo 5 secondi quindi se nell'MDB non si è ancora concluso l'aggiornamento dei dati, di conseguenza la chiusura della connessione viene posticipata, e si scontra con il tentativo di zippare il file perchè l'LDB è ancora presente e blocca l'operazione.

    Se questo è il caso (è da verificare) allora o inserisci un ritardo di qualche secondo prima di zippare, oppure devi forzare il tempo di refresh impostando una proprietà specifica del JET.

    Sinceramente in NET non l'ho mai fatto, da VB6 facevo così:

    codice:
        Dim CN As ADODB.Connection
        Set CN = New ADODB.Connection
        CN.CursorLocation = adUseServer
        CN.Open "PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source=" & gsDataBasePath 
        CN.Properties("Jet OLEDB:Transaction Commit Mode") = 1      ' ***
        CN.Properties("Jet OLEDB:Lock Delay") = 90 + Int(Rnd * 60)   ' ***
        CN.BeginTrans
        CN.Execute(sSqlCommand)
        CN.CommitTrans
    
        ''' Poi si esegue il refresh della cache:
        Set Jet = CreateObject("JRO.JetEngine")
        Jet.RefreshCache CN
        Set Jet = Nothing
    In questo modo, i dati sono aggiornati immediatamente.

    Sono quasi sicuro al 99% che sia questo il problema, perchè l'ho verificato molte volte anche nella stampa che eseguita immediatamente dopo un'aggiornamento dei dati, mostrava sempre i dati vecchi, dopo il refresh mostrava i dati aggiornati.

    Non puoi creare un solo MDB in cui inserire una tabella per ogni file?

    Ciao

  5. #5
    Non puoi creare un solo MDB in cui inserire una tabella per ogni file?
    purtroppo no (non dipende da me).


    Allora ho provato a mettere in sleep il thread prima di zippare per 10 secondi ma il problema rimane.
    Allora ho provato anche a eliminare la parte di compressione e mi aspettato che così il file .Idb scomparissero dopo un po', invece rimangono finchè non chiudo il programma.

    oppure devi forzare il tempo di refresh impostando una proprietà specifica del JET.
    purtroppo non riesco a trovare nulla in c#, tutti gli esempi che trovo sono in vb o vb.net

  6. #6
    Utente di HTML.it L'avatar di gibra
    Registrato dal
    Apr 2008
    residenza
    Italy
    Messaggi
    4,244
    Che sia causato da questo?

    codice:
    cat = new ADOX.CatalogClass();
    che tiene in piedi una connessione?

    Ciao

  7. #7
    l'ho pensato anche io e ho provato con:
    codice:
    Marshal.ReleaseComObject(cat)
    ma non ho risolto.

    Comunque ho visto che i file .ldb vengono generati durante la creazione del db.
    Ora sto provando una soluzione diversa (che non si appoggià più su ADOX).
    Metto un file .mdb vuoto nelle risorse.
    E poi quando mi serve lo "estraggo" dalle risorse e lo uso.
    Ora devo solo capire come fare (si accettano suggerimenti).

  8. #8
    Risolto inserendo un db vuoto come risorsa incorporata

  9. #9
    Utente di HTML.it L'avatar di gibra
    Registrato dal
    Apr 2008
    residenza
    Italy
    Messaggi
    4,244
    Ops, io volevo suggerirtelo, ma mi hai anticipato.
    Beh, a questo hai già risolto il problema.
    Ottimo lavoro.

    Ciao

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 © 2025 vBulletin Solutions, Inc. All rights reserved.