public void SaveTextStream(string name, Action <TextWriter> action) { _ectx.Check(InRepository, "Can't save a text stream when writing to a single stream"); _ectx.CheckNonEmpty(name, nameof(name)); _ectx.CheckValue(action, nameof(action)); // I verified in the CLR source that the default buffer size is 1024. It's unfortunate // that to set leaveOpen to true, we have to specify the buffer size.... using (var ent = Repository.CreateEntry(Directory, name)) using (var writer = Utils.OpenWriter(ent.Stream)) { action(writer); } }
/// <summary> /// Save schema associations of role/column-name in <paramref name="rep"/>. /// </summary> internal static void SaveRoleMappings(IHostEnvironment env, IChannel ch, RoleMappedSchema schema, RepositoryWriter rep) { // REVIEW: Should we also save this stuff, for instance, in some portion of the // score command or transform? Contracts.AssertValue(env); env.AssertValue(ch); ch.AssertValue(schema); ArrayDataViewBuilder builder = new ArrayDataViewBuilder(env); List<string> rolesList = new List<string>(); List<string> columnNamesList = new List<string>(); // OrderBy is stable, so there is no danger in it "reordering" columns // when a role is filled by multiple columns. foreach (var role in schema.GetColumnRoleNames().OrderBy(r => r.Key.Value)) { rolesList.Add(role.Key.Value); columnNamesList.Add(role.Value); } builder.AddColumn("Role", rolesList.ToArray()); builder.AddColumn("Column", columnNamesList.ToArray()); using (var entry = rep.CreateEntry(DirTrainingInfo, RoleMappingFile)) { // REVIEW: It seems very important that we have the role mappings // be easily human interpretable and even manipulable, but relying on the // text saver/loader means that special characters like '\n' won't be reinterpretable. // On the other hand, no one is such a big lunatic that they will actually // ever go ahead and do something so stupid as that. var saver = new TextSaver(env, new TextSaver.Arguments() { Dense = true, Silent = true }); var view = builder.GetDataView(); saver.SaveData(entry.Stream, view, Utils.GetIdentityPermutation(view.Schema.ColumnCount)); } }
/// <summary> /// Create a ModelSaveContext supporting saving to a repository, for implementors of ICanSaveModel. /// </summary> public ModelSaveContext(RepositoryWriter rep, string dir, string name) { Contracts.CheckValue(rep, nameof(rep)); Repository = rep; _ectx = rep.ExceptionContext; _ectx.CheckValueOrNull(dir); _ectx.CheckNonEmpty(name, nameof(name)); Directory = dir; Strings = new NormStr.Pool(); _ent = rep.CreateEntry(dir, name); try { Writer = new BinaryWriter(_ent.Stream, Encoding.UTF8, leaveOpen: true); try { ModelHeader.BeginWrite(Writer, out FpMin, out Header); } catch { Writer.Dispose(); throw; } } catch { _ent.Dispose(); throw; } }
/// <summary> /// Save the object by calling TrySaveModel then falling back to .net serialization. /// </summary> public static void SaveModel <T>(RepositoryWriter rep, T value, string path) where T : class { if (value == null) { return; } var sm = value as ICanSaveModel; if (sm != null) { using (var ctx = new ModelSaveContext(rep, path, ModelLoadContext.ModelStreamName)) { sm.Save(ctx); ctx.Done(); } return; } var sb = value as ICanSaveInBinaryFormat; if (sb != null) { using (var ent = rep.CreateEntry(path, ModelLoadContext.NameBinary)) using (var writer = new BinaryWriter(ent.Stream, Encoding.UTF8, leaveOpen: true)) { sb.SaveAsBinary(writer); } return; } }
public static RepositoryWriter CreateNew(Stream stream, IExceptionContext ectx = null, bool useFileSystem = true) { Contracts.CheckValueOrNull(ectx); ectx.CheckValue(stream, nameof(stream)); var rep = new RepositoryWriter(stream, ectx, useFileSystem); using (var ent = rep.CreateEntry(ModelFileUtils.DirTrainingInfo, "Version.txt")) using (var writer = Utils.OpenWriter(ent.Stream)) writer.WriteLine(typeof(RepositoryWriter).Assembly.GetName().Version); return(rep); }