示例#1
0
        /// <summary>
        /// Ends the sequence of creating a content/signature pair.
        /// Writes the list of deleted files to the archives.
        /// </summary>
        /// <param name="signaturefile">The signature archive file</param>
        /// <param name="contentfile">The content archive file</param>
        /// <param name="volumesize">The max volume size</param>
        /// <returns>True if the volume is completed, false otherwise</returns>
        public bool FinalizeMultiPass(Library.Interface.ICompression signaturefile, Library.Interface.ICompression contentfile, long volumesize)
        {
            if (!m_finalized)
            {
                if (m_unproccesed.Files.Count == 0)
                {
                    long stringsize = 0;
                    foreach (string s in m_oldSignatures.Keys)
                    {
                        string sourcefolder = "<unknown>";
                        try
                        {
                            string fullpath = GetFullPathFromRelname(s);
                            sourcefolder = GetSourceFolder(fullpath);
                            if (!m_unproccesed.IsAffectedByError(fullpath))
                            {
                                m_deletedfiles.Add(s);
                                stringsize += System.Text.Encoding.UTF8.GetByteCount(s + "\r\n");
                            }
                        }
                        catch (Exception ex)
                        {
                            if (m_stat != null)
                                m_stat.LogError(string.Format(Strings.RSyncDir.DeletedFilenameError, s, sourcefolder), ex);
                            Logging.Log.WriteMessage(string.Format(Strings.RSyncDir.DeletedFilenameError, s, sourcefolder), XervBackup.Library.Logging.LogMessageType.Error, ex);
                            m_unproccesed.FilesWithError.Add(s);
                        }
                    }

                    m_oldSignatures.Clear();

                    if (m_deletedfiles.Count > 0)
                    {
                        //The +100 is a safety margin
                        stringsize += System.Text.Encoding.UTF8.GetByteCount(DELETED_FILES) + 100;
                        if (contentfile.Size + contentfile.FlushBufferSize + stringsize > volumesize)
                            return false; //The followup cannot fit in the volume, so we make a full new volume

                        signaturefile.WriteAllLines(DELETED_FILES, m_deletedfiles.ToArray());
                        contentfile.WriteAllLines(DELETED_FILES, m_deletedfiles.ToArray());
                        m_deletedfiles.Clear();
                    }

                    //We only write the USN if all files were processed
                    if (m_currentUSN != null)
                        using (System.IO.Stream s = signaturefile.CreateFile(USN_VALUES))
                            m_currentUSN.Save(s);

                    //Only write this if all files were processed
                    if (m_checkedUnchangedFiles.Count > 0)
                        signaturefile.WriteAllLines(UNMODIFIED_FILES, m_checkedUnchangedFiles.ToArray());

                    if (m_unproccesed.Symlinks.Count > 0)
                    {
                        foreach(KeyValuePair<string, string> kvp in m_unproccesed.Symlinks)
                        {
                            string target = FilenamesToPlatformIndependant(new string[] { kvp.Value })[0];
                            string source = Path.Combine(SYMLINK_ROOT, GetRelativeName(kvp.Key));
                            byte[] targetBytes = Encoding.UTF8.GetBytes(target);

                            contentfile.WriteAllBytes(source, targetBytes);
                            signaturefile.WriteAllBytes(source, targetBytes);
                        }
                        m_unproccesed.Symlinks.Clear();
                    }
                }

                m_finalized = true;
            }

            return m_finalized;
        }