Пример #1
0
        protected void OpenFile(bool full)
        {
            if (reader != null)
            {
                reader.Seek(0);
            }
            else
            {
                try {
                    // We don't actually write to the file, but requesting ReadWrite access ensures
                    // that nobody else has the file open for writing (unless someone else set FileShare.Write,
                    // but that's unlikely, and this program doesn't do that).
                    //
                    // Opening with FileAccess.Read would mean that other programs could have the file open and
                    // modify it, thus invaliding the file offsets stored in the partially-loaded entries.
                    //
                    // We need to open with FileShare.Read because the main window and other programs need to
                    // read the dictionary header to populate the list. (This should probably change.)

                    // Of course, if we're just reading the dictionary header, we only request read access.
                    var access = full ? FileAccess.ReadWrite : FileAccess.Read;

                    // If we're only loading a header, we have to set FileShare.ReadWrite or the call
                    // fails if the file is already open for ReadWrite.
                    // If we can open the file for Read access, it should be safe to read from without it
                    // being modified (when writing to the dictionary, we specify FileShare.None).
                    var share = full ? FileShare.Read : FileShare.ReadWrite;

                    reader = new Utf8LineReader(Path, access, share);
                } catch (IOException e) {
                    throw new DictionaryLoadException(e.Message, e);
                } catch (ArgumentException e) {
                    throw new DictionaryLoadException(e.Message, e);
                } catch (UnauthorizedAccessException e) {
                    throw new DictionaryLoadException(e.Message, e);
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Writes all entries to a file. There's no way to tell if the dictionary entries have been modified,
        /// as of yet, so currently we must write the file whether it's necessary or not.
        /// </summary>
        /// <param name="path">The file name (relative or absolute) to write to.</param>
        protected void Write(string path)
        {
            // Update the revision ID. Instead of incrementing a number, pick a random GUID and use that.
            // If incrementing were used, then if a dictionary were copied to a different computer, modified,
            // and copied back to the original computer, where the dictionary had also been modified, the
            // cache revision ID on the original computer would still match that of the dictionary file, despite
            // being invalid.
            revisionID = Guid.NewGuid().ToString();

            // If we're not writing cautiously, we can't read the entries on-demand while the temporary output file
            // is written.
            if (path == Path)
                CloseFile();

            PreloadPartialEntries();

            Metrics.Measure(string.Format("Writing dictionary {0} to file", this.Name), delegate {
                // Now dispose of the reader so that we can unlock the file.
                // The file needs to be truncated anyway, so it's not possible to share the file stream
                // with the Line Reader.
                if (reader != null) {
                    reader.Dispose();
                    reader = null;
                }

                using (var stream = File.Open(path, FileMode.Create, FileAccess.Write, FileShare.None)) {
                    using (var writer = new LineWriter(stream)) {
                        writer.WriteLine(magicNumber);

                        if (Name != null)
                            writer.WriteLine("name " + Uri.EscapeDataString(Name));
                        if (Author != null)
                            writer.WriteLine("author " + Uri.EscapeDataString(Author));
                        if (Url != null)
                            writer.WriteLine("url " + Uri.EscapeDataString(Url));
                        writer.WriteLine("revision-id " + Uri.EscapeDataString(revisionID));

                        // TODO: WritePairedProperty
                        writer.WriteLine(string.Format("headwords-hint {0} {1}", forwards.HeadWords, backwards.HeadWords));
                        if (FirstLanguage != null || SecondLanguage != null)
                            writer.WriteLine(string.Format("languages {0} {1}", Uri.EscapeDataString(FirstLanguage), Uri.EscapeDataString(SecondLanguage)));
                        if (FirstLanguageCode != null || SecondLanguageCode != null)
                            writer.WriteLine(string.Format("language-codes {0} {1}", Uri.EscapeDataString(FirstLanguageCode), Uri.EscapeDataString(SecondLanguageCode)));
                        writer.WriteLine("sorted");

                        foreach (Entry entry in ForwardsSection)
                            WriteEntry(writer, "f ", entry);

                        foreach (Entry entry in ReverseSection)
                            WriteEntry(writer, "b ", entry);
                    }
                }
            });
        }
Пример #3
0
        protected void OpenFile(bool full)
        {
            if (reader != null)
                reader.Seek(0);
            else {
                try {
                    // We don't actually write to the file, but requesting ReadWrite access ensures
                    // that nobody else has the file open for writing (unless someone else set FileShare.Write,
                    // but that's unlikely, and this program doesn't do that).
                    //
                    // Opening with FileAccess.Read would mean that other programs could have the file open and
                    // modify it, thus invaliding the file offsets stored in the partially-loaded entries.
                    //
                    // We need to open with FileShare.Read because the main window and other programs need to
                    // read the dictionary header to populate the list. (This should probably change.)

                    // Of course, if we're just reading the dictionary header, we only request read access.
                    var access = full ? FileAccess.ReadWrite : FileAccess.Read;

                    // If we're only loading a header, we have to set FileShare.ReadWrite or the call
                    // fails if the file is already open for ReadWrite.
                    // If we can open the file for Read access, it should be safe to read from without it
                    // being modified (when writing to the dictionary, we specify FileShare.None).
                    var share = full ? FileShare.Read : FileShare.ReadWrite;

                    reader = new Utf8LineReader(Path, access, share);
                } catch (IOException e) {
                    throw new DictionaryLoadException(e.Message, e);
                } catch (ArgumentException e) {
                    throw new DictionaryLoadException(e.Message, e);
                } catch (UnauthorizedAccessException e) {
                    throw new DictionaryLoadException(e.Message, e);
                }
            }
        }
Пример #4
0
 protected void CloseFile()
 {
     if (reader != null) {
         reader.Dispose();
         reader = null;
     }
 }