/// <summary>
            /// Closes the journal file.
            /// </summary>
            internal void Close()
            {
                lock (this) {
                    if (!is_open) {
                        throw new IOException("Journal file is already closed.");
                    }

                    data.Close();
                    data = null;
                    is_open = false;
                }
            }
            /// <summary>
            /// Opens the journal for recovery.
            /// </summary>
            /// <remarks>
            /// This scans the journal and generates some statistics about the journal file 
            /// such as the last check point and the journal number.
            /// </remarks>
            /// <returns></returns>
            /// <exception cref="IOException">
            /// If the journal file doesn't exist.
            /// </exception>
            internal JournalSummary OpenForRecovery()
            {
                if (is_open) {
                    throw new IOException("Journal file is already open.");
                }
                if (!File.Exists(file)) {
                    throw new IOException("Journal file does not exists.");
                }

                // Open the random access file to this journal
                data = new StreamFile(file, read_only ? FileAccess.Read : FileAccess.ReadWrite);
                is_open = true;

                // Create the summary object (by default, not recoverable).
                JournalSummary summary = new JournalSummary(this);

                long end_pointer = data.Length;

                // If end_pointer < 8 then can't recovert this journal
                if (end_pointer < 8) {
                    return summary;
                }

                // The input stream.
                BinaryReader din = new BinaryReader(data.FileStream, Encoding.Unicode);

                try {
                    // Set the journal number for this
                    this.journal_number = din.ReadInt64();
                    long position = 8;

                    ArrayList checkpoint_res_list = new ArrayList();

                    // Start scan
                    while (true) {

                        // If we can't Read 12 bytes ahead, return the summary
                        if (position + 12 > end_pointer) {
                            return summary;
                        }

                        long type = din.ReadInt64();
                        int size = din.ReadInt32();

                        //          Console.Out.WriteLine("Scan: " + type + " pos=" + position + " size=" + size);
                        position = position + size + 12;

                        bool skip_body = true;

                        // If checkpoint reached then we are recoverable
                        if (type == 100) {
                            summary.last_checkpoint = position;
                            summary.can_be_recovered = true;

                            // Add the resources input this check point
                            summary.resource_list.AddRange(checkpoint_res_list);
                            // And clear the temporary list.
                            checkpoint_res_list.Clear();

                        }

                        // If end reached, or type is not understood then return
                        else if (position >= end_pointer ||
                                 type < 1 || type > 32) {
                            return summary;
                        }

                        // If we are resource type, then load the resource
                        if (type == 2) {

                            // We don't skip body for this type, we Read the content
                            skip_body = false;
                            long id = din.ReadInt64();
                            int str_len = din.ReadInt32();
                            StringBuilder str = new StringBuilder(str_len);
                            for (int i = 0; i < str_len; ++i) {
                                str.Append(din.ReadChar());
                            }

                            String resource_name = str.ToString();
                            checkpoint_res_list.Add(resource_name);

                        }

                        if (skip_body)
                            din.BaseStream.Seek(size, SeekOrigin.Current);
                    }

                } finally {
                    din.Close();
                }
            }
Beispiel #3
0
 public SFFileStream(StreamFile file)
 {
     this.file = file;
 }
            /// <summary>
            /// Opens the journal file.
            /// </summary>
            /// <param name="journal_number"></param>
            /// <exception cref="IOException">
            /// If the journal file exists.
            /// </exception>
            internal void Open(long journal_number)
            {
                if (is_open) {
                    throw new IOException("Journal file is already open.");
                }
                if (File.Exists(file)) {
                    throw new IOException("Journal file already exists.");
                }

                this.journal_number = journal_number;
                data = new StreamFile(file, read_only ? FileAccess.Read : FileAccess.ReadWrite);
                data_out = new BinaryWriter(new BufferedStream(data.FileStream), Encoding.Unicode);
                data_out.Write(journal_number);
                is_open = true;
            }
Beispiel #5
0
 public SFFileStream(StreamFile file)
 {
     this.file = file;
 }