/// <summary> /// Write out a header to the given stream that indicates the chosen /// compression codec, and return the same stream wrapped with that codec. /// </summary> /// <remarks> /// Write out a header to the given stream that indicates the chosen /// compression codec, and return the same stream wrapped with that codec. /// If no codec is specified, simply adds buffering to the stream, so that /// the returned stream is always buffered. /// </remarks> /// <param name="os"> /// The stream to write header to and wrap. This stream should /// be unbuffered. /// </param> /// <returns> /// A stream wrapped with the specified compressor, or buffering /// if compression is not enabled. /// </returns> /// <exception cref="System.IO.IOException"> /// if an IO error occurs or the compressor cannot be /// instantiated /// </exception> internal virtual DataOutputStream WriteHeaderAndWrapStream(OutputStream os) { DataOutputStream dos = new DataOutputStream(os); dos.WriteBoolean(imageCodec != null); if (imageCodec != null) { string codecClassName = imageCodec.GetType().GetCanonicalName(); Text.WriteString(dos, codecClassName); return(new DataOutputStream(imageCodec.CreateOutputStream(os))); } else { // use a buffered output stream return(new DataOutputStream(new BufferedOutputStream(os))); } }
/// <exception cref="System.IO.IOException"/> private void SaveInternal(FileOutputStream fout, FSImageCompression compression, string filePath) { StartupProgress prog = NameNode.GetStartupProgress(); MessageDigest digester = MD5Hash.GetDigester(); underlyingOutputStream = new DigestOutputStream(new BufferedOutputStream(fout), digester ); underlyingOutputStream.Write(FSImageUtil.MagicHeader); fileChannel = fout.GetChannel(); FsImageProto.FileSummary.Builder b = FsImageProto.FileSummary.NewBuilder().SetOndiskVersion (FSImageUtil.FileVersion).SetLayoutVersion(NameNodeLayoutVersion.CurrentLayoutVersion ); codec = compression.GetImageCodec(); if (codec != null) { b.SetCodec(codec.GetType().GetCanonicalName()); sectionOutputStream = codec.CreateOutputStream(underlyingOutputStream); } else { sectionOutputStream = underlyingOutputStream; } SaveNameSystemSection(b); // Check for cancellation right after serializing the name system section. // Some unit tests, such as TestSaveNamespace#testCancelSaveNameSpace // depends on this behavior. context.CheckCancelled(); Step step = new Step(StepType.Inodes, filePath); prog.BeginStep(Phase.SavingCheckpoint, step); SaveInodes(b); SaveSnapshots(b); prog.EndStep(Phase.SavingCheckpoint, step); step = new Step(StepType.DelegationTokens, filePath); prog.BeginStep(Phase.SavingCheckpoint, step); SaveSecretManagerSection(b); prog.EndStep(Phase.SavingCheckpoint, step); step = new Step(StepType.CachePools, filePath); prog.BeginStep(Phase.SavingCheckpoint, step); SaveCacheManagerSection(b); prog.EndStep(Phase.SavingCheckpoint, step); SaveStringTableSection(b); // We use the underlyingOutputStream to write the header. Therefore flush // the buffered stream (which is potentially compressed) first. FlushSectionOutputStream(); FsImageProto.FileSummary summary = ((FsImageProto.FileSummary)b.Build()); SaveFileSummary(underlyingOutputStream, summary); underlyingOutputStream.Close(); savedDigest = new MD5Hash(digester.Digest()); }