You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@thrift.apache.org by "ASF GitHub Bot (JIRA)" <ji...@apache.org> on 2018/04/09 11:37:06 UTC

[jira] [Commented] (THRIFT-4532) Avoid updating Thrift compiler generated code if the output has not changed

    [ https://issues.apache.org/jira/browse/THRIFT-4532?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16430407#comment-16430407 ] 

ASF GitHub Bot commented on THRIFT-4532:
----------------------------------------

mustafa-cosar closed pull request #1534: THRIFT-4532: Avoid updating Thrift compiler generated code if the output has not changed 
URL: https://github.com/apache/thrift/pull/1534
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/compiler/cpp/src/thrift/generate/t_as3_generator.cc b/compiler/cpp/src/thrift/generate/t_as3_generator.cc
index 87089b44e0..41724fe499 100644
--- a/compiler/cpp/src/thrift/generate/t_as3_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_as3_generator.cc
@@ -31,7 +31,7 @@
 #include "thrift/generate/t_oop_generator.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -83,13 +83,13 @@ class t_as3_generator : public t_oop_generator {
   void generate_xception(t_struct* txception);
   void generate_service(t_service* tservice);
 
-  void print_const_value(std::ofstream& out,
+  void print_const_value(std::ostream& out,
                          std::string name,
                          t_type* type,
                          t_const_value* value,
                          bool in_static,
                          bool defval = false);
-  std::string render_const_value(ofstream& out,
+  std::string render_const_value(ostream& out,
                                  std::string name,
                                  t_type* type,
                                  t_const_value* value);
@@ -100,19 +100,19 @@ class t_as3_generator : public t_oop_generator {
 
   void generate_as3_struct(t_struct* tstruct, bool is_exception);
 
-  void generate_as3_struct_definition(std::ofstream& out,
+  void generate_as3_struct_definition(std::ostream& out,
                                       t_struct* tstruct,
                                       bool is_xception = false,
                                       bool in_class = false,
                                       bool is_result = false);
   // removed -- equality,compare_to
-  void generate_as3_struct_reader(std::ofstream& out, t_struct* tstruct);
-  void generate_as3_validator(std::ofstream& out, t_struct* tstruct);
-  void generate_as3_struct_result_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_as3_struct_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_as3_struct_tostring(std::ofstream& out, t_struct* tstruct, bool bindable);
-  void generate_as3_meta_data_map(std::ofstream& out, t_struct* tstruct);
-  void generate_field_value_meta_data(std::ofstream& out, t_type* type);
+  void generate_as3_struct_reader(std::ostream& out, t_struct* tstruct);
+  void generate_as3_validator(std::ostream& out, t_struct* tstruct);
+  void generate_as3_struct_result_writer(std::ostream& out, t_struct* tstruct);
+  void generate_as3_struct_writer(std::ostream& out, t_struct* tstruct);
+  void generate_as3_struct_tostring(std::ostream& out, t_struct* tstruct, bool bindable);
+  void generate_as3_meta_data_map(std::ostream& out, t_struct* tstruct);
+  void generate_field_value_meta_data(std::ostream& out, t_type* type);
   std::string get_as3_type_string(t_type* type);
   void generate_reflection_setters(std::ostringstream& out,
                                    t_type* type,
@@ -122,15 +122,15 @@ class t_as3_generator : public t_oop_generator {
                                    t_type* type,
                                    std::string field_name,
                                    std::string cap_name);
-  void generate_generic_field_getters_setters(std::ofstream& out, t_struct* tstruct);
-  void generate_generic_isset_method(std::ofstream& out, t_struct* tstruct);
-  void generate_as3_bean_boilerplate(std::ofstream& out, t_struct* tstruct, bool bindable);
+  void generate_generic_field_getters_setters(std::ostream& out, t_struct* tstruct);
+  void generate_generic_isset_method(std::ostream& out, t_struct* tstruct);
+  void generate_as3_bean_boilerplate(std::ostream& out, t_struct* tstruct, bool bindable);
 
   void generate_function_helpers(t_function* tfunction);
   std::string get_cap_name(std::string name);
   std::string generate_isset_check(t_field* field);
   std::string generate_isset_check(std::string field);
-  void generate_isset_set(ofstream& out, t_field* field);
+  void generate_isset_set(ostream& out, t_field* field);
   // removed std::string isset_field_id(t_field* field);
 
   void generate_service_interface(t_service* tservice);
@@ -143,38 +143,38 @@ class t_as3_generator : public t_oop_generator {
    * Serialization constructs
    */
 
-  void generate_deserialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
+  void generate_deserialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
 
-  void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
+  void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
 
-  void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
+  void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
 
-  void generate_deserialize_list_element(std::ofstream& out,
+  void generate_deserialize_list_element(std::ostream& out,
                                          t_list* tlist,
                                          std::string prefix = "");
 
-  void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
+  void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
 
-  void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_serialize_map_element(std::ofstream& out,
+  void generate_serialize_map_element(std::ostream& out,
                                       t_map* tmap,
                                       std::string iter,
                                       std::string map);
 
-  void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
+  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
 
-  void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
+  void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
 
-  void generate_as3_doc(std::ofstream& out, t_doc* tdoc);
+  void generate_as3_doc(std::ostream& out, t_doc* tdoc);
 
-  void generate_as3_doc(std::ofstream& out, t_function* tdoc);
+  void generate_as3_doc(std::ostream& out, t_function* tdoc);
 
   /**
    * Helper rendering functions
@@ -208,7 +208,7 @@ class t_as3_generator : public t_oop_generator {
    */
 
   std::string package_name_;
-  std::ofstream f_service_;
+  ofstream_with_content_based_conditional_update f_service_;
   std::string package_dir_;
 
   bool bindable_;
@@ -353,8 +353,8 @@ void t_as3_generator::generate_typedef(t_typedef* ttypedef) {
 void t_as3_generator::generate_enum(t_enum* tenum) {
   // Make output file
   string f_enum_name = package_dir_ + "/" + (tenum->get_name()) + ".as";
-  ofstream f_enum;
-  f_enum.open(f_enum_name.c_str());
+  ofstream_with_content_based_conditional_update f_enum;
+  f_enum.open(f_enum_name);
 
   // Comment and package it
   f_enum << autogen_comment() << as3_package() << endl;
@@ -416,8 +416,8 @@ void t_as3_generator::generate_consts(std::vector<t_const*> consts) {
   }
 
   string f_consts_name = package_dir_ + "/" + program_name_ + "Constants.as";
-  ofstream f_consts;
-  f_consts.open(f_consts_name.c_str());
+  ofstream_with_content_based_conditional_update f_consts;
+  f_consts.open(f_consts_name);
 
   // Print header
   f_consts << autogen_comment() << as3_package();
@@ -443,7 +443,7 @@ void t_as3_generator::generate_consts(std::vector<t_const*> consts) {
   f_consts.close();
 }
 
-void t_as3_generator::print_const_value(std::ofstream& out,
+void t_as3_generator::print_const_value(std::ostream& out,
                                         string name,
                                         t_type* type,
                                         t_const_value* value,
@@ -567,7 +567,7 @@ void t_as3_generator::print_const_value(std::ofstream& out,
   }
 }
 
-string t_as3_generator::render_const_value(ofstream& out,
+string t_as3_generator::render_const_value(ostream& out,
                                            string name,
                                            t_type* type,
                                            t_const_value* value) {
@@ -644,7 +644,7 @@ void t_as3_generator::generate_xception(t_struct* txception) {
 void t_as3_generator::generate_as3_struct(t_struct* tstruct, bool is_exception) {
   // Make output file
   string f_struct_name = package_dir_ + "/" + (tstruct->get_name()) + ".as";
-  ofstream f_struct;
+  ofstream_with_content_based_conditional_update f_struct;
   f_struct.open(f_struct_name.c_str());
 
   f_struct << autogen_comment() << as3_package();
@@ -678,7 +678,7 @@ void t_as3_generator::generate_as3_struct(t_struct* tstruct, bool is_exception)
  * @param in_class     If inside a class, needs to be static class
  * @param is_result    If this is a result it needs a different writer
  */
-void t_as3_generator::generate_as3_struct_definition(ofstream& out,
+void t_as3_generator::generate_as3_struct_definition(ostream& out,
                                                      t_struct* tstruct,
                                                      bool is_exception,
                                                      bool in_class,
@@ -782,7 +782,7 @@ void t_as3_generator::generate_as3_struct_definition(ofstream& out,
  *
  * @param tstruct The struct definition
  */
-void t_as3_generator::generate_as3_struct_reader(ofstream& out, t_struct* tstruct) {
+void t_as3_generator::generate_as3_struct_reader(ostream& out, t_struct* tstruct) {
   out << indent() << "public function read(iprot:TProtocol):void {" << endl;
   indent_up();
 
@@ -862,7 +862,7 @@ void t_as3_generator::generate_as3_struct_reader(ofstream& out, t_struct* tstruc
 
 // generates as3 method to perform various checks
 // (e.g. check that all required fields are set)
-void t_as3_generator::generate_as3_validator(ofstream& out, t_struct* tstruct) {
+void t_as3_generator::generate_as3_validator(ostream& out, t_struct* tstruct) {
   indent(out) << "public function validate():void {" << endl;
   indent_up();
 
@@ -912,7 +912,7 @@ void t_as3_generator::generate_as3_validator(ofstream& out, t_struct* tstruct) {
  *
  * @param tstruct The struct definition
  */
-void t_as3_generator::generate_as3_struct_writer(ofstream& out, t_struct* tstruct) {
+void t_as3_generator::generate_as3_struct_writer(ostream& out, t_struct* tstruct) {
   out << indent() << "public function write(oprot:TProtocol):void {" << endl;
   indent_up();
 
@@ -971,7 +971,7 @@ void t_as3_generator::generate_as3_struct_writer(ofstream& out, t_struct* tstruc
  *
  * @param tstruct The struct definition
  */
-void t_as3_generator::generate_as3_struct_result_writer(ofstream& out, t_struct* tstruct) {
+void t_as3_generator::generate_as3_struct_result_writer(ostream& out, t_struct* tstruct) {
   out << indent() << "public function write(oprot:TProtocol):void {" << endl;
   indent_up();
 
@@ -1044,7 +1044,7 @@ void t_as3_generator::generate_reflection_setters(ostringstream& out,
   indent_down();
 }
 
-void t_as3_generator::generate_generic_field_getters_setters(std::ofstream& out,
+void t_as3_generator::generate_generic_field_getters_setters(std::ostream& out,
                                                              t_struct* tstruct) {
 
   std::ostringstream getter_stream;
@@ -1100,7 +1100,7 @@ void t_as3_generator::generate_generic_field_getters_setters(std::ofstream& out,
 }
 
 // Creates a generic isSet method that takes the field number as argument
-void t_as3_generator::generate_generic_isset_method(std::ofstream& out, t_struct* tstruct) {
+void t_as3_generator::generate_generic_isset_method(std::ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
@@ -1134,7 +1134,7 @@ void t_as3_generator::generate_generic_isset_method(std::ofstream& out, t_struct
  *
  * @param tstruct The struct definition
  */
-void t_as3_generator::generate_as3_bean_boilerplate(ofstream& out,
+void t_as3_generator::generate_as3_bean_boilerplate(ostream& out,
                                                     t_struct* tstruct,
                                                     bool bindable) {
   const vector<t_field*>& fields = tstruct->get_members();
@@ -1216,7 +1216,7 @@ void t_as3_generator::generate_as3_bean_boilerplate(ofstream& out,
  *
  * @param tstruct The struct definition
  */
-void t_as3_generator::generate_as3_struct_tostring(ofstream& out,
+void t_as3_generator::generate_as3_struct_tostring(ostream& out,
                                                    t_struct* tstruct,
                                                    bool bindable) {
   // If it's bindable, it extends EventDispatcher so toString is an override.
@@ -1293,7 +1293,7 @@ void t_as3_generator::generate_as3_struct_tostring(ofstream& out,
  *
  * @param tstruct The struct definition
  */
-void t_as3_generator::generate_as3_meta_data_map(ofstream& out, t_struct* tstruct) {
+void t_as3_generator::generate_as3_meta_data_map(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
@@ -1381,7 +1381,7 @@ std::string t_as3_generator::get_as3_type_string(t_type* type) {
   }
 }
 
-void t_as3_generator::generate_field_value_meta_data(std::ofstream& out, t_type* type) {
+void t_as3_generator::generate_field_value_meta_data(std::ostream& out, t_type* type) {
   out << endl;
   indent_up();
   indent_up();
@@ -1960,7 +1960,7 @@ void t_as3_generator::generate_process_function(t_service* tservice, t_function*
  * @param tfield The field
  * @param prefix The variable name or container for this field
  */
-void t_as3_generator::generate_deserialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_as3_generator::generate_deserialize_field(ostream& out, t_field* tfield, string prefix) {
   t_type* type = get_true_type(tfield->get_type());
 
   if (type->is_void()) {
@@ -2025,7 +2025,7 @@ void t_as3_generator::generate_deserialize_field(ofstream& out, t_field* tfield,
 /**
  * Generates an unserializer for a struct, invokes read()
  */
-void t_as3_generator::generate_deserialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_as3_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   out << indent() << prefix << " = new " << type_name(tstruct) << "();" << endl << indent()
       << prefix << ".read(iprot);" << endl;
 }
@@ -2033,7 +2033,7 @@ void t_as3_generator::generate_deserialize_struct(ofstream& out, t_struct* tstru
 /**
  * Deserializes a container by reading its size and then iterating
  */
-void t_as3_generator::generate_deserialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_as3_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) {
   scope_up(out);
 
   string obj;
@@ -2093,7 +2093,7 @@ void t_as3_generator::generate_deserialize_container(ofstream& out, t_type* ttyp
 /**
  * Generates code to deserialize a map
  */
-void t_as3_generator::generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix) {
+void t_as3_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix) {
   string key = tmp("_key");
   string val = tmp("_val");
   t_field fkey(tmap->get_key_type(), key);
@@ -2111,7 +2111,7 @@ void t_as3_generator::generate_deserialize_map_element(ofstream& out, t_map* tma
 /**
  * Deserializes a set element
  */
-void t_as3_generator::generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix) {
+void t_as3_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) {
   string elem = tmp("_elem");
   t_field felem(tset->get_elem_type(), elem);
 
@@ -2125,7 +2125,7 @@ void t_as3_generator::generate_deserialize_set_element(ofstream& out, t_set* tse
 /**
  * Deserializes a list element
  */
-void t_as3_generator::generate_deserialize_list_element(ofstream& out,
+void t_as3_generator::generate_deserialize_list_element(ostream& out,
                                                         t_list* tlist,
                                                         string prefix) {
   string elem = tmp("_elem");
@@ -2144,7 +2144,7 @@ void t_as3_generator::generate_deserialize_list_element(ofstream& out,
  * @param tfield The field to serialize
  * @param prefix Name to prepend to field name
  */
-void t_as3_generator::generate_serialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_as3_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix) {
   t_type* type = get_true_type(tfield->get_type());
 
   // Do nothing for void types
@@ -2213,7 +2213,7 @@ void t_as3_generator::generate_serialize_field(ofstream& out, t_field* tfield, s
  * @param tstruct The struct to serialize
  * @param prefix  String prefix to attach to all fields
  */
-void t_as3_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_as3_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   (void)tstruct;
   out << indent() << prefix << ".write(oprot);" << endl;
 }
@@ -2224,7 +2224,7 @@ void t_as3_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct
  * @param ttype  The type of container
  * @param prefix String prefix for fields
  */
-void t_as3_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_as3_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
   scope_up(out);
 
   if (ttype->is_map()) {
@@ -2282,7 +2282,7 @@ void t_as3_generator::generate_serialize_container(ofstream& out, t_type* ttype,
 /**
  * Serializes the members of a map.
  */
-void t_as3_generator::generate_serialize_map_element(ofstream& out,
+void t_as3_generator::generate_serialize_map_element(ostream& out,
                                                      t_map* tmap,
                                                      string iter,
                                                      string map) {
@@ -2295,7 +2295,7 @@ void t_as3_generator::generate_serialize_map_element(ofstream& out,
 /**
  * Serializes the members of a set.
  */
-void t_as3_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
+void t_as3_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
   t_field efield(tset->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "");
 }
@@ -2303,7 +2303,7 @@ void t_as3_generator::generate_serialize_set_element(ofstream& out, t_set* tset,
 /**
  * Serializes the members of a list.
  */
-void t_as3_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string iter) {
+void t_as3_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter) {
   t_field efield(tlist->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "");
 }
@@ -2390,7 +2390,7 @@ string t_as3_generator::declare_field(t_field* tfield, bool init) {
   if (init) {
     t_type* ttype = get_true_type(tfield->get_type());
     if (ttype->is_base_type() && tfield->get_value() != NULL) {
-      ofstream dummy;
+      std::ofstream dummy;
       result += " = " + render_const_value(dummy, tfield->get_name(), ttype, tfield->get_value());
     } else if (ttype->is_base_type()) {
       t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base();
@@ -2539,7 +2539,7 @@ string t_as3_generator::constant_name(string name) {
 /**
  * Emits a As3Doc comment if the provided object has a doc in Thrift
  */
-void t_as3_generator::generate_as3_doc(ofstream& out, t_doc* tdoc) {
+void t_as3_generator::generate_as3_doc(ostream& out, t_doc* tdoc) {
   if (tdoc->has_doc()) {
     generate_docstring_comment(out, "/**\n", " * ", tdoc->get_doc(), " */\n");
   }
@@ -2548,7 +2548,7 @@ void t_as3_generator::generate_as3_doc(ofstream& out, t_doc* tdoc) {
 /**
  * Emits a As3Doc comment if the provided function object has a doc in Thrift
  */
-void t_as3_generator::generate_as3_doc(ofstream& out, t_function* tfunction) {
+void t_as3_generator::generate_as3_doc(ostream& out, t_function* tfunction) {
   if (tfunction->has_doc()) {
     stringstream ss;
     ss << tfunction->get_doc();
@@ -2573,7 +2573,7 @@ std::string t_as3_generator::generate_isset_check(std::string field_name) {
   return "is" + get_cap_name("set") + get_cap_name(field_name) + "()";
 }
 
-void t_as3_generator::generate_isset_set(ofstream& out, t_field* field) {
+void t_as3_generator::generate_isset_set(ostream& out, t_field* field) {
   if (!type_can_be_null(field->get_type())) {
     indent(out) << "this.__isset_" << field->get_name() << " = true;" << endl;
   }
diff --git a/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc b/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc
index 3ae7854f98..b27fc6099d 100644
--- a/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc
@@ -33,7 +33,7 @@
 #include "thrift/generate/t_oop_generator.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -116,10 +116,10 @@ class t_c_glib_generator : public t_oop_generator {
 
 private:
   /* file streams */
-  ofstream f_types_;
-  ofstream f_types_impl_;
-  ofstream f_header_;
-  ofstream f_service_;
+  ofstream_with_content_based_conditional_update f_types_;
+  ofstream_with_content_based_conditional_update f_types_impl_;
+  ofstream_with_content_based_conditional_update f_header_;
+  ofstream_with_content_based_conditional_update f_service_;
 
   /* namespace variables */
   string nspace;
@@ -145,8 +145,8 @@ class t_c_glib_generator : public t_oop_generator {
                        bool pointer = false,
                        bool constant = false,
                        bool reference = false);
-  void declare_local_variable(ofstream& out, t_type* ttype, string& base_name, bool for_hash_table);
-  void declore_local_variable_for_write(ofstream& out, t_type* ttype, string& base_name);
+  void declare_local_variable(ostream& out, t_type* ttype, string& base_name, bool for_hash_table);
+  void declore_local_variable_for_write(ostream& out, t_type* ttype, string& base_name);
 
   /* generation functions */
   void generate_const_initializer(string name,
@@ -159,51 +159,51 @@ class t_c_glib_generator : public t_oop_generator {
   void generate_service_processor(t_service* tservice);
   void generate_service_server(t_service* tservice);
   void generate_object(t_struct* tstruct);
-  void generate_struct_writer(ofstream& out,
+  void generate_struct_writer(ostream& out,
                               t_struct* tstruct,
                               string this_name,
                               string this_get = "",
                               bool is_function = true);
-  void generate_struct_reader(ofstream& out,
+  void generate_struct_reader(ostream& out,
                               t_struct* tstruct,
                               string this_name,
                               string this_get = "",
                               bool is_function = true);
 
-  void generate_serialize_field(ofstream& out,
+  void generate_serialize_field(ostream& out,
                                 t_field* tfield,
                                 string prefix,
                                 string suffix,
                                 int error_ret);
-  void generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix, int error_ret);
-  void generate_serialize_container(ofstream& out, t_type* ttype, string prefix, int error_ret);
-  void generate_serialize_map_element(ofstream& out,
+  void generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix, int error_ret);
+  void generate_serialize_container(ostream& out, t_type* ttype, string prefix, int error_ret);
+  void generate_serialize_map_element(ostream& out,
                                       t_map* tmap,
                                       string key,
                                       string value,
                                       int error_ret);
-  void generate_serialize_set_element(ofstream& out, t_set* tset, string element, int error_ret);
-  void generate_serialize_list_element(ofstream& out,
+  void generate_serialize_set_element(ostream& out, t_set* tset, string element, int error_ret);
+  void generate_serialize_list_element(ostream& out,
                                        t_list* tlist,
                                        string list,
                                        string index,
                                        int error_ret);
 
-  void generate_deserialize_field(ofstream& out,
+  void generate_deserialize_field(ostream& out,
                                   t_field* tfield,
                                   string prefix,
                                   string suffix,
                                   int error_ret,
                                   bool allocate = true);
-  void generate_deserialize_struct(ofstream& out,
+  void generate_deserialize_struct(ostream& out,
                                    t_struct* tstruct,
                                    string prefix,
                                    int error_ret,
                                    bool allocate = true);
-  void generate_deserialize_container(ofstream& out, t_type* ttype, string prefix, int error_ret);
-  void generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix, int error_ret);
-  void generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix, int error_ret);
-  void generate_deserialize_list_element(ofstream& out,
+  void generate_deserialize_container(ostream& out, t_type* ttype, string prefix, int error_ret);
+  void generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix, int error_ret);
+  void generate_deserialize_set_element(ostream& out, t_set* tset, string prefix, int error_ret);
+  void generate_deserialize_list_element(ostream& out,
                                          t_list* tlist,
                                          string prefix,
                                          string index,
@@ -3480,7 +3480,7 @@ void t_c_glib_generator::generate_object(t_struct* tstruct) {
 /**
  * Generates functions to write Thrift structures to a stream.
  */
-void t_c_glib_generator::generate_struct_writer(ofstream& out,
+void t_c_glib_generator::generate_struct_writer(ostream& out,
                                                 t_struct* tstruct,
                                                 string this_name,
                                                 string this_get,
@@ -3553,7 +3553,7 @@ void t_c_glib_generator::generate_struct_writer(ofstream& out,
 /**
  * Generates code to read Thrift structures from a stream.
  */
-void t_c_glib_generator::generate_struct_reader(ofstream& out,
+void t_c_glib_generator::generate_struct_reader(ostream& out,
                                                 t_struct* tstruct,
                                                 string this_name,
                                                 string this_get,
@@ -3690,7 +3690,7 @@ void t_c_glib_generator::generate_struct_reader(ofstream& out,
   indent(out) << "}" << endl << endl;
 }
 
-void t_c_glib_generator::generate_serialize_field(ofstream& out,
+void t_c_glib_generator::generate_serialize_field(ostream& out,
                                                   t_field* tfield,
                                                   string prefix,
                                                   string suffix,
@@ -3756,7 +3756,7 @@ void t_c_glib_generator::generate_serialize_field(ofstream& out,
   }
 }
 
-void t_c_glib_generator::generate_serialize_struct(ofstream& out,
+void t_c_glib_generator::generate_serialize_struct(ostream& out,
                                                    t_struct* tstruct,
                                                    string prefix,
                                                    int error_ret) {
@@ -3766,7 +3766,7 @@ void t_c_glib_generator::generate_serialize_struct(ofstream& out,
       << indent() << "xfer += ret;" << endl << endl;
 }
 
-void t_c_glib_generator::generate_serialize_container(ofstream& out,
+void t_c_glib_generator::generate_serialize_container(ostream& out,
                                                       t_type* ttype,
                                                       string prefix,
                                                       int error_ret) {
@@ -3923,7 +3923,7 @@ void t_c_glib_generator::generate_serialize_container(ofstream& out,
   scope_down(out);
 }
 
-void t_c_glib_generator::generate_serialize_map_element(ofstream& out,
+void t_c_glib_generator::generate_serialize_map_element(ostream& out,
                                                         t_map* tmap,
                                                         string key,
                                                         string value,
@@ -3935,7 +3935,7 @@ void t_c_glib_generator::generate_serialize_map_element(ofstream& out,
   generate_serialize_field(out, &vfield, "", "", error_ret);
 }
 
-void t_c_glib_generator::generate_serialize_set_element(ofstream& out,
+void t_c_glib_generator::generate_serialize_set_element(ostream& out,
                                                         t_set* tset,
                                                         string element,
                                                         int error_ret) {
@@ -3943,7 +3943,7 @@ void t_c_glib_generator::generate_serialize_set_element(ofstream& out,
   generate_serialize_field(out, &efield, "", "", error_ret);
 }
 
-void t_c_glib_generator::generate_serialize_list_element(ofstream& out,
+void t_c_glib_generator::generate_serialize_list_element(ostream& out,
                                                          t_list* tlist,
                                                          string list,
                                                          string index,
@@ -3975,7 +3975,7 @@ void t_c_glib_generator::generate_serialize_list_element(ofstream& out,
 }
 
 /* deserializes a field of any type. */
-void t_c_glib_generator::generate_deserialize_field(ofstream& out,
+void t_c_glib_generator::generate_deserialize_field(ostream& out,
                                                     t_field* tfield,
                                                     string prefix,
                                                     string suffix,
@@ -4068,7 +4068,7 @@ void t_c_glib_generator::generate_deserialize_field(ofstream& out,
   }
 }
 
-void t_c_glib_generator::generate_deserialize_struct(ofstream& out,
+void t_c_glib_generator::generate_deserialize_struct(ostream& out,
                                                      t_struct* tstruct,
                                                      string prefix,
                                                      int error_ret,
@@ -4101,7 +4101,7 @@ void t_c_glib_generator::generate_deserialize_struct(ofstream& out,
   out << indent() << "}" << endl << indent() << "xfer += ret;" << endl;
 }
 
-void t_c_glib_generator::generate_deserialize_container(ofstream& out,
+void t_c_glib_generator::generate_deserialize_container(ostream& out,
                                                         t_type* ttype,
                                                         string prefix,
                                                         int error_ret) {
@@ -4202,7 +4202,7 @@ void t_c_glib_generator::generate_deserialize_container(ofstream& out,
   scope_down(out);
 }
 
-void t_c_glib_generator::declare_local_variable(ofstream& out, t_type* ttype, string& name, bool for_hash_table) {
+void t_c_glib_generator::declare_local_variable(ostream& out, t_type* ttype, string& name, bool for_hash_table) {
   string tname = type_name(ttype);
 
   /* If the given type is a typedef, find its underlying type so we
@@ -4226,7 +4226,7 @@ void t_c_glib_generator::declare_local_variable(ofstream& out, t_type* ttype, st
   }
 }
 
-void t_c_glib_generator::declore_local_variable_for_write(ofstream& out,
+void t_c_glib_generator::declore_local_variable_for_write(ostream& out,
                                                           t_type* ttype,
                                                           string& name) {
   string tname = type_name(ttype);
@@ -4236,7 +4236,7 @@ void t_c_glib_generator::declore_local_variable_for_write(ofstream& out,
   out << indent() << tname << ptr << name << init_val << ";" << endl;
 }
 
-void t_c_glib_generator::generate_deserialize_map_element(ofstream& out,
+void t_c_glib_generator::generate_deserialize_map_element(ostream& out,
                                                           t_map* tmap,
                                                           string prefix,
                                                           int error_ret) {
@@ -4270,7 +4270,7 @@ void t_c_glib_generator::generate_deserialize_map_element(ofstream& out,
   indent_down();
 }
 
-void t_c_glib_generator::generate_deserialize_set_element(ofstream& out,
+void t_c_glib_generator::generate_deserialize_set_element(ostream& out,
                                                           t_set* tset,
                                                           string prefix,
                                                           int error_ret) {
@@ -4290,7 +4290,7 @@ void t_c_glib_generator::generate_deserialize_set_element(ofstream& out,
   indent_down();
 }
 
-void t_c_glib_generator::generate_deserialize_list_element(ofstream& out,
+void t_c_glib_generator::generate_deserialize_list_element(ostream& out,
                                                            t_list* tlist,
                                                            string prefix,
                                                            string index,
diff --git a/compiler/cpp/src/thrift/generate/t_cl_generator.cc b/compiler/cpp/src/thrift/generate/t_cl_generator.cc
index d9266d11b2..628d0d8d78 100644
--- a/compiler/cpp/src/thrift/generate/t_cl_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_cl_generator.cc
@@ -79,15 +79,15 @@ class t_cl_generator : public t_oop_generator {
   void generate_struct      (t_struct*   tstruct);
   void generate_xception    (t_struct*   txception);
   void generate_service     (t_service*  tservice);
-  void generate_cl_struct (std::ofstream& out, t_struct* tstruct, bool is_exception);
-  void generate_cl_struct_internal (std::ofstream& out, t_struct* tstruct, bool is_exception);
-  void generate_exception_sig(std::ofstream& out, t_function* f);
+  void generate_cl_struct (std::ostream& out, t_struct* tstruct, bool is_exception);
+  void generate_cl_struct_internal (std::ostream& out, t_struct* tstruct, bool is_exception);
+  void generate_exception_sig(std::ostream& out, t_function* f);
   std::string render_const_value(t_type* type, t_const_value* value);
 
   std::string cl_autogen_comment();
-  void asdf_def(std::ofstream &out);
-  void package_def(std::ofstream &out);
-  void package_in(std::ofstream &out);
+  void asdf_def(std::ostream &out);
+  void package_def(std::ostream &out);
+  void package_in(std::ostream &out);
   std::string generated_package();
   std::string prefix(std::string name);
   std::string package_of(t_program* program);
@@ -107,9 +107,9 @@ class t_cl_generator : public t_oop_generator {
   /**
    * Isolate the variable definitions, as they can require structure definitions
    */
-  std::ofstream f_asd_;
-  std::ofstream f_types_;
-  std::ofstream f_vars_;
+  ofstream_with_content_based_conditional_update f_asd_;
+  ofstream_with_content_based_conditional_update f_types_;
+  ofstream_with_content_based_conditional_update f_vars_;
 
   std::string copy_options_;
 
@@ -195,7 +195,7 @@ string t_cl_generator::generated_package() {
   return program_->get_namespace("cpp");
 }
 
-void t_cl_generator::asdf_def(std::ofstream &out) {
+void t_cl_generator::asdf_def(std::ostream &out) {
   out << "(asdf:defsystem #:" << system_prefix << program_name_ << endl;
   indent_up();
   out << indent() << render_includes()
@@ -209,7 +209,7 @@ void t_cl_generator::asdf_def(std::ofstream &out) {
 /***
  * Generate a package definition. Add use references equivalent to the idl file's include statements.
  */
-void t_cl_generator::package_def(std::ofstream &out) {
+void t_cl_generator::package_def(std::ostream &out) {
   const vector<t_program*>& includes = program_->get_includes();
 
   out << "(thrift:def-package :" << package();
@@ -223,7 +223,7 @@ void t_cl_generator::package_def(std::ofstream &out) {
   out << ")" << endl << endl;
 }
 
-void t_cl_generator::package_in(std::ofstream &out) {
+void t_cl_generator::package_in(std::ostream &out) {
   out << "(cl:in-package :" << package() << ")" << endl << endl;
 }
 
@@ -381,7 +381,7 @@ void t_cl_generator::generate_xception(t_struct* txception) {
   generate_cl_struct(f_types_, txception, true);
 }
 
-void t_cl_generator::generate_cl_struct_internal(std::ofstream& out, t_struct* tstruct, bool is_exception) {
+void t_cl_generator::generate_cl_struct_internal(std::ostream& out, t_struct* tstruct, bool is_exception) {
   (void)is_exception;
   const vector<t_field*>& members = tstruct->get_members();
   vector<t_field*>::const_iterator m_iter;
@@ -417,7 +417,7 @@ void t_cl_generator::generate_cl_struct_internal(std::ofstream& out, t_struct* t
   out << ")";
 }
 
-void t_cl_generator::generate_cl_struct(std::ofstream& out, t_struct* tstruct, bool is_exception = false) {
+void t_cl_generator::generate_cl_struct(std::ostream& out, t_struct* tstruct, bool is_exception = false) {
   std::string name = type_name(tstruct);
   out << (is_exception ? "(thrift:def-exception " : "(thrift:def-struct ") <<
       prefix(name) << endl;
@@ -432,7 +432,7 @@ void t_cl_generator::generate_cl_struct(std::ofstream& out, t_struct* tstruct, b
   out << ")" << endl << endl;
 }
 
-void t_cl_generator::generate_exception_sig(std::ofstream& out, t_function* f) {
+void t_cl_generator::generate_exception_sig(std::ostream& out, t_function* f) {
   generate_cl_struct_internal(out, f->get_xceptions(), true);
 }
 
diff --git a/compiler/cpp/src/thrift/generate/t_cocoa_generator.cc b/compiler/cpp/src/thrift/generate/t_cocoa_generator.cc
index 0c0e1e0d44..5bed2d71a5 100644
--- a/compiler/cpp/src/thrift/generate/t_cocoa_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_cocoa_generator.cc
@@ -109,35 +109,35 @@ class t_cocoa_generator : public t_oop_generator {
                                  bool box_it = false);
 
   void generate_cocoa_struct(t_struct* tstruct, bool is_exception);
-  void generate_cocoa_struct_interface(std::ofstream& out,
+  void generate_cocoa_struct_interface(std::ostream& out,
                                        t_struct* tstruct,
                                        bool is_xception = false);
-  void generate_cocoa_struct_implementation(std::ofstream& out,
+  void generate_cocoa_struct_implementation(std::ostream& out,
                                             t_struct* tstruct,
                                             bool is_xception = false,
                                             bool is_result = false);
-  void generate_cocoa_struct_initializer_signature(std::ofstream& out, t_struct* tstruct);
-  void generate_cocoa_struct_init_with_coder_method(ofstream& out,
+  void generate_cocoa_struct_initializer_signature(std::ostream& out, t_struct* tstruct);
+  void generate_cocoa_struct_init_with_coder_method(ostream& out,
                                                     t_struct* tstruct,
                                                     bool is_exception);
-  void generate_cocoa_struct_encode_with_coder_method(ofstream& out,
+  void generate_cocoa_struct_encode_with_coder_method(ostream& out,
                                                       t_struct* tstruct,
                                                       bool is_exception);
-  void generate_cocoa_struct_copy_method(ofstream& out,
+  void generate_cocoa_struct_copy_method(ostream& out,
                                          t_struct* tstruct,
                                          bool is_exception);
-  void generate_cocoa_struct_hash_method(ofstream& out, t_struct* tstruct);
-  void generate_cocoa_struct_is_equal_method(ofstream& out,
+  void generate_cocoa_struct_hash_method(ostream& out, t_struct* tstruct);
+  void generate_cocoa_struct_is_equal_method(ostream& out,
                                              t_struct* tstruct,
                                              bool is_exception);
-  void generate_cocoa_struct_field_accessor_implementations(std::ofstream& out,
+  void generate_cocoa_struct_field_accessor_implementations(std::ostream& out,
                                                             t_struct* tstruct,
                                                             bool is_exception);
-  void generate_cocoa_struct_reader(std::ofstream& out, t_struct* tstruct);
-  void generate_cocoa_struct_result_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_cocoa_struct_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_cocoa_struct_validator(std::ofstream& out, t_struct* tstruct);
-  void generate_cocoa_struct_description(std::ofstream& out, t_struct* tstruct);
+  void generate_cocoa_struct_reader(std::ostream& out, t_struct* tstruct);
+  void generate_cocoa_struct_result_writer(std::ostream& out, t_struct* tstruct);
+  void generate_cocoa_struct_writer(std::ostream& out, t_struct* tstruct);
+  void generate_cocoa_struct_validator(std::ostream& out, t_struct* tstruct);
+  void generate_cocoa_struct_description(std::ostream& out, t_struct* tstruct);
 
   std::string function_result_helper_struct_type(t_service *tservice, t_function* tfunction);
   std::string function_args_helper_struct_type(t_service* tservice, t_function* tfunction);
@@ -147,29 +147,29 @@ class t_cocoa_generator : public t_oop_generator {
    * Service-level generation functions
    */
 
-  void generate_cocoa_service_protocol(std::ofstream& out, t_service* tservice);
-  void generate_cocoa_service_async_protocol(std::ofstream& out, t_service* tservice);
+  void generate_cocoa_service_protocol(std::ostream& out, t_service* tservice);
+  void generate_cocoa_service_async_protocol(std::ostream& out, t_service* tservice);
 
-  void generate_cocoa_service_client_interface(std::ofstream& out, t_service* tservice);
-  void generate_cocoa_service_client_async_interface(std::ofstream& out, t_service* tservice);
+  void generate_cocoa_service_client_interface(std::ostream& out, t_service* tservice);
+  void generate_cocoa_service_client_async_interface(std::ostream& out, t_service* tservice);
 
-  void generate_cocoa_service_client_send_function_implementation(ofstream& out,
+  void generate_cocoa_service_client_send_function_implementation(ostream& out,
                                                                   t_service* tservice,
                                                                   t_function* tfunction,
                                                                   bool needs_protocol);
-  void generate_cocoa_service_client_send_function_invocation(ofstream& out, t_function* tfunction);
-  void generate_cocoa_service_client_send_async_function_invocation(ofstream& out,
+  void generate_cocoa_service_client_send_function_invocation(ostream& out, t_function* tfunction);
+  void generate_cocoa_service_client_send_async_function_invocation(ostream& out,
                                                                     t_function* tfunction,
                                                                     string failureBlockName);
-  void generate_cocoa_service_client_recv_function_implementation(ofstream& out,
+  void generate_cocoa_service_client_recv_function_implementation(ostream& out,
                                                                   t_service* tservice,
                                                                   t_function* tfunction,
                                                                   bool needs_protocol);
-  void generate_cocoa_service_client_implementation(std::ofstream& out, t_service* tservice);
-  void generate_cocoa_service_client_async_implementation(std::ofstream& out, t_service* tservice);
+  void generate_cocoa_service_client_implementation(std::ostream& out, t_service* tservice);
+  void generate_cocoa_service_client_async_implementation(std::ostream& out, t_service* tservice);
 
-  void generate_cocoa_service_server_interface(std::ofstream& out, t_service* tservice);
-  void generate_cocoa_service_server_implementation(std::ofstream& out, t_service* tservice);
+  void generate_cocoa_service_server_interface(std::ostream& out, t_service* tservice);
+  void generate_cocoa_service_server_implementation(std::ostream& out, t_service* tservice);
   void generate_cocoa_service_helpers(t_service* tservice);
   void generate_service_client(t_service* tservice);
   void generate_service_server(t_service* tservice);
@@ -179,34 +179,34 @@ class t_cocoa_generator : public t_oop_generator {
    * Serialization constructs
    */
 
-  void generate_deserialize_field(std::ofstream& out, t_field* tfield, std::string fieldName);
+  void generate_deserialize_field(std::ostream& out, t_field* tfield, std::string fieldName);
 
-  void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
+  void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
 
-  void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
+  void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
 
-  void generate_deserialize_list_element(std::ofstream& out,
+  void generate_deserialize_list_element(std::ostream& out,
                                          t_list* tlist,
                                          std::string prefix = "");
 
-  void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
+  void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
 
-  void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string fieldName = "");
+  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string fieldName = "");
 
-  void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_serialize_map_element(std::ofstream& out,
+  void generate_serialize_map_element(std::ostream& out,
                                       t_map* tmap,
                                       std::string iter,
                                       std::string map);
 
-  void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
+  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
 
-  void generate_serialize_list_element(std::ofstream& out,
+  void generate_serialize_list_element(std::ostream& out,
                                        t_list* tlist,
                                        std::string index,
                                        std::string listName);
@@ -254,8 +254,8 @@ class t_cocoa_generator : public t_oop_generator {
    * File streams
    */
 
-  std::ofstream f_header_;
-  std::ofstream f_impl_;
+  ofstream_with_content_based_conditional_update f_header_;
+  ofstream_with_content_based_conditional_update f_impl_;
 
   bool log_unexpected_;
   bool validate_required_;
@@ -568,7 +568,7 @@ void t_cocoa_generator::generate_xception(t_struct* txception) {
  *
  * @param tstruct The struct definition
  */
-void t_cocoa_generator::generate_cocoa_struct_interface(ofstream& out,
+void t_cocoa_generator::generate_cocoa_struct_interface(ostream& out,
                                                         t_struct* tstruct,
                                                         bool is_exception) {
 
@@ -618,7 +618,7 @@ void t_cocoa_generator::generate_cocoa_struct_interface(ofstream& out,
  * Generate signature for initializer of struct with a parameter for
  * each field.
  */
-void t_cocoa_generator::generate_cocoa_struct_initializer_signature(ofstream& out,
+void t_cocoa_generator::generate_cocoa_struct_initializer_signature(ostream& out,
                                                                     t_struct* tstruct) {
   const vector<t_field*>& members = tstruct->get_members();
   vector<t_field*>::const_iterator m_iter;
@@ -641,7 +641,7 @@ void t_cocoa_generator::generate_cocoa_struct_initializer_signature(ofstream& ou
  * Generate the initWithCoder method for this struct so it's compatible with
  * the NSCoding protocol
  */
-void t_cocoa_generator::generate_cocoa_struct_init_with_coder_method(ofstream& out,
+void t_cocoa_generator::generate_cocoa_struct_init_with_coder_method(ostream& out,
                                                                      t_struct* tstruct,
                                                                      bool is_exception) {
 
@@ -713,7 +713,7 @@ void t_cocoa_generator::generate_cocoa_struct_init_with_coder_method(ofstream& o
  * Generate the encodeWithCoder method for this struct so it's compatible with
  * the NSCoding protocol
  */
-void t_cocoa_generator::generate_cocoa_struct_encode_with_coder_method(ofstream& out,
+void t_cocoa_generator::generate_cocoa_struct_encode_with_coder_method(ostream& out,
                                                                        t_struct* tstruct,
                                                                        bool is_exception) {
 
@@ -780,7 +780,7 @@ void t_cocoa_generator::generate_cocoa_struct_encode_with_coder_method(ofstream&
 /**
  * Generate the copy method for this struct
  */
-void t_cocoa_generator::generate_cocoa_struct_copy_method(ofstream& out, t_struct* tstruct, bool is_exception) {
+void t_cocoa_generator::generate_cocoa_struct_copy_method(ostream& out, t_struct* tstruct, bool is_exception) {
   out << indent() << "- (instancetype) copyWithZone:(NSZone *)zone" << endl;
   scope_up(out);
 
@@ -815,7 +815,7 @@ void t_cocoa_generator::generate_cocoa_struct_copy_method(ofstream& out, t_struc
 /**
  * Generate the hash method for this struct
  */
-void t_cocoa_generator::generate_cocoa_struct_hash_method(ofstream& out, t_struct* tstruct) {
+void t_cocoa_generator::generate_cocoa_struct_hash_method(ostream& out, t_struct* tstruct) {
   indent(out) << "- (NSUInteger) hash" << endl;
   scope_up(out);
   out << indent() << "NSUInteger hash = 17;" << endl;
@@ -846,7 +846,7 @@ void t_cocoa_generator::generate_cocoa_struct_hash_method(ofstream& out, t_struc
 /**
  * Generate the isEqual method for this struct
  */
-void t_cocoa_generator::generate_cocoa_struct_is_equal_method(ofstream& out, t_struct* tstruct, bool is_exception) {
+void t_cocoa_generator::generate_cocoa_struct_is_equal_method(ostream& out, t_struct* tstruct, bool is_exception) {
   indent(out) << "- (BOOL) isEqual: (id) anObject" << endl;
   scope_up(out);
 
@@ -913,7 +913,7 @@ void t_cocoa_generator::generate_cocoa_struct_is_equal_method(ofstream& out, t_s
  * @param is_exception Is this an exception?
  * @param is_result    If this is a result it needs a different writer
  */
-void t_cocoa_generator::generate_cocoa_struct_implementation(ofstream& out,
+void t_cocoa_generator::generate_cocoa_struct_implementation(ostream& out,
                                                              t_struct* tstruct,
                                                              bool is_exception,
                                                              bool is_result) {
@@ -1017,7 +1017,7 @@ void t_cocoa_generator::generate_cocoa_struct_implementation(ofstream& out,
  *
  * @param tstruct The struct definition
  */
-void t_cocoa_generator::generate_cocoa_struct_reader(ofstream& out, t_struct* tstruct) {
+void t_cocoa_generator::generate_cocoa_struct_reader(ostream& out, t_struct* tstruct) {
   out << "- (BOOL) read: (id <TProtocol>) inProtocol error: (NSError *__autoreleasing *)__thriftError" << endl;
   scope_up(out);
 
@@ -1111,7 +1111,7 @@ void t_cocoa_generator::generate_cocoa_struct_reader(ofstream& out, t_struct* ts
  *
  * @param tstruct The struct definition
  */
-void t_cocoa_generator::generate_cocoa_struct_writer(ofstream& out, t_struct* tstruct) {
+void t_cocoa_generator::generate_cocoa_struct_writer(ostream& out, t_struct* tstruct) {
   out << indent() << "- (BOOL) write: (id <TProtocol>) outProtocol error: (NSError *__autoreleasing *)__thriftError {" << endl;
   indent_up();
 
@@ -1162,7 +1162,7 @@ void t_cocoa_generator::generate_cocoa_struct_writer(ofstream& out, t_struct* ts
  *
  * @param tstruct The struct definition
  */
-void t_cocoa_generator::generate_cocoa_struct_result_writer(ofstream& out, t_struct* tstruct) {
+void t_cocoa_generator::generate_cocoa_struct_result_writer(ostream& out, t_struct* tstruct) {
   out << indent() << "- (BOOL) write: (id <TProtocol>) outProtocol error: (NSError *__autoreleasing *)__thriftError {" << endl;
   indent_up();
 
@@ -1225,7 +1225,7 @@ void t_cocoa_generator::generate_cocoa_struct_result_writer(ofstream& out, t_str
  *
  * @param tstruct The struct definition
  */
-void t_cocoa_generator::generate_cocoa_struct_validator(ofstream& out, t_struct* tstruct) {
+void t_cocoa_generator::generate_cocoa_struct_validator(ostream& out, t_struct* tstruct) {
   out << indent() << "- (BOOL) validate: (NSError *__autoreleasing *)__thriftError {" << endl;
   indent_up();
 
@@ -1259,7 +1259,7 @@ void t_cocoa_generator::generate_cocoa_struct_validator(ofstream& out, t_struct*
  *
  * @param tstruct The struct definition
  */
-void t_cocoa_generator::generate_cocoa_struct_field_accessor_implementations(ofstream& out,
+void t_cocoa_generator::generate_cocoa_struct_field_accessor_implementations(ostream& out,
                                                                              t_struct* tstruct,
                                                                              bool is_exception) {
   (void)is_exception;
@@ -1298,7 +1298,7 @@ void t_cocoa_generator::generate_cocoa_struct_field_accessor_implementations(ofs
  *
  * @param tstruct The struct definition
  */
-void t_cocoa_generator::generate_cocoa_struct_description(ofstream& out, t_struct* tstruct) {
+void t_cocoa_generator::generate_cocoa_struct_description(ostream& out, t_struct* tstruct) {
 
   // Allow use of debugDescription so the app can add description via a cateogory/extension
   if (debug_descriptions_) {
@@ -1428,7 +1428,7 @@ void t_cocoa_generator::generate_function_helpers(t_service *tservice, t_functio
  *
  * @param tservice The service to generate a protocol definition for
  */
-void t_cocoa_generator::generate_cocoa_service_protocol(ofstream& out, t_service* tservice) {
+void t_cocoa_generator::generate_cocoa_service_protocol(ostream& out, t_service* tservice) {
   out << "@protocol " << cocoa_prefix_ << tservice->get_name() << " <NSObject>" << endl;
 
   vector<t_function*> functions = tservice->get_functions();
@@ -1452,7 +1452,7 @@ void t_cocoa_generator::generate_cocoa_service_protocol(ofstream& out, t_service
  *
  * @param tservice The service to generate a protocol definition for
  */
-void t_cocoa_generator::generate_cocoa_service_async_protocol(ofstream& out, t_service* tservice) {
+void t_cocoa_generator::generate_cocoa_service_async_protocol(ostream& out, t_service* tservice) {
   out << "@protocol " << cocoa_prefix_ << tservice->get_name() << "Async"
       << " <NSObject>" << endl;
 
@@ -1472,7 +1472,7 @@ void t_cocoa_generator::generate_cocoa_service_async_protocol(ofstream& out, t_s
  *
  * @param tservice The service to generate a client interface definition for
  */
-void t_cocoa_generator::generate_cocoa_service_client_interface(ofstream& out,
+void t_cocoa_generator::generate_cocoa_service_client_interface(ostream& out,
                                                                 t_service* tservice) {
   out << "@interface " << cocoa_prefix_ << tservice->get_name() << "Client : TBaseClient <"
       << cocoa_prefix_ << tservice->get_name() << "> " << endl;
@@ -1488,7 +1488,7 @@ void t_cocoa_generator::generate_cocoa_service_client_interface(ofstream& out,
  *
  * @param tservice The service to generate a client interface definition for
  */
-void t_cocoa_generator::generate_cocoa_service_client_async_interface(ofstream& out,
+void t_cocoa_generator::generate_cocoa_service_client_async_interface(ostream& out,
                                                                       t_service* tservice) {
   out << "@interface " << cocoa_prefix_ << tservice->get_name() << "ClientAsync : TBaseClient <"
       << cocoa_prefix_ << tservice->get_name() << "Async> " << endl
@@ -1506,7 +1506,7 @@ void t_cocoa_generator::generate_cocoa_service_client_async_interface(ofstream&
  *
  * @param tservice The service to generate a client interface definition for
  */
-void t_cocoa_generator::generate_cocoa_service_server_interface(ofstream& out,
+void t_cocoa_generator::generate_cocoa_service_server_interface(ostream& out,
                                                                 t_service* tservice) {
   out << "@interface " << cocoa_prefix_ << tservice->get_name()
       << "Processor : NSObject <TProcessor> " << endl;
@@ -1519,7 +1519,7 @@ void t_cocoa_generator::generate_cocoa_service_server_interface(ofstream& out,
 }
 
 void t_cocoa_generator::generate_cocoa_service_client_send_function_implementation(
-    ofstream& out,
+    ostream& out,
     t_service *tservice,
     t_function* tfunction,
     bool needs_protocol) {
@@ -1577,7 +1577,7 @@ void t_cocoa_generator::generate_cocoa_service_client_send_function_implementati
 }
 
 void t_cocoa_generator::generate_cocoa_service_client_recv_function_implementation(
-    ofstream& out,
+    ostream& out,
     t_service* tservice,
     t_function* tfunction,
     bool needs_protocol) {
@@ -1666,7 +1666,7 @@ void t_cocoa_generator::generate_cocoa_service_client_recv_function_implementati
  * @param tfunction The service to generate an implementation for
  */
 void t_cocoa_generator::generate_cocoa_service_client_send_function_invocation(
-                                                                               ofstream& out,
+                                                                               ostream& out,
                                                                                t_function* tfunction) {
 
   t_struct* arg_struct = tfunction->get_arglist();
@@ -1696,7 +1696,7 @@ void t_cocoa_generator::generate_cocoa_service_client_send_function_invocation(
  * @param tfunction The service to generate an implementation for
  */
 void t_cocoa_generator::generate_cocoa_service_client_send_async_function_invocation(
-                                                                                     ofstream& out,
+                                                                                     ostream& out,
                                                                                      t_function* tfunction,
                                                                                      string failureBlockName) {
 
@@ -1730,7 +1730,7 @@ void t_cocoa_generator::generate_cocoa_service_client_send_async_function_invoca
  *
  * @param tservice The service to generate an implementation for
  */
-void t_cocoa_generator::generate_cocoa_service_client_implementation(ofstream& out,
+void t_cocoa_generator::generate_cocoa_service_client_implementation(ostream& out,
                                                                      t_service* tservice) {
 
   string name = cocoa_prefix_ + tservice->get_name() + "Client";
@@ -1814,7 +1814,7 @@ void t_cocoa_generator::generate_cocoa_service_client_implementation(ofstream& o
  *
  * @param tservice The service to generate an implementation for
  */
-void t_cocoa_generator::generate_cocoa_service_client_async_implementation(ofstream& out,
+void t_cocoa_generator::generate_cocoa_service_client_async_implementation(ostream& out,
                                                                            t_service* tservice) {
 
   string name = cocoa_prefix_ + tservice->get_name() + "ClientAsync";
@@ -1974,7 +1974,7 @@ void t_cocoa_generator::generate_cocoa_service_client_async_implementation(ofstr
  *
  * @param tservice The service to generate an implementation for
  */
-void t_cocoa_generator::generate_cocoa_service_server_implementation(ofstream& out,
+void t_cocoa_generator::generate_cocoa_service_server_implementation(ostream& out,
                                                                      t_service* tservice) {
 
   string name = cocoa_prefix_ + tservice->get_name() + "Processor";
@@ -2150,7 +2150,7 @@ void t_cocoa_generator::generate_cocoa_service_server_implementation(ofstream& o
  * @param tfield The field
  * @param fieldName The variable name for this field
  */
-void t_cocoa_generator::generate_deserialize_field(ofstream& out,
+void t_cocoa_generator::generate_deserialize_field(ostream& out,
                                                    t_field* tfield,
                                                    string fieldName) {
   t_type* type = get_true_type(tfield->get_type());
@@ -2216,7 +2216,7 @@ void t_cocoa_generator::generate_deserialize_field(ofstream& out,
 /**
  * Generates an unserializer for a struct, allocates the struct and invokes read:
  */
-void t_cocoa_generator::generate_deserialize_struct(ofstream& out,
+void t_cocoa_generator::generate_deserialize_struct(ostream& out,
                                                     t_struct* tstruct,
                                                     string fieldName) {
   indent(out) << type_name(tstruct) << fieldName << " = [[" << type_name(tstruct, true)
@@ -2227,7 +2227,7 @@ void t_cocoa_generator::generate_deserialize_struct(ofstream& out,
 /**
  * Deserializes a container by reading its size and then iterating
  */
-void t_cocoa_generator::generate_deserialize_container(ofstream& out,
+void t_cocoa_generator::generate_deserialize_container(ostream& out,
                                                        t_type* ttype,
                                                        string fieldName) {
   string size = tmp("_size");
@@ -2348,7 +2348,7 @@ string t_cocoa_generator::unbox(t_type* ttype, string field_name) {
 /**
  * Generates code to deserialize a map element
  */
-void t_cocoa_generator::generate_deserialize_map_element(ofstream& out,
+void t_cocoa_generator::generate_deserialize_map_element(ostream& out,
                                                          t_map* tmap,
                                                          string fieldName) {
   string key = tmp("_key");
@@ -2368,7 +2368,7 @@ void t_cocoa_generator::generate_deserialize_map_element(ofstream& out,
 /**
  * Deserializes a set element
  */
-void t_cocoa_generator::generate_deserialize_set_element(ofstream& out,
+void t_cocoa_generator::generate_deserialize_set_element(ostream& out,
                                                          t_set* tset,
                                                          string fieldName) {
   string elem = tmp("_elem");
@@ -2383,7 +2383,7 @@ void t_cocoa_generator::generate_deserialize_set_element(ofstream& out,
 /**
  * Deserializes a list element
  */
-void t_cocoa_generator::generate_deserialize_list_element(ofstream& out,
+void t_cocoa_generator::generate_deserialize_list_element(ostream& out,
                                                           t_list* tlist,
                                                           string fieldName) {
   string elem = tmp("_elem");
@@ -2401,7 +2401,7 @@ void t_cocoa_generator::generate_deserialize_list_element(ofstream& out,
  * @param tfield The field to serialize
  * @param fieldName Name to of the variable holding the field
  */
-void t_cocoa_generator::generate_serialize_field(ofstream& out, t_field* tfield, string fieldName) {
+void t_cocoa_generator::generate_serialize_field(ostream& out, t_field* tfield, string fieldName) {
   t_type* type = get_true_type(tfield->get_type());
 
   // Do nothing for void types
@@ -2468,7 +2468,7 @@ void t_cocoa_generator::generate_serialize_field(ofstream& out, t_field* tfield,
  * @param tstruct The struct to serialize
  * @param fieldName Name of variable holding struct
  */
-void t_cocoa_generator::generate_serialize_struct(ofstream& out,
+void t_cocoa_generator::generate_serialize_struct(ostream& out,
                                                   t_struct* tstruct,
                                                   string fieldName) {
   (void)tstruct;
@@ -2481,7 +2481,7 @@ void t_cocoa_generator::generate_serialize_struct(ofstream& out,
  * @param ttype  The type of container
  * @param fieldName Name of variable holding container
  */
-void t_cocoa_generator::generate_serialize_container(ofstream& out,
+void t_cocoa_generator::generate_serialize_container(ostream& out,
                                                      t_type* ttype,
                                                      string fieldName) {
   scope_up(out);
@@ -2547,7 +2547,7 @@ void t_cocoa_generator::generate_serialize_container(ofstream& out,
 /**
  * Serializes the members of a map.
  */
-void t_cocoa_generator::generate_serialize_map_element(ofstream& out,
+void t_cocoa_generator::generate_serialize_map_element(ostream& out,
                                                        t_map* tmap,
                                                        string key,
                                                        string mapName) {
@@ -2560,7 +2560,7 @@ void t_cocoa_generator::generate_serialize_map_element(ofstream& out,
 /**
  * Serializes the members of a set.
  */
-void t_cocoa_generator::generate_serialize_set_element(ofstream& out,
+void t_cocoa_generator::generate_serialize_set_element(ostream& out,
                                                        t_set* tset,
                                                        string elementName) {
   t_field efield(tset->get_elem_type(), elementName);
@@ -2570,7 +2570,7 @@ void t_cocoa_generator::generate_serialize_set_element(ofstream& out,
 /**
  * Serializes the members of a list.
  */
-void t_cocoa_generator::generate_serialize_list_element(ofstream& out,
+void t_cocoa_generator::generate_serialize_list_element(ostream& out,
                                                         t_list* tlist,
                                                         string index,
                                                         string listName) {
diff --git a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc
index c78b806ed1..3e8f728d24 100644
--- a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc
@@ -112,8 +112,8 @@ class t_cpp_generator : public t_oop_generator {
 
   void generate_typedef(t_typedef* ttypedef);
   void generate_enum(t_enum* tenum);
-  void generate_enum_ostream_operator_decl(std::ofstream& out, t_enum* tenum);
-  void generate_enum_ostream_operator(std::ofstream& out, t_enum* tenum);
+  void generate_enum_ostream_operator_decl(std::ostream& out, t_enum* tenum);
+  void generate_enum_ostream_operator(std::ostream& out, t_enum* tenum);
   void generate_forward_declaration(t_struct* tstruct);
   void generate_struct(t_struct* tstruct) { generate_cpp_struct(tstruct, false); }
   void generate_xception(t_struct* txception) { generate_cpp_struct(txception, true); }
@@ -121,13 +121,13 @@ class t_cpp_generator : public t_oop_generator {
 
   void generate_service(t_service* tservice);
 
-  void print_const_value(std::ofstream& out, std::string name, t_type* type, t_const_value* value);
-  std::string render_const_value(std::ofstream& out,
+  void print_const_value(std::ostream& out, std::string name, t_type* type, t_const_value* value);
+  std::string render_const_value(std::ostream& out,
                                  std::string name,
                                  t_type* type,
                                  t_const_value* value);
 
-  void generate_struct_declaration(std::ofstream& out,
+  void generate_struct_declaration(std::ostream& out,
                                    t_struct* tstruct,
                                    bool is_exception = false,
                                    bool pointers = false,
@@ -135,26 +135,26 @@ class t_cpp_generator : public t_oop_generator {
                                    bool write = true,
                                    bool swap = false,
                                    bool is_user_struct = false);
-  void generate_struct_definition(std::ofstream& out,
-                                  std::ofstream& force_cpp_out,
+  void generate_struct_definition(std::ostream& out,
+                                  std::ostream& force_cpp_out,
                                   t_struct* tstruct,
                                   bool setters = true,
                                   bool is_user_struct = false);
-  void generate_copy_constructor(std::ofstream& out, t_struct* tstruct, bool is_exception);
-  void generate_move_constructor(std::ofstream& out, t_struct* tstruct, bool is_exception);
-  void generate_constructor_helper(std::ofstream& out,
+  void generate_copy_constructor(std::ostream& out, t_struct* tstruct, bool is_exception);
+  void generate_move_constructor(std::ostream& out, t_struct* tstruct, bool is_exception);
+  void generate_constructor_helper(std::ostream& out,
                                    t_struct* tstruct,
                                    bool is_excpetion,
                                    bool is_move);
-  void generate_assignment_operator(std::ofstream& out, t_struct* tstruct);
-  void generate_move_assignment_operator(std::ofstream& out, t_struct* tstruct);
-  void generate_assignment_helper(std::ofstream& out, t_struct* tstruct, bool is_move);
-  void generate_struct_reader(std::ofstream& out, t_struct* tstruct, bool pointers = false);
-  void generate_struct_writer(std::ofstream& out, t_struct* tstruct, bool pointers = false);
-  void generate_struct_result_writer(std::ofstream& out, t_struct* tstruct, bool pointers = false);
-  void generate_struct_swap(std::ofstream& out, t_struct* tstruct);
-  void generate_struct_print_method(std::ofstream& out, t_struct* tstruct);
-  void generate_exception_what_method(std::ofstream& out, t_struct* tstruct);
+  void generate_assignment_operator(std::ostream& out, t_struct* tstruct);
+  void generate_move_assignment_operator(std::ostream& out, t_struct* tstruct);
+  void generate_assignment_helper(std::ostream& out, t_struct* tstruct, bool is_move);
+  void generate_struct_reader(std::ostream& out, t_struct* tstruct, bool pointers = false);
+  void generate_struct_writer(std::ostream& out, t_struct* tstruct, bool pointers = false);
+  void generate_struct_result_writer(std::ostream& out, t_struct* tstruct, bool pointers = false);
+  void generate_struct_swap(std::ostream& out, t_struct* tstruct);
+  void generate_struct_print_method(std::ostream& out, t_struct* tstruct);
+  void generate_exception_what_method(std::ostream& out, t_struct* tstruct);
 
   /**
    * Service-level generation functions
@@ -179,45 +179,45 @@ class t_cpp_generator : public t_oop_generator {
    * Serialization constructs
    */
 
-  void generate_deserialize_field(std::ofstream& out,
+  void generate_deserialize_field(std::ostream& out,
                                   t_field* tfield,
                                   std::string prefix = "",
                                   std::string suffix = "");
 
-  void generate_deserialize_struct(std::ofstream& out,
+  void generate_deserialize_struct(std::ostream& out,
                                    t_struct* tstruct,
                                    std::string prefix = "",
                                    bool pointer = false);
 
-  void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
+  void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
 
-  void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
+  void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
 
-  void generate_deserialize_list_element(std::ofstream& out,
+  void generate_deserialize_list_element(std::ostream& out,
                                          t_list* tlist,
                                          std::string prefix,
                                          bool push_back,
                                          std::string index);
 
-  void generate_serialize_field(std::ofstream& out,
+  void generate_serialize_field(std::ostream& out,
                                 t_field* tfield,
                                 std::string prefix = "",
                                 std::string suffix = "");
 
-  void generate_serialize_struct(std::ofstream& out,
+  void generate_serialize_struct(std::ostream& out,
                                  t_struct* tstruct,
                                  std::string prefix = "",
                                  bool pointer = false);
 
-  void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_serialize_map_element(std::ofstream& out, t_map* tmap, std::string iter);
+  void generate_serialize_map_element(std::ostream& out, t_map* tmap, std::string iter);
 
-  void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
+  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
 
-  void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
+  void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
 
   void generate_function_call(ostream& out,
                               t_function* tfunction,
@@ -248,16 +248,16 @@ class t_cpp_generator : public t_oop_generator {
   std::string argument_list(t_struct* tstruct, bool name_params = true, bool start_comma = false);
   std::string type_to_enum(t_type* ttype);
 
-  void generate_enum_constant_list(std::ofstream& f,
+  void generate_enum_constant_list(std::ostream& f,
                                    const vector<t_enum_value*>& constants,
                                    const char* prefix,
                                    const char* suffix,
                                    bool include_values);
 
-  void generate_struct_ostream_operator_decl(std::ofstream& f, t_struct* tstruct);
-  void generate_struct_ostream_operator(std::ofstream& f, t_struct* tstruct);
-  void generate_struct_print_method_decl(std::ofstream& f, t_struct* tstruct);
-  void generate_exception_what_method_decl(std::ofstream& f,
+  void generate_struct_ostream_operator_decl(std::ostream& f, t_struct* tstruct);
+  void generate_struct_ostream_operator(std::ostream& f, t_struct* tstruct);
+  void generate_struct_print_method_decl(std::ostream& f, t_struct* tstruct);
+  void generate_exception_what_method_decl(std::ostream& f,
                                            t_struct* tstruct,
                                            bool external = false);
 
@@ -360,12 +360,12 @@ class t_cpp_generator : public t_oop_generator {
    * function.
    */
 
-  std::ofstream f_types_;
-  std::ofstream f_types_impl_;
-  std::ofstream f_types_tcc_;
-  std::ofstream f_header_;
-  std::ofstream f_service_;
-  std::ofstream f_service_tcc_;
+  ofstream_with_content_based_conditional_update f_types_;
+  ofstream_with_content_based_conditional_update f_types_impl_;
+  ofstream_with_content_based_conditional_update f_types_tcc_;
+  ofstream_with_content_based_conditional_update f_header_;
+  ofstream_with_content_based_conditional_update f_service_;
+  ofstream_with_content_based_conditional_update f_service_tcc_;
 
   // The ProcessorGenerator is used to generate parts of the code,
   // so it needs access to many of our protected members and methods.
@@ -386,7 +386,7 @@ void t_cpp_generator::init_generator() {
 
   // Make output file
   string f_types_name = get_out_dir() + program_name_ + "_types.h";
-  f_types_.open(f_types_name.c_str());
+  f_types_.open(f_types_name);
 
   string f_types_impl_name = get_out_dir() + program_name_ + "_types.cpp";
   f_types_impl_.open(f_types_impl_name.c_str());
@@ -505,7 +505,7 @@ void t_cpp_generator::generate_typedef(t_typedef* ttypedef) {
            << ttypedef->get_symbolic() << ";" << endl << endl;
 }
 
-void t_cpp_generator::generate_enum_constant_list(std::ofstream& f,
+void t_cpp_generator::generate_enum_constant_list(std::ostream& f,
                                                   const vector<t_enum_value*>& constants,
                                                   const char* prefix,
                                                   const char* suffix,
@@ -585,7 +585,7 @@ void t_cpp_generator::generate_enum(t_enum* tenum) {
   generate_enum_ostream_operator(f_types_impl_, tenum);
 }
 
-void t_cpp_generator::generate_enum_ostream_operator_decl(std::ofstream& out, t_enum* tenum) {
+void t_cpp_generator::generate_enum_ostream_operator_decl(std::ostream& out, t_enum* tenum) {
 
   out << "std::ostream& operator<<(std::ostream& out, const ";
   if (gen_pure_enums_) {
@@ -597,7 +597,7 @@ void t_cpp_generator::generate_enum_ostream_operator_decl(std::ofstream& out, t_
   out << endl;
 }
 
-void t_cpp_generator::generate_enum_ostream_operator(std::ofstream& out, t_enum* tenum) {
+void t_cpp_generator::generate_enum_ostream_operator(std::ostream& out, t_enum* tenum) {
 
   // If we've been told the consuming application will provide an ostream
   // operator definition then we only make a declaration:
@@ -635,12 +635,12 @@ void t_cpp_generator::generate_enum_ostream_operator(std::ofstream& out, t_enum*
  */
 void t_cpp_generator::generate_consts(std::vector<t_const*> consts) {
   string f_consts_name = get_out_dir() + program_name_ + "_constants.h";
-  ofstream f_consts;
-  f_consts.open(f_consts_name.c_str());
+  ofstream_with_content_based_conditional_update f_consts;
+  f_consts.open(f_consts_name);
 
   string f_consts_impl_name = get_out_dir() + program_name_ + "_constants.cpp";
-  ofstream f_consts_impl;
-  f_consts_impl.open(f_consts_impl_name.c_str());
+  ofstream_with_content_based_conditional_update f_consts_impl;
+  f_consts_impl.open(f_consts_impl_name);
 
   // Print header
   f_consts << autogen_comment();
@@ -684,6 +684,7 @@ void t_cpp_generator::generate_consts(std::vector<t_const*> consts) {
   f_consts.close();
 
   f_consts_impl << endl << ns_close_ << endl << endl;
+  f_consts_impl.close();
 }
 
 /**
@@ -691,7 +692,7 @@ void t_cpp_generator::generate_consts(std::vector<t_const*> consts) {
  * is NOT performed in this function as it is always run beforehand using the
  * validate_types method in main.cc
  */
-void t_cpp_generator::print_const_value(ofstream& out,
+void t_cpp_generator::print_const_value(ostream& out,
                                         string name,
                                         t_type* type,
                                         t_const_value* value) {
@@ -764,7 +765,7 @@ void t_cpp_generator::print_const_value(ofstream& out,
 /**
  *
  */
-string t_cpp_generator::render_const_value(ofstream& out,
+string t_cpp_generator::render_const_value(ostream& out,
                                            string name,
                                            t_type* type,
                                            t_const_value* value) {
@@ -826,7 +827,7 @@ void t_cpp_generator::generate_cpp_struct(t_struct* tstruct, bool is_exception)
   generate_struct_declaration(f_types_, tstruct, is_exception, false, true, true, true, true);
   generate_struct_definition(f_types_impl_, f_types_impl_, tstruct, true, true);
 
-  std::ofstream& out = (gen_templates_ ? f_types_tcc_ : f_types_impl_);
+  std::ostream& out = (gen_templates_ ? f_types_tcc_ : f_types_impl_);
   generate_struct_reader(out, tstruct);
   generate_struct_writer(out, tstruct);
   generate_struct_swap(f_types_impl_, tstruct);
@@ -848,13 +849,13 @@ void t_cpp_generator::generate_cpp_struct(t_struct* tstruct, bool is_exception)
   }
 }
 
-void t_cpp_generator::generate_copy_constructor(ofstream& out,
+void t_cpp_generator::generate_copy_constructor(ostream& out,
                                                 t_struct* tstruct,
                                                 bool is_exception) {
   generate_constructor_helper(out, tstruct, is_exception, /*is_move=*/false);
 }
 
-void t_cpp_generator::generate_move_constructor(ofstream& out,
+void t_cpp_generator::generate_move_constructor(ostream& out,
                                                 t_struct* tstruct,
                                                 bool is_exception) {
   generate_constructor_helper(out, tstruct, is_exception, /*is_move=*/true);
@@ -870,7 +871,7 @@ std::string maybeMove(std::string const& other, bool move) {
 }
 }
 
-void t_cpp_generator::generate_constructor_helper(ofstream& out,
+void t_cpp_generator::generate_constructor_helper(ostream& out,
                                                   t_struct* tstruct,
                                                   bool is_exception,
                                                   bool is_move) {
@@ -913,15 +914,15 @@ void t_cpp_generator::generate_constructor_helper(ofstream& out,
   indent(out) << "}" << endl;
 }
 
-void t_cpp_generator::generate_assignment_operator(ofstream& out, t_struct* tstruct) {
+void t_cpp_generator::generate_assignment_operator(ostream& out, t_struct* tstruct) {
   generate_assignment_helper(out, tstruct, /*is_move=*/false);
 }
 
-void t_cpp_generator::generate_move_assignment_operator(ofstream& out, t_struct* tstruct) {
+void t_cpp_generator::generate_move_assignment_operator(ostream& out, t_struct* tstruct) {
   generate_assignment_helper(out, tstruct, /*is_move=*/true);
 }
 
-void t_cpp_generator::generate_assignment_helper(ofstream& out, t_struct* tstruct, bool is_move) {
+void t_cpp_generator::generate_assignment_helper(ostream& out, t_struct* tstruct, bool is_move) {
   std::string tmp_name = tmp("other");
 
   indent(out) << tstruct->get_name() << "& " << tstruct->get_name() << "::operator=(";
@@ -964,7 +965,7 @@ void t_cpp_generator::generate_assignment_helper(ofstream& out, t_struct* tstruc
  * @param out Output stream
  * @param tstruct The struct
  */
-void t_cpp_generator::generate_struct_declaration(ofstream& out,
+void t_cpp_generator::generate_struct_declaration(ostream& out,
                                                   t_struct* tstruct,
                                                   bool is_exception,
                                                   bool pointers,
@@ -1213,8 +1214,8 @@ void t_cpp_generator::generate_struct_declaration(ofstream& out,
   }
 }
 
-void t_cpp_generator::generate_struct_definition(ofstream& out,
-                                                 ofstream& force_cpp_out,
+void t_cpp_generator::generate_struct_definition(ostream& out,
+                                                 ostream& force_cpp_out,
                                                  t_struct* tstruct,
                                                  bool setters,
                                                  bool is_user_struct) {
@@ -1271,7 +1272,7 @@ void t_cpp_generator::generate_struct_definition(ofstream& out,
  * @param out Stream to write to
  * @param tstruct The struct
  */
-void t_cpp_generator::generate_struct_reader(ofstream& out, t_struct* tstruct, bool pointers) {
+void t_cpp_generator::generate_struct_reader(ostream& out, t_struct* tstruct, bool pointers) {
   if (gen_templates_) {
     out << indent() << "template <class Protocol_>" << endl << indent() << "uint32_t "
         << tstruct->get_name() << "::read(Protocol_* iprot) {" << endl;
@@ -1394,7 +1395,7 @@ void t_cpp_generator::generate_struct_reader(ofstream& out, t_struct* tstruct, b
  * @param out Stream to write to
  * @param tstruct The struct
  */
-void t_cpp_generator::generate_struct_writer(ofstream& out, t_struct* tstruct, bool pointers) {
+void t_cpp_generator::generate_struct_writer(ostream& out, t_struct* tstruct, bool pointers) {
   string name = tstruct->get_name();
   const vector<t_field*>& fields = tstruct->get_sorted_members();
   vector<t_field*>::const_iterator f_iter;
@@ -1460,7 +1461,7 @@ void t_cpp_generator::generate_struct_writer(ofstream& out, t_struct* tstruct, b
  * @param out Output stream
  * @param tstruct The result struct
  */
-void t_cpp_generator::generate_struct_result_writer(ofstream& out,
+void t_cpp_generator::generate_struct_result_writer(ostream& out,
                                                     t_struct* tstruct,
                                                     bool pointers) {
   string name = tstruct->get_name();
@@ -1524,7 +1525,7 @@ void t_cpp_generator::generate_struct_result_writer(ofstream& out,
  * @param out Stream to write to
  * @param tstruct The struct
  */
-void t_cpp_generator::generate_struct_swap(ofstream& out, t_struct* tstruct) {
+void t_cpp_generator::generate_struct_swap(ostream& out, t_struct* tstruct) {
   out << indent() << "void swap(" << tstruct->get_name() << " &a, " << tstruct->get_name()
       << " &b) {" << endl;
   indent_up();
@@ -1561,14 +1562,14 @@ void t_cpp_generator::generate_struct_swap(ofstream& out, t_struct* tstruct) {
   out << endl;
 }
 
-void t_cpp_generator::generate_struct_ostream_operator_decl(std::ofstream& out, t_struct* tstruct) {
+void t_cpp_generator::generate_struct_ostream_operator_decl(std::ostream& out, t_struct* tstruct) {
   out << "std::ostream& operator<<(std::ostream& out, const "
       << tstruct->get_name()
       << "& obj);" << endl;
   out << endl;
 }
 
-void t_cpp_generator::generate_struct_ostream_operator(std::ofstream& out, t_struct* tstruct) {
+void t_cpp_generator::generate_struct_ostream_operator(std::ostream& out, t_struct* tstruct) {
   if (!has_custom_ostream(tstruct)) {
     // thrift defines this behavior
     out << "std::ostream& operator<<(std::ostream& out, const "
@@ -1582,7 +1583,7 @@ void t_cpp_generator::generate_struct_ostream_operator(std::ofstream& out, t_str
   }
 }
 
-void t_cpp_generator::generate_struct_print_method_decl(std::ofstream& out, t_struct* tstruct) {
+void t_cpp_generator::generate_struct_print_method_decl(std::ostream& out, t_struct* tstruct) {
   out << "void ";
   if (tstruct) {
     out << tstruct->get_name() << "::";
@@ -1590,7 +1591,7 @@ void t_cpp_generator::generate_struct_print_method_decl(std::ofstream& out, t_st
   out << "printTo(std::ostream& out) const";
 }
 
-void t_cpp_generator::generate_exception_what_method_decl(std::ofstream& out,
+void t_cpp_generator::generate_exception_what_method_decl(std::ostream& out,
                                                           t_struct* tstruct,
                                                           bool external) {
   out << "const char* ";
@@ -1601,33 +1602,33 @@ void t_cpp_generator::generate_exception_what_method_decl(std::ofstream& out,
 }
 
 namespace struct_ostream_operator_generator {
-void generate_required_field_value(std::ofstream& out, const t_field* field) {
+void generate_required_field_value(std::ostream& out, const t_field* field) {
   out << " << to_string(" << field->get_name() << ")";
 }
 
-void generate_optional_field_value(std::ofstream& out, const t_field* field) {
+void generate_optional_field_value(std::ostream& out, const t_field* field) {
   out << "; (__isset." << field->get_name() << " ? (out";
   generate_required_field_value(out, field);
   out << ") : (out << \"<null>\"))";
 }
 
-void generate_field_value(std::ofstream& out, const t_field* field) {
+void generate_field_value(std::ostream& out, const t_field* field) {
   if (field->get_req() == t_field::T_OPTIONAL)
     generate_optional_field_value(out, field);
   else
     generate_required_field_value(out, field);
 }
 
-void generate_field_name(std::ofstream& out, const t_field* field) {
+void generate_field_name(std::ostream& out, const t_field* field) {
   out << "\"" << field->get_name() << "=\"";
 }
 
-void generate_field(std::ofstream& out, const t_field* field) {
+void generate_field(std::ostream& out, const t_field* field) {
   generate_field_name(out, field);
   generate_field_value(out, field);
 }
 
-void generate_fields(std::ofstream& out,
+void generate_fields(std::ostream& out,
                      const vector<t_field*>& fields,
                      const std::string& indent) {
   const vector<t_field*>::const_iterator beg = fields.begin();
@@ -1649,7 +1650,7 @@ void generate_fields(std::ofstream& out,
 /**
  * Generates operator<<
  */
-void t_cpp_generator::generate_struct_print_method(std::ofstream& out, t_struct* tstruct) {
+void t_cpp_generator::generate_struct_print_method(std::ostream& out, t_struct* tstruct) {
   out << indent();
   generate_struct_print_method_decl(out, tstruct);
   out << " {" << endl;
@@ -1668,7 +1669,7 @@ void t_cpp_generator::generate_struct_print_method(std::ofstream& out, t_struct*
 /**
  * Generates what() method for exceptions
  */
-void t_cpp_generator::generate_exception_what_method(std::ofstream& out, t_struct* tstruct) {
+void t_cpp_generator::generate_exception_what_method(std::ostream& out, t_struct* tstruct) {
   out << indent();
   generate_exception_what_method_decl(out, tstruct, true);
   out << " {" << endl;
@@ -1835,7 +1836,7 @@ void t_cpp_generator::generate_service(t_service* tservice) {
 void t_cpp_generator::generate_service_helpers(t_service* tservice) {
   vector<t_function*> functions = tservice->get_functions();
   vector<t_function*>::iterator f_iter;
-  std::ofstream& out = (gen_templates_ ? f_service_tcc_ : f_service_);
+  std::ostream& out = (gen_templates_ ? f_service_tcc_ : f_service_);
 
   for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
     t_struct* ts = (*f_iter)->get_arglist();
@@ -2071,7 +2072,7 @@ void t_cpp_generator::generate_service_async_skeleton(t_service* tservice) {
 
   string ns = namespace_prefix(tservice->get_program()->get_namespace("cpp"));
 
-  ofstream f_skeleton;
+  ofstream_with_content_based_conditional_update f_skeleton;
   f_skeleton.open(f_skeleton_name.c_str());
   f_skeleton << "// This autogenerated skeleton file illustrates one way to adapt a synchronous"
              << endl << "// interface into an asynchronous interface. You should copy it to another"
@@ -2239,7 +2240,7 @@ void t_cpp_generator::generate_service_client(t_service* tservice, string style)
     ifstyle = "CobCl";
   }
 
-  std::ofstream& out = (gen_templates_ ? f_service_tcc_ : f_service_);
+  std::ostream& out = (gen_templates_ ? f_service_tcc_ : f_service_);
   string template_header, template_suffix, short_suffix, protocol_type, _this;
   string const prot_factory_type = "::apache::thrift::protocol::TProtocolFactory";
   if (gen_templates_) {
@@ -2830,8 +2831,8 @@ class ProcessorGenerator {
 
   t_cpp_generator* generator_;
   t_service* service_;
-  std::ofstream& f_header_;
-  std::ofstream& f_out_;
+  std::ostream& f_header_;
+  std::ostream& f_out_;
   string service_name_;
   string style_;
   string pstyle_;
@@ -3205,7 +3206,7 @@ void t_cpp_generator::generate_function_helpers(t_service* tservice, t_function*
     return;
   }
 
-  std::ofstream& out = (gen_templates_ ? f_service_tcc_ : f_service_);
+  std::ostream& out = (gen_templates_ ? f_service_tcc_ : f_service_);
 
   t_struct result(program_, tservice->get_name() + "_" + tfunction->get_name() + "_result");
   t_field success(tfunction->get_returntype(), "success", 0);
@@ -3252,7 +3253,7 @@ void t_cpp_generator::generate_process_function(t_service* tservice,
   vector<t_field*>::const_iterator x_iter;
   string service_func_name = "\"" + tservice->get_name() + "." + tfunction->get_name() + "\"";
 
-  std::ofstream& out = (gen_templates_ ? f_service_tcc_ : f_service_);
+  std::ostream& out = (gen_templates_ ? f_service_tcc_ : f_service_);
 
   string prot_type = (specialized ? "Protocol_" : "::apache::thrift::protocol::TProtocol");
   string class_suffix;
@@ -3664,7 +3665,7 @@ void t_cpp_generator::generate_service_skeleton(t_service* tservice) {
 
   string ns = namespace_prefix(tservice->get_program()->get_namespace("cpp"));
 
-  ofstream f_skeleton;
+  ofstream_with_content_based_conditional_update f_skeleton;
   f_skeleton.open(f_skeleton_name.c_str());
   f_skeleton << "// This autogenerated skeleton file illustrates how to build a server." << endl
              << "// You should copy it to another filename to avoid overwriting it." << endl << endl
@@ -3726,7 +3727,7 @@ void t_cpp_generator::generate_service_skeleton(t_service* tservice) {
 /**
  * Deserializes a field of any type.
  */
-void t_cpp_generator::generate_deserialize_field(ofstream& out,
+void t_cpp_generator::generate_deserialize_field(ostream& out,
                                                  t_field* tfield,
                                                  string prefix,
                                                  string suffix) {
@@ -3795,7 +3796,7 @@ void t_cpp_generator::generate_deserialize_field(ofstream& out,
  * buffer for deserialization, and that there is a variable protocol which
  * is a reference to a TProtocol serialization object.
  */
-void t_cpp_generator::generate_deserialize_struct(ofstream& out,
+void t_cpp_generator::generate_deserialize_struct(ostream& out,
                                                   t_struct* tstruct,
                                                   string prefix,
                                                   bool pointer) {
@@ -3819,7 +3820,7 @@ void t_cpp_generator::generate_deserialize_struct(ofstream& out,
   }
 }
 
-void t_cpp_generator::generate_deserialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_cpp_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) {
   scope_up(out);
 
   string size = tmp("_size");
@@ -3880,7 +3881,7 @@ void t_cpp_generator::generate_deserialize_container(ofstream& out, t_type* ttyp
 /**
  * Generates code to deserialize a map
  */
-void t_cpp_generator::generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix) {
+void t_cpp_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix) {
   string key = tmp("_key");
   string val = tmp("_val");
   t_field fkey(tmap->get_key_type(), key);
@@ -3895,7 +3896,7 @@ void t_cpp_generator::generate_deserialize_map_element(ofstream& out, t_map* tma
   generate_deserialize_field(out, &fval);
 }
 
-void t_cpp_generator::generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix) {
+void t_cpp_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) {
   string elem = tmp("_elem");
   t_field felem(tset->get_elem_type(), elem);
 
@@ -3906,7 +3907,7 @@ void t_cpp_generator::generate_deserialize_set_element(ofstream& out, t_set* tse
   indent(out) << prefix << ".insert(" << elem << ");" << endl;
 }
 
-void t_cpp_generator::generate_deserialize_list_element(ofstream& out,
+void t_cpp_generator::generate_deserialize_list_element(ostream& out,
                                                         t_list* tlist,
                                                         string prefix,
                                                         bool use_push,
@@ -3929,7 +3930,7 @@ void t_cpp_generator::generate_deserialize_list_element(ofstream& out,
  * @param tfield The field to serialize
  * @param prefix Name to prepend to field name
  */
-void t_cpp_generator::generate_serialize_field(ofstream& out,
+void t_cpp_generator::generate_serialize_field(ostream& out,
                                                t_field* tfield,
                                                string prefix,
                                                string suffix) {
@@ -4002,7 +4003,7 @@ void t_cpp_generator::generate_serialize_field(ofstream& out,
  * @param tstruct The struct to serialize
  * @param prefix  String prefix to attach to all fields
  */
-void t_cpp_generator::generate_serialize_struct(ofstream& out,
+void t_cpp_generator::generate_serialize_struct(ostream& out,
                                                 t_struct* tstruct,
                                                 string prefix,
                                                 bool pointer) {
@@ -4019,7 +4020,7 @@ void t_cpp_generator::generate_serialize_struct(ofstream& out,
   }
 }
 
-void t_cpp_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_cpp_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
   scope_up(out);
 
   if (ttype->is_map()) {
@@ -4065,7 +4066,7 @@ void t_cpp_generator::generate_serialize_container(ofstream& out, t_type* ttype,
  * Serializes the members of a map.
  *
  */
-void t_cpp_generator::generate_serialize_map_element(ofstream& out, t_map* tmap, string iter) {
+void t_cpp_generator::generate_serialize_map_element(ostream& out, t_map* tmap, string iter) {
   t_field kfield(tmap->get_key_type(), iter + "->first");
   generate_serialize_field(out, &kfield, "");
 
@@ -4076,7 +4077,7 @@ void t_cpp_generator::generate_serialize_map_element(ofstream& out, t_map* tmap,
 /**
  * Serializes the members of a set.
  */
-void t_cpp_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
+void t_cpp_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
   t_field efield(tset->get_elem_type(), "(*" + iter + ")");
   generate_serialize_field(out, &efield, "");
 }
@@ -4084,7 +4085,7 @@ void t_cpp_generator::generate_serialize_set_element(ofstream& out, t_set* tset,
 /**
  * Serializes the members of a list.
  */
-void t_cpp_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string iter) {
+void t_cpp_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter) {
   t_field efield(tlist->get_elem_type(), "(*" + iter + ")");
   generate_serialize_field(out, &efield, "");
 }
diff --git a/compiler/cpp/src/thrift/generate/t_csharp_generator.cc b/compiler/cpp/src/thrift/generate/t_csharp_generator.cc
index b108c45643..b471fda08d 100644
--- a/compiler/cpp/src/thrift/generate/t_csharp_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_csharp_generator.cc
@@ -37,7 +37,7 @@
 #include "thrift/generate/t_oop_generator.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -100,46 +100,46 @@ class t_csharp_generator : public t_oop_generator {
   void generate_union(t_struct* tunion);
   void generate_xception(t_struct* txception);
   void generate_service(t_service* tservice);
-  void generate_property(ofstream& out, t_field* tfield, bool isPublic, bool generateIsset);
-  void generate_csharp_property(ofstream& out,
+  void generate_property(ostream& out, t_field* tfield, bool isPublic, bool generateIsset);
+  void generate_csharp_property(ostream& out,
                                 t_field* tfield,
                                 bool isPublic,
                                 bool includeIsset = true,
                                 std::string fieldPrefix = "");
-  bool print_const_value(std::ofstream& out,
+  bool print_const_value(std::ostream& out,
                          std::string name,
                          t_type* type,
                          t_const_value* value,
                          bool in_static,
                          bool defval = false,
                          bool needtype = false);
-  std::string render_const_value(std::ofstream& out,
+  std::string render_const_value(std::ostream& out,
                                  std::string name,
                                  t_type* type,
                                  t_const_value* value);
-  void print_const_constructor(std::ofstream& out, std::vector<t_const*> consts);
-  void print_const_def_value(std::ofstream& out,
+  void print_const_constructor(std::ostream& out, std::vector<t_const*> consts);
+  void print_const_def_value(std::ostream& out,
                              std::string name,
                              t_type* type,
                              t_const_value* value);
 
   void generate_csharp_struct(t_struct* tstruct, bool is_exception);
   void generate_csharp_union(t_struct* tunion);
-  void generate_csharp_struct_definition(std::ofstream& out,
+  void generate_csharp_struct_definition(std::ostream& out,
                                          t_struct* tstruct,
                                          bool is_xception = false,
                                          bool in_class = false,
                                          bool is_result = false);
-  void generate_csharp_union_definition(std::ofstream& out, t_struct* tunion);
-  void generate_csharp_union_class(std::ofstream& out, t_struct* tunion, t_field* tfield);
-  void generate_csharp_wcffault(std::ofstream& out, t_struct* tstruct);
-  void generate_csharp_struct_reader(std::ofstream& out, t_struct* tstruct);
-  void generate_csharp_struct_result_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_csharp_struct_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_csharp_struct_tostring(std::ofstream& out, t_struct* tstruct);
-  void generate_csharp_struct_equals(std::ofstream& out, t_struct* tstruct);
-  void generate_csharp_struct_hashcode(std::ofstream& out, t_struct* tstruct);
-  void generate_csharp_union_reader(std::ofstream& out, t_struct* tunion);
+  void generate_csharp_union_definition(std::ostream& out, t_struct* tunion);
+  void generate_csharp_union_class(std::ostream& out, t_struct* tunion, t_field* tfield);
+  void generate_csharp_wcffault(std::ostream& out, t_struct* tstruct);
+  void generate_csharp_struct_reader(std::ostream& out, t_struct* tstruct);
+  void generate_csharp_struct_result_writer(std::ostream& out, t_struct* tstruct);
+  void generate_csharp_struct_writer(std::ostream& out, t_struct* tstruct);
+  void generate_csharp_struct_tostring(std::ostream& out, t_struct* tstruct);
+  void generate_csharp_struct_equals(std::ostream& out, t_struct* tstruct);
+  void generate_csharp_struct_hashcode(std::ostream& out, t_struct* tstruct);
+  void generate_csharp_union_reader(std::ostream& out, t_struct* tunion);
 
   void generate_function_helpers(t_function* tfunction);
   void generate_service_interface(t_service* tservice);
@@ -156,36 +156,36 @@ class t_csharp_generator : public t_oop_generator {
   void generate_process_function(t_service* tservice, t_function* function);
   void generate_process_function_async(t_service* tservice, t_function* function);
 
-  void generate_deserialize_field(std::ofstream& out,
+  void generate_deserialize_field(std::ostream& out,
                                   t_field* tfield,
                                   std::string prefix = "",
                                   bool is_propertyless = false);
-  void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
-  void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
-  void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
-  void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
-  void generate_deserialize_list_element(std::ofstream& out, t_list* list, std::string prefix = "");
-  void generate_serialize_field(std::ofstream& out,
+  void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
+  void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
+  void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
+  void generate_deserialize_list_element(std::ostream& out, t_list* list, std::string prefix = "");
+  void generate_serialize_field(std::ostream& out,
                                 t_field* tfield,
                                 std::string prefix = "",
                                 bool is_element = false,
                                 bool is_propertyless = false);
-  void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
-  void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
-  void generate_serialize_map_element(std::ofstream& out,
+  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
+  void generate_serialize_map_element(std::ostream& out,
                                       t_map* tmap,
                                       std::string iter,
                                       std::string map);
-  void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
-  void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
+  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
+  void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
 
-  void generate_csharp_doc(std::ofstream& out, t_field* field);
-  void generate_csharp_doc(std::ofstream& out, t_doc* tdoc);
-  void generate_csharp_doc(std::ofstream& out, t_function* tdoc);
-  void generate_csharp_docstring_comment(std::ofstream& out, string contents);
+  void generate_csharp_doc(std::ostream& out, t_field* field);
+  void generate_csharp_doc(std::ostream& out, t_doc* tdoc);
+  void generate_csharp_doc(std::ostream& out, t_function* tdoc);
+  void generate_csharp_docstring_comment(std::ostream& out, string contents);
 
-  void start_csharp_namespace(std::ofstream& out);
-  void end_csharp_namespace(std::ofstream& out);
+  void start_csharp_namespace(std::ostream& out);
+  void end_csharp_namespace(std::ostream& out);
 
   std::string csharp_type_usings();
   std::string csharp_thrift_usings();
@@ -224,7 +224,7 @@ class t_csharp_generator : public t_oop_generator {
 
 private:
   std::string namespace_name_;
-  std::ofstream f_service_;
+  ofstream_with_content_based_conditional_update f_service_;
   std::string namespace_dir_;
   bool async_;
   bool nullable_;
@@ -403,14 +403,14 @@ void t_csharp_generator::init_keywords() {
   csharp_keywords["yield"] = 1;
 }
 
-void t_csharp_generator::start_csharp_namespace(ofstream& out) {
+void t_csharp_generator::start_csharp_namespace(ostream& out) {
   if (!namespace_name_.empty()) {
     out << "namespace " << namespace_name_ << "\n";
     scope_up(out);
   }
 }
 
-void t_csharp_generator::end_csharp_namespace(ofstream& out) {
+void t_csharp_generator::end_csharp_namespace(ostream& out) {
   if (!namespace_name_.empty()) {
     scope_down(out);
   }
@@ -438,7 +438,7 @@ void t_csharp_generator::generate_typedef(t_typedef* ttypedef) {
 
 void t_csharp_generator::generate_enum(t_enum* tenum) {
   string f_enum_name = namespace_dir_ + "/" + (tenum->get_name()) + ".cs";
-  ofstream f_enum;
+  ofstream_with_content_based_conditional_update f_enum;
   f_enum.open(f_enum_name.c_str());
 
   f_enum << autogen_comment() << endl;
@@ -471,7 +471,7 @@ void t_csharp_generator::generate_consts(std::vector<t_const*> consts) {
     return;
   }
   string f_consts_name = namespace_dir_ + '/' + program_name_ + ".Constants.cs";
-  ofstream f_consts;
+  ofstream_with_content_based_conditional_update f_consts;
   f_consts.open(f_consts_name.c_str());
 
   f_consts << autogen_comment() << csharp_type_usings() << endl;
@@ -504,7 +504,7 @@ void t_csharp_generator::generate_consts(std::vector<t_const*> consts) {
   f_consts.close();
 }
 
-void t_csharp_generator::print_const_def_value(std::ofstream& out,
+void t_csharp_generator::print_const_def_value(std::ostream& out,
                                                string name,
                                                t_type* type,
                                                t_const_value* value) {
@@ -557,7 +557,7 @@ void t_csharp_generator::print_const_def_value(std::ofstream& out,
   }
 }
 
-void t_csharp_generator::print_const_constructor(std::ofstream& out, std::vector<t_const*> consts) {
+void t_csharp_generator::print_const_constructor(std::ostream& out, std::vector<t_const*> consts) {
   indent(out) << "static " << make_valid_csharp_identifier(program_name_).c_str() << "Constants()"
               << endl;
   scope_up(out);
@@ -574,7 +574,7 @@ void t_csharp_generator::print_const_constructor(std::ofstream& out, std::vector
 
 // it seems like all that methods that call this are using in_static to be the opposite of what it
 // would imply
-bool t_csharp_generator::print_const_value(std::ofstream& out,
+bool t_csharp_generator::print_const_value(std::ostream& out,
                                            string name,
                                            t_type* type,
                                            t_const_value* value,
@@ -614,7 +614,7 @@ bool t_csharp_generator::print_const_value(std::ofstream& out,
   return need_static_construction;
 }
 
-std::string t_csharp_generator::render_const_value(ofstream& out,
+std::string t_csharp_generator::render_const_value(ostream& out,
                                                    string name,
                                                    t_type* type,
                                                    t_const_value* value) {
@@ -671,7 +671,7 @@ void t_csharp_generator::generate_xception(t_struct* txception) {
 
 void t_csharp_generator::generate_csharp_struct(t_struct* tstruct, bool is_exception) {
   string f_struct_name = namespace_dir_ + "/" + (tstruct->get_name()) + ".cs";
-  ofstream f_struct;
+  ofstream_with_content_based_conditional_update f_struct;
 
   f_struct.open(f_struct_name.c_str());
 
@@ -682,7 +682,7 @@ void t_csharp_generator::generate_csharp_struct(t_struct* tstruct, bool is_excep
   f_struct.close();
 }
 
-void t_csharp_generator::generate_csharp_struct_definition(ofstream& out,
+void t_csharp_generator::generate_csharp_struct_definition(ostream& out,
                                                            t_struct* tstruct,
                                                            bool is_exception,
                                                            bool in_class,
@@ -885,7 +885,7 @@ void t_csharp_generator::generate_csharp_struct_definition(ofstream& out,
   }
 }
 
-void t_csharp_generator::generate_csharp_wcffault(ofstream& out, t_struct* tstruct) {
+void t_csharp_generator::generate_csharp_wcffault(ostream& out, t_struct* tstruct) {
   out << endl;
   indent(out) << "#if !SILVERLIGHT" << endl;
   indent(out) << "[Serializable]" << endl;
@@ -915,7 +915,7 @@ void t_csharp_generator::generate_csharp_wcffault(ofstream& out, t_struct* tstru
   out << endl;
 }
 
-void t_csharp_generator::generate_csharp_struct_reader(ofstream& out, t_struct* tstruct) {
+void t_csharp_generator::generate_csharp_struct_reader(ostream& out, t_struct* tstruct) {
   indent(out) << "public void Read (TProtocol iprot)" << endl;
   scope_up(out);
 
@@ -1005,7 +1005,7 @@ void t_csharp_generator::generate_csharp_struct_reader(ofstream& out, t_struct*
   indent(out) << "}" << endl << endl;
 }
 
-void t_csharp_generator::generate_csharp_struct_writer(ofstream& out, t_struct* tstruct) {
+void t_csharp_generator::generate_csharp_struct_writer(ostream& out, t_struct* tstruct) {
   out << indent() << "public void Write(TProtocol oprot) {" << endl;
   indent_up();
 
@@ -1084,7 +1084,7 @@ void t_csharp_generator::generate_csharp_struct_writer(ofstream& out, t_struct*
   indent(out) << "}" << endl << endl;
 }
 
-void t_csharp_generator::generate_csharp_struct_result_writer(ofstream& out, t_struct* tstruct) {
+void t_csharp_generator::generate_csharp_struct_result_writer(ostream& out, t_struct* tstruct) {
   indent(out) << "public void Write(TProtocol oprot) {" << endl;
   indent_up();
 
@@ -1156,7 +1156,7 @@ void t_csharp_generator::generate_csharp_struct_result_writer(ofstream& out, t_s
   indent(out) << "}" << endl << endl;
 }
 
-void t_csharp_generator::generate_csharp_struct_tostring(ofstream& out, t_struct* tstruct) {
+void t_csharp_generator::generate_csharp_struct_tostring(ostream& out, t_struct* tstruct) {
   indent(out) << "public override string ToString() {" << endl;
   indent_up();
 
@@ -1230,7 +1230,7 @@ void t_csharp_generator::generate_csharp_struct_tostring(ofstream& out, t_struct
 
 void t_csharp_generator::generate_csharp_union(t_struct* tunion) {
   string f_union_name = namespace_dir_ + "/" + (tunion->get_name()) + ".cs";
-  ofstream f_union;
+  ofstream_with_content_based_conditional_update f_union;
 
   f_union.open(f_union_name.c_str());
 
@@ -1241,7 +1241,7 @@ void t_csharp_generator::generate_csharp_union(t_struct* tunion) {
   f_union.close();
 }
 
-void t_csharp_generator::generate_csharp_union_definition(std::ofstream& out, t_struct* tunion) {
+void t_csharp_generator::generate_csharp_union_definition(std::ostream& out, t_struct* tunion) {
   // Let's define the class first
   start_csharp_namespace(out);
 
@@ -1292,7 +1292,7 @@ void t_csharp_generator::generate_csharp_union_definition(std::ofstream& out, t_
   end_csharp_namespace(out);
 }
 
-void t_csharp_generator::generate_csharp_union_class(std::ofstream& out,
+void t_csharp_generator::generate_csharp_union_class(std::ostream& out,
                                                      t_struct* tunion,
                                                      t_field* tfield) {
   indent(out) << "public class " << tfield->get_name() << " : " << tunion->get_name() << " {"
@@ -1341,7 +1341,7 @@ void t_csharp_generator::generate_csharp_union_class(std::ofstream& out,
   indent(out) << "}" << endl << endl;
 }
 
-void t_csharp_generator::generate_csharp_struct_equals(ofstream& out, t_struct* tstruct) {
+void t_csharp_generator::generate_csharp_struct_equals(ostream& out, t_struct* tstruct) {
   indent(out) << "public override bool Equals(object that) {" << endl;
   indent_up();
 
@@ -1390,7 +1390,7 @@ void t_csharp_generator::generate_csharp_struct_equals(ofstream& out, t_struct*
   indent(out) << "}" << endl << endl;
 }
 
-void t_csharp_generator::generate_csharp_struct_hashcode(ofstream& out, t_struct* tstruct) {
+void t_csharp_generator::generate_csharp_struct_hashcode(ostream& out, t_struct* tstruct) {
   indent(out) << "public override int GetHashCode() {" << endl;
   indent_up();
 
@@ -2378,7 +2378,7 @@ void t_csharp_generator::generate_process_function_async(t_service* tservice, t_
   f_service_ << endl;
 }
 
-void t_csharp_generator::generate_csharp_union_reader(std::ofstream& out, t_struct* tunion) {
+void t_csharp_generator::generate_csharp_union_reader(std::ostream& out, t_struct* tunion) {
   // Thanks to THRIFT-1768, we don't need to check for required fields in the union
   const vector<t_field*>& fields = tunion->get_members();
   vector<t_field*>::const_iterator f_iter;
@@ -2452,7 +2452,7 @@ void t_csharp_generator::generate_csharp_union_reader(std::ofstream& out, t_stru
   indent(out) << "}" << endl << endl;
 }
 
-void t_csharp_generator::generate_deserialize_field(ofstream& out,
+void t_csharp_generator::generate_deserialize_field(ostream& out,
                                                     t_field* tfield,
                                                     string prefix,
                                                     bool is_propertyless) {
@@ -2525,7 +2525,7 @@ void t_csharp_generator::generate_deserialize_field(ofstream& out,
   }
 }
 
-void t_csharp_generator::generate_deserialize_struct(ofstream& out,
+void t_csharp_generator::generate_deserialize_struct(ostream& out,
                                                      t_struct* tstruct,
                                                      string prefix) {
   if (union_ && tstruct->is_union()) {
@@ -2536,7 +2536,7 @@ void t_csharp_generator::generate_deserialize_struct(ofstream& out,
   }
 }
 
-void t_csharp_generator::generate_deserialize_container(ofstream& out,
+void t_csharp_generator::generate_deserialize_container(ostream& out,
                                                         t_type* ttype,
                                                         string prefix) {
   scope_up(out);
@@ -2587,7 +2587,7 @@ void t_csharp_generator::generate_deserialize_container(ofstream& out,
   scope_down(out);
 }
 
-void t_csharp_generator::generate_deserialize_map_element(ofstream& out,
+void t_csharp_generator::generate_deserialize_map_element(ostream& out,
                                                           t_map* tmap,
                                                           string prefix) {
   string key = tmp("_key");
@@ -2605,7 +2605,7 @@ void t_csharp_generator::generate_deserialize_map_element(ofstream& out,
   indent(out) << prefix << "[" << key << "] = " << val << ";" << endl;
 }
 
-void t_csharp_generator::generate_deserialize_set_element(ofstream& out,
+void t_csharp_generator::generate_deserialize_set_element(ostream& out,
                                                           t_set* tset,
                                                           string prefix) {
   string elem = tmp("_elem");
@@ -2618,7 +2618,7 @@ void t_csharp_generator::generate_deserialize_set_element(ofstream& out,
   indent(out) << prefix << ".Add(" << elem << ");" << endl;
 }
 
-void t_csharp_generator::generate_deserialize_list_element(ofstream& out,
+void t_csharp_generator::generate_deserialize_list_element(ostream& out,
                                                            t_list* tlist,
                                                            string prefix) {
   string elem = tmp("_elem");
@@ -2631,7 +2631,7 @@ void t_csharp_generator::generate_deserialize_list_element(ofstream& out,
   indent(out) << prefix << ".Add(" << elem << ");" << endl;
 }
 
-void t_csharp_generator::generate_serialize_field(ofstream& out,
+void t_csharp_generator::generate_serialize_field(ostream& out,
                                                   t_field* tfield,
                                                   string prefix,
                                                   bool is_element,
@@ -2704,14 +2704,14 @@ void t_csharp_generator::generate_serialize_field(ofstream& out,
   }
 }
 
-void t_csharp_generator::generate_serialize_struct(ofstream& out,
+void t_csharp_generator::generate_serialize_struct(ostream& out,
                                                    t_struct* tstruct,
                                                    string prefix) {
   (void)tstruct;
   out << indent() << prefix << ".Write(oprot);" << endl;
 }
 
-void t_csharp_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_csharp_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
   scope_up(out);
 
   if (ttype->is_map()) {
@@ -2763,7 +2763,7 @@ void t_csharp_generator::generate_serialize_container(ofstream& out, t_type* tty
   scope_down(out);
 }
 
-void t_csharp_generator::generate_serialize_map_element(ofstream& out,
+void t_csharp_generator::generate_serialize_map_element(ostream& out,
                                                         t_map* tmap,
                                                         string iter,
                                                         string map) {
@@ -2773,25 +2773,25 @@ void t_csharp_generator::generate_serialize_map_element(ofstream& out,
   generate_serialize_field(out, &vfield, "", true);
 }
 
-void t_csharp_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
+void t_csharp_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
   t_field efield(tset->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "", true);
 }
 
-void t_csharp_generator::generate_serialize_list_element(ofstream& out,
+void t_csharp_generator::generate_serialize_list_element(ostream& out,
                                                          t_list* tlist,
                                                          string iter) {
   t_field efield(tlist->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "", true);
 }
 
-void t_csharp_generator::generate_property(ofstream& out,
+void t_csharp_generator::generate_property(ostream& out,
                                            t_field* tfield,
                                            bool isPublic,
                                            bool generateIsset) {
   generate_csharp_property(out, tfield, isPublic, generateIsset, "_");
 }
-void t_csharp_generator::generate_csharp_property(ofstream& out,
+void t_csharp_generator::generate_csharp_property(ostream& out,
                                                   t_field* tfield,
                                                   bool isPublic,
                                                   bool generateIsset,
@@ -3040,7 +3040,7 @@ string t_csharp_generator::declare_field(t_field* tfield, bool init, std::string
       ttype = ((t_typedef*)ttype)->get_type();
     }
     if (ttype->is_base_type() && field_has_default(tfield)) {
-      ofstream dummy;
+      std::ofstream dummy;
       result += " = " + render_const_value(dummy, tfield->get_name(), ttype, tfield->get_value());
     } else if (ttype->is_base_type()) {
       t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base();
@@ -3158,11 +3158,11 @@ string t_csharp_generator::type_to_enum(t_type* type) {
   throw "INVALID TYPE IN type_to_enum: " + type->get_name();
 }
 
-void t_csharp_generator::generate_csharp_docstring_comment(ofstream& out, string contents) {
+void t_csharp_generator::generate_csharp_docstring_comment(ostream& out, string contents) {
   generate_docstring_comment(out, "/// <summary>\n", "/// ", contents, "/// </summary>\n");
 }
 
-void t_csharp_generator::generate_csharp_doc(ofstream& out, t_field* field) {
+void t_csharp_generator::generate_csharp_doc(ostream& out, t_field* field) {
   if (field->get_type()->is_enum()) {
     string combined_message = field->get_doc() + "\n<seealso cref=\""
                               + get_enum_class_name(field->get_type()) + "\"/>";
@@ -3172,13 +3172,13 @@ void t_csharp_generator::generate_csharp_doc(ofstream& out, t_field* field) {
   }
 }
 
-void t_csharp_generator::generate_csharp_doc(ofstream& out, t_doc* tdoc) {
+void t_csharp_generator::generate_csharp_doc(ostream& out, t_doc* tdoc) {
   if (tdoc->has_doc()) {
     generate_csharp_docstring_comment(out, tdoc->get_doc());
   }
 }
 
-void t_csharp_generator::generate_csharp_doc(ofstream& out, t_function* tfunction) {
+void t_csharp_generator::generate_csharp_doc(ostream& out, t_function* tfunction) {
   if (tfunction->has_doc()) {
     stringstream ps;
     const vector<t_field*>& fields = tfunction->get_arglist()->get_members();
diff --git a/compiler/cpp/src/thrift/generate/t_d_generator.cc b/compiler/cpp/src/thrift/generate/t_d_generator.cc
index bbef639aea..df56cfc03d 100644
--- a/compiler/cpp/src/thrift/generate/t_d_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_d_generator.cc
@@ -118,7 +118,7 @@ class t_d_generator : public t_oop_generator {
   virtual void generate_consts(std::vector<t_const*> consts) {
     if (!consts.empty()) {
       string f_consts_name = package_dir_ + program_name_ + "_constants.d";
-      ofstream f_consts;
+      ofstream_with_content_based_conditional_update f_consts;
       f_consts.open(f_consts_name.c_str());
 
       f_consts << autogen_comment() << "module " << render_package(*program_) << program_name_
@@ -201,7 +201,7 @@ class t_d_generator : public t_oop_generator {
 
     // Service implementation file includes
     string f_servicename = package_dir_ + svc_name + ".d";
-    std::ofstream f_service;
+    ofstream_with_content_based_conditional_update f_service;
     f_service.open(f_servicename.c_str());
     f_service << autogen_comment() << "module " << render_package(*program_) << svc_name << ";"
               << endl << endl;
@@ -339,13 +339,13 @@ class t_d_generator : public t_oop_generator {
 
     // Server skeleton generation.
     string f_skeletonname = package_dir_ + svc_name + "_server.skeleton.d";
-    std::ofstream f_skeleton;
+    ofstream_with_content_based_conditional_update f_skeleton;
     f_skeleton.open(f_skeletonname.c_str());
     print_server_skeleton(f_skeleton, tservice);
     f_skeleton.close();
   }
 
-  void emit_doc(t_doc *doc, std::ofstream& out) {
+  void emit_doc(t_doc *doc, std::ostream& out) {
     if (!doc->has_doc()) {
       return;
     }
@@ -733,8 +733,8 @@ class t_d_generator : public t_oop_generator {
    * File streams, stored here to avoid passing them as parameters to every
    * function.
    */
-  ofstream f_types_;
-  ofstream f_header_;
+  ofstream_with_content_based_conditional_update f_types_;
+  ofstream_with_content_based_conditional_update f_header_;
 
   string package_dir_;
 };
diff --git a/compiler/cpp/src/thrift/generate/t_dart_generator.cc b/compiler/cpp/src/thrift/generate/t_dart_generator.cc
index c2d07e92ab..d190e1682a 100644
--- a/compiler/cpp/src/thrift/generate/t_dart_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_dart_generator.cc
@@ -31,7 +31,7 @@
 #include "thrift/generate/t_oop_generator.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -141,13 +141,13 @@ class t_dart_generator : public t_oop_generator {
   void generate_xception(t_struct* txception);
   void generate_service(t_service* tservice);
 
-  void print_const_value(std::ofstream& out,
+  void print_const_value(std::ostream& out,
                          std::string name,
                          t_type* type,
                          t_const_value* value,
                          bool in_static,
                          bool defval = false);
-  std::string render_const_value(ofstream& out,
+  std::string render_const_value(ostream& out,
                                  std::string name,
                                  t_type* type,
                                  t_const_value* value);
@@ -158,21 +158,21 @@ class t_dart_generator : public t_oop_generator {
 
   void generate_dart_struct(t_struct* tstruct, bool is_exception);
 
-  void generate_dart_struct_definition(std::ofstream& out,
+  void generate_dart_struct_definition(std::ostream& out,
                                        t_struct* tstruct,
                                        bool is_xception = false,
                                        bool is_result = false,
                                        string export_file_name = "");
-  void generate_dart_struct_reader(std::ofstream& out, t_struct* tstruct);
-  void generate_dart_validator(std::ofstream& out, t_struct* tstruct);
-  void generate_dart_struct_result_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_dart_struct_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_dart_struct_tostring(std::ofstream& out, t_struct* tstruct);
+  void generate_dart_struct_reader(std::ostream& out, t_struct* tstruct);
+  void generate_dart_validator(std::ostream& out, t_struct* tstruct);
+  void generate_dart_struct_result_writer(std::ostream& out, t_struct* tstruct);
+  void generate_dart_struct_writer(std::ostream& out, t_struct* tstruct);
+  void generate_dart_struct_tostring(std::ostream& out, t_struct* tstruct);
   std::string get_dart_type_string(t_type* type);
-  void generate_generic_field_getters(std::ofstream& out, t_struct* tstruct);
-  void generate_generic_field_setters(std::ofstream& out, t_struct* tstruct);
-  void generate_generic_isset_method(std::ofstream& out, t_struct* tstruct);
-  void generate_dart_bean_boilerplate(std::ofstream& out, t_struct* tstruct);
+  void generate_generic_field_getters(std::ostream& out, t_struct* tstruct);
+  void generate_generic_field_setters(std::ostream& out, t_struct* tstruct);
+  void generate_generic_isset_method(std::ostream& out, t_struct* tstruct);
+  void generate_dart_bean_boilerplate(std::ostream& out, t_struct* tstruct);
 
   void generate_function_helpers(t_function* tfunction);
   std::string init_value(t_field* tfield);
@@ -184,7 +184,7 @@ class t_dart_generator : public t_oop_generator {
   std::string get_constants_class_name(std::string name);
   std::string generate_isset_check(t_field* field);
   std::string generate_isset_check(std::string field);
-  void generate_isset_set(ofstream& out, t_field* field);
+  void generate_isset_set(ostream& out, t_field* field);
 
   void generate_service_interface(t_service* tservice);
   void generate_service_helpers(t_service* tservice);
@@ -196,38 +196,38 @@ class t_dart_generator : public t_oop_generator {
    * Serialization constructs
    */
 
-  void generate_deserialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
+  void generate_deserialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
 
-  void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
+  void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
 
-  void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
+  void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
 
-  void generate_deserialize_list_element(std::ofstream& out,
+  void generate_deserialize_list_element(std::ostream& out,
                                          t_list* tlist,
                                          std::string prefix = "");
 
-  void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
+  void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
 
-  void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_serialize_map_element(std::ofstream& out,
+  void generate_serialize_map_element(std::ostream& out,
                                       t_map* tmap,
                                       std::string iter,
                                       std::string map);
 
-  void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
+  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
 
-  void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
+  void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
 
-  void generate_dart_doc(std::ofstream& out, t_doc* tdoc);
+  void generate_dart_doc(std::ostream& out, t_doc* tdoc);
 
-  void generate_dart_doc(std::ofstream& out, t_function* tdoc);
+  void generate_dart_doc(std::ostream& out, t_function* tdoc);
 
   /**
    * Helper rendering functions
@@ -265,7 +265,7 @@ class t_dart_generator : public t_oop_generator {
   std::string constant_name(std::string name);
 
 private:
-  std::ofstream f_service_;
+  ofstream_with_content_based_conditional_update f_service_;
 
   std::string library_name_;
   std::string library_prefix_;
@@ -391,7 +391,7 @@ void t_dart_generator::generate_dart_library() {
     f_library_name = get_out_dir() + "/" + library_name_ + ".dart";
   }
 
-  ofstream f_library;
+  ofstream_with_content_based_conditional_update f_library;
   f_library.open(f_library_name.c_str());
 
   f_library << autogen_comment() << endl;
@@ -413,7 +413,7 @@ void t_dart_generator::export_class_to_library(string file_name, string class_na
 
 void t_dart_generator::generate_dart_pubspec() {
   string f_pubspec_name = base_dir_ + "/pubspec.yaml";
-  ofstream f_pubspec;
+  ofstream_with_content_based_conditional_update f_pubspec;
   f_pubspec.open(f_pubspec_name.c_str());
 
   indent(f_pubspec) << "name: " << library_name_ << endl;
@@ -478,7 +478,7 @@ void t_dart_generator::generate_enum(t_enum* tenum) {
   string file_name = get_file_name(tenum->get_name());
 
   string f_enum_name = src_dir_ + "/" + file_name + ".dart";
-  ofstream f_enum;
+  ofstream_with_content_based_conditional_update f_enum;
   f_enum.open(f_enum_name.c_str());
 
   // Comment and add library
@@ -540,7 +540,7 @@ void t_dart_generator::generate_consts(std::vector<t_const*> consts) {
   string file_name = get_file_name(class_name);
 
   string f_consts_name = src_dir_ + "/" + file_name + ".dart";
-  ofstream f_consts;
+  ofstream_with_content_based_conditional_update f_consts;
   f_consts.open(f_consts_name.c_str());
 
   // Print header
@@ -566,7 +566,7 @@ void t_dart_generator::generate_consts(std::vector<t_const*> consts) {
   f_consts.close();
 }
 
-void t_dart_generator::print_const_value(std::ofstream& out,
+void t_dart_generator::print_const_value(std::ostream& out,
                                         string name,
                                         t_type* type,
                                         t_const_value* value,
@@ -668,7 +668,7 @@ void t_dart_generator::print_const_value(std::ofstream& out,
   }
 }
 
-string t_dart_generator::render_const_value(ofstream& out,
+string t_dart_generator::render_const_value(ostream& out,
                                            string name,
                                            t_type* type,
                                            t_const_value* value) {
@@ -740,7 +740,7 @@ void t_dart_generator::generate_xception(t_struct* txception) {
 void t_dart_generator::generate_dart_struct(t_struct* tstruct, bool is_exception) {
   string file_name = get_file_name(tstruct->get_name());
   string f_struct_name = src_dir_ + "/" + file_name + ".dart";
-  ofstream f_struct;
+  ofstream_with_content_based_conditional_update f_struct;
   f_struct.open(f_struct_name.c_str());
 
   f_struct << autogen_comment() << dart_library(file_name) << endl;
@@ -764,7 +764,7 @@ void t_dart_generator::generate_dart_struct(t_struct* tstruct, bool is_exception
  * @param in_class     If inside a class, needs to be static class
  * @param is_result    If this is a result it needs a different writer
  */
-void t_dart_generator::generate_dart_struct_definition(ofstream& out,
+void t_dart_generator::generate_dart_struct_definition(ostream& out,
                                                        t_struct* tstruct,
                                                        bool is_exception,
                                                        bool is_result,
@@ -861,7 +861,7 @@ void t_dart_generator::generate_dart_struct_definition(ofstream& out,
  *
  * @param tstruct The struct definition
  */
-void t_dart_generator::generate_dart_struct_reader(ofstream& out, t_struct* tstruct) {
+void t_dart_generator::generate_dart_struct_reader(ostream& out, t_struct* tstruct) {
   indent(out) << "read(TProtocol iprot)";
   scope_up(out);
 
@@ -949,7 +949,7 @@ void t_dart_generator::generate_dart_struct_reader(ofstream& out, t_struct* tstr
 
 // generates dart method to perform various checks
 // (e.g. check that all required fields are set)
-void t_dart_generator::generate_dart_validator(ofstream& out, t_struct* tstruct) {
+void t_dart_generator::generate_dart_validator(ostream& out, t_struct* tstruct) {
   indent(out) << "validate()";
   scope_up(out);
 
@@ -1000,7 +1000,7 @@ void t_dart_generator::generate_dart_validator(ofstream& out, t_struct* tstruct)
  *
  * @param tstruct The struct definition
  */
-void t_dart_generator::generate_dart_struct_writer(ofstream& out, t_struct* tstruct) {
+void t_dart_generator::generate_dart_struct_writer(ostream& out, t_struct* tstruct) {
   out << indent() << "write(TProtocol oprot)";
   scope_up(out);
 
@@ -1056,7 +1056,7 @@ void t_dart_generator::generate_dart_struct_writer(ofstream& out, t_struct* tstr
  *
  * @param tstruct The struct definition
  */
-void t_dart_generator::generate_dart_struct_result_writer(ofstream& out, t_struct* tstruct) {
+void t_dart_generator::generate_dart_struct_result_writer(ostream& out, t_struct* tstruct) {
   indent(out) << "write(TProtocol oprot)";
   scope_up(out);
 
@@ -1097,7 +1097,7 @@ void t_dart_generator::generate_dart_struct_result_writer(ofstream& out, t_struc
   scope_down(out, endl2);
 }
 
-void t_dart_generator::generate_generic_field_getters(std::ofstream& out,
+void t_dart_generator::generate_generic_field_getters(std::ostream& out,
                                                       t_struct* tstruct) {
   // create the getter
   indent(out) << "getFieldValue(int fieldID)";
@@ -1127,7 +1127,7 @@ void t_dart_generator::generate_generic_field_getters(std::ofstream& out,
   scope_down(out, endl2);  // method
 }
 
-void t_dart_generator::generate_generic_field_setters(std::ofstream& out,
+void t_dart_generator::generate_generic_field_setters(std::ostream& out,
                                                       t_struct* tstruct) {
 
   // create the setter
@@ -1172,7 +1172,7 @@ void t_dart_generator::generate_generic_field_setters(std::ofstream& out,
 }
 
 // Creates a generic isSet method that takes the field number as argument
-void t_dart_generator::generate_generic_isset_method(std::ofstream& out, t_struct* tstruct) {
+void t_dart_generator::generate_generic_isset_method(std::ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
@@ -1208,7 +1208,7 @@ void t_dart_generator::generate_generic_isset_method(std::ofstream& out, t_struc
  *
  * @param tstruct The struct definition
  */
-void t_dart_generator::generate_dart_bean_boilerplate(ofstream& out,
+void t_dart_generator::generate_dart_bean_boilerplate(ostream& out,
                                                     t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
@@ -1257,7 +1257,7 @@ void t_dart_generator::generate_dart_bean_boilerplate(ofstream& out,
  *
  * @param tstruct The struct definition
  */
-void t_dart_generator::generate_dart_struct_tostring(ofstream& out,
+void t_dart_generator::generate_dart_struct_tostring(ostream& out,
                                                    t_struct* tstruct) {
   indent(out) << "String toString()";
   scope_up(out);
@@ -1784,7 +1784,7 @@ void t_dart_generator::generate_process_function(t_service* tservice, t_function
  * @param tfield The field
  * @param prefix The variable name or container for this field
  */
-void t_dart_generator::generate_deserialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_dart_generator::generate_deserialize_field(ostream& out, t_field* tfield, string prefix) {
   t_type* type = get_true_type(tfield->get_type());
   string field_name = get_member_name(tfield->get_name());
 
@@ -1850,7 +1850,7 @@ void t_dart_generator::generate_deserialize_field(ofstream& out, t_field* tfield
 /**
  * Generates an unserializer for a struct, invokes read()
  */
-void t_dart_generator::generate_deserialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_dart_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   indent(out) << prefix << " = new " << type_name(tstruct) << "();" << endl;
   indent(out) << prefix << ".read(iprot);" << endl;
 }
@@ -1858,7 +1858,7 @@ void t_dart_generator::generate_deserialize_struct(ofstream& out, t_struct* tstr
 /**
  * Deserializes a container by reading its size and then iterating
  */
-void t_dart_generator::generate_deserialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_dart_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) {
   indent(out);
   scope_up(out, "");
 
@@ -1915,7 +1915,7 @@ void t_dart_generator::generate_deserialize_container(ofstream& out, t_type* tty
 /**
  * Generates code to deserialize a map
  */
-void t_dart_generator::generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix) {
+void t_dart_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix) {
   string key = tmp("_key");
   string val = tmp("_val");
   t_field fkey(tmap->get_key_type(), key);
@@ -1933,7 +1933,7 @@ void t_dart_generator::generate_deserialize_map_element(ofstream& out, t_map* tm
 /**
  * Deserializes a set element
  */
-void t_dart_generator::generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix) {
+void t_dart_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) {
   string elem = tmp("_elem");
   t_field felem(tset->get_elem_type(), elem);
 
@@ -1947,7 +1947,7 @@ void t_dart_generator::generate_deserialize_set_element(ofstream& out, t_set* ts
 /**
  * Deserializes a list element
  */
-void t_dart_generator::generate_deserialize_list_element(ofstream& out,
+void t_dart_generator::generate_deserialize_list_element(ostream& out,
                                                         t_list* tlist,
                                                         string prefix) {
   string elem = tmp("_elem");
@@ -1966,7 +1966,7 @@ void t_dart_generator::generate_deserialize_list_element(ofstream& out,
  * @param tfield The field to serialize
  * @param prefix Name to prepend to field name
  */
-void t_dart_generator::generate_serialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_dart_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix) {
   t_type* type = get_true_type(tfield->get_type());
   string field_name = get_member_name(tfield->get_name());
 
@@ -2036,7 +2036,7 @@ void t_dart_generator::generate_serialize_field(ofstream& out, t_field* tfield,
  * @param tstruct The struct to serialize
  * @param prefix  String prefix to attach to all fields
  */
-void t_dart_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_dart_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   (void)tstruct;
   indent(out) << prefix << ".write(oprot);" << endl;
 }
@@ -2047,7 +2047,7 @@ void t_dart_generator::generate_serialize_struct(ofstream& out, t_struct* tstruc
  * @param ttype  The type of container
  * @param prefix String prefix for fields
  */
-void t_dart_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_dart_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
   indent(out);
   scope_up(out, "");
 
@@ -2098,7 +2098,7 @@ void t_dart_generator::generate_serialize_container(ofstream& out, t_type* ttype
 /**
  * Serializes the members of a map.
  */
-void t_dart_generator::generate_serialize_map_element(ofstream& out,
+void t_dart_generator::generate_serialize_map_element(ostream& out,
                                                      t_map* tmap,
                                                      string iter,
                                                      string map) {
@@ -2111,7 +2111,7 @@ void t_dart_generator::generate_serialize_map_element(ofstream& out,
 /**
  * Serializes the members of a set.
  */
-void t_dart_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
+void t_dart_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
   t_field efield(tset->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "");
 }
@@ -2119,7 +2119,7 @@ void t_dart_generator::generate_serialize_set_element(ofstream& out, t_set* tset
 /**
  * Serializes the members of a list.
  */
-void t_dart_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string iter) {
+void t_dart_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter) {
   t_field efield(tlist->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "");
 }
@@ -2194,7 +2194,7 @@ string t_dart_generator::declare_field(t_field* tfield, bool init) {
   if (init) {
     t_type* ttype = get_true_type(tfield->get_type());
     if (ttype->is_base_type() && tfield->get_value() != NULL) {
-      ofstream dummy;
+      std:: ofstream dummy;
       result += " = " + render_const_value(dummy, field_name, ttype, tfield->get_value());
     } else if (ttype->is_base_type()) {
       t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base();
@@ -2452,7 +2452,7 @@ string t_dart_generator::constant_name(string name) {
 /**
  * Emits a doc comment if the provided object has a doc in Thrift
  */
-void t_dart_generator::generate_dart_doc(ofstream& out, t_doc* tdoc) {
+void t_dart_generator::generate_dart_doc(ostream& out, t_doc* tdoc) {
   if (tdoc->has_doc()) {
     generate_docstring_comment(out, "", "/// ", tdoc->get_doc(), "");
   }
@@ -2461,7 +2461,7 @@ void t_dart_generator::generate_dart_doc(ofstream& out, t_doc* tdoc) {
 /**
  * Emits a doc comment if the provided function object has a doc in Thrift
  */
-void t_dart_generator::generate_dart_doc(ofstream& out, t_function* tfunction) {
+void t_dart_generator::generate_dart_doc(ostream& out, t_function* tfunction) {
   if (tfunction->has_doc()) {
     stringstream ss;
     ss << tfunction->get_doc();
@@ -2488,7 +2488,7 @@ std::string t_dart_generator::generate_isset_check(std::string field_name) {
   return "is" + get_cap_name("set") + get_cap_name(field_name) + "()";
 }
 
-void t_dart_generator::generate_isset_set(ofstream& out, t_field* field) {
+void t_dart_generator::generate_isset_set(ostream& out, t_field* field) {
   if (!type_can_be_null(field->get_type())) {
     string field_name = get_member_name(field->get_name());
     indent(out) << "this.__isset_" << field_name << " = true;" << endl;
diff --git a/compiler/cpp/src/thrift/generate/t_delphi_generator.cc b/compiler/cpp/src/thrift/generate/t_delphi_generator.cc
index 4db1cf7dad..c7ae544820 100644
--- a/compiler/cpp/src/thrift/generate/t_delphi_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_delphi_generator.cc
@@ -773,7 +773,7 @@ void t_delphi_generator::close_generator() {
   }
 
   std::string f_name = get_out_dir() + "/" + unitname + ".pas";
-  std::ofstream f_all;
+  ofstream_with_content_based_conditional_update f_all;
 
   f_all.open(f_name.c_str());
 
diff --git a/compiler/cpp/src/thrift/generate/t_erl_generator.cc b/compiler/cpp/src/thrift/generate/t_erl_generator.cc
index 768db139d3..587133f8cb 100644
--- a/compiler/cpp/src/thrift/generate/t_erl_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_erl_generator.cc
@@ -220,15 +220,15 @@ class t_erl_generator : public t_generator {
   std::ostringstream f_info_;
   std::ostringstream f_info_ext_;
 
-  std::ofstream f_types_file_;
-  std::ofstream f_types_hrl_file_;
+  ofstream_with_content_based_conditional_update f_types_file_;
+  ofstream_with_content_based_conditional_update f_types_hrl_file_;
 
-  std::ofstream f_consts_file_;
-  std::ofstream f_consts_hrl_file_;
+  ofstream_with_content_based_conditional_update f_consts_file_;
+  ofstream_with_content_based_conditional_update f_consts_hrl_file_;
 
   std::ostringstream f_service_;
-  std::ofstream f_service_file_;
-  std::ofstream f_service_hrl_;
+  ofstream_with_content_based_conditional_update f_service_file_;
+  ofstream_with_content_based_conditional_update f_service_hrl_;
 
   /**
    * Metadata containers
diff --git a/compiler/cpp/src/thrift/generate/t_generator.h b/compiler/cpp/src/thrift/generate/t_generator.h
index cbbfcb9fa1..b55b619cb1 100644
--- a/compiler/cpp/src/thrift/generate/t_generator.h
+++ b/compiler/cpp/src/thrift/generate/t_generator.h
@@ -21,6 +21,7 @@
 #define T_GENERATOR_H
 #define MSC_2015_VER 1900
 
+#include <cstring>
 #include <string>
 #include <iomanip>
 #include <iostream>
@@ -186,7 +187,6 @@ class t_generator {
     }
   }
 
-
   /**
    * Indentation print function
    */
@@ -227,6 +227,7 @@ class t_generator {
     }
     return in;
   }
+
   /**
    * Transforms a camel case string to an equivalent one separated by underscores
    * e.g. aMultiWord -> a_multi_word
@@ -245,6 +246,7 @@ class t_generator {
     }
     return in;
   }
+
   /**
     * Transforms a string with words separated by underscores to a camel case equivalent
     * e.g. a_multi_word -> aMultiWord
@@ -346,4 +348,65 @@ class t_generator {
   int tmp_;
 };
 
+template<typename _CharT, typename _Traits = std::char_traits<_CharT> >
+class template_ofstream_with_content_based_conditional_update : public std::ostringstream {
+public:
+  template_ofstream_with_content_based_conditional_update(): output_file_path(""), contents_written(false) {}
+  template_ofstream_with_content_based_conditional_update(std::string const& output_file_path_)
+  : output_file_path(output_file_path_), contents_written(false) {}
+
+  ~template_ofstream_with_content_based_conditional_update() {
+    if (!contents_written) {
+      close();
+    }
+  }
+
+  void open(std::string const& output_file_path_) {
+    output_file_path = output_file_path_;
+  }
+
+  void close() {
+    if (contents_written || output_file_path == "")
+      return;
+
+    if (!is_readable(output_file_path)) {
+      dump();
+      return;
+    }
+
+    std::ifstream old_file;
+    old_file.exceptions(old_file.exceptions() | std::ifstream::badbit | std::ifstream::failbit);
+    old_file.open(output_file_path.c_str(), std::ios::in);
+
+    if (old_file) {
+      std::string const old_file_contents(static_cast<std::ostringstream const&>(std::ostringstream() << old_file.rdbuf()).str());
+      old_file.close();
+
+      if (old_file_contents != str()) {
+        dump();
+      }
+    }
+    contents_written = true;
+  }
+
+protected:
+  void dump() {
+    std::ofstream out_file;
+    out_file.exceptions(out_file.exceptions() | std::ofstream::badbit | std::ofstream::failbit);
+    out_file.open(output_file_path.c_str(), std::ios::out);
+    out_file << str();
+    out_file.close();
+    contents_written = true;
+  }
+
+  static bool is_readable(std::string const& file_name) {
+    return static_cast<bool>(std::ifstream(file_name.c_str()));
+  }
+
+private:
+  std::string output_file_path;
+  bool contents_written;
+};
+typedef template_ofstream_with_content_based_conditional_update<char> ofstream_with_content_based_conditional_update;
+
 #endif
diff --git a/compiler/cpp/src/thrift/generate/t_go_generator.cc b/compiler/cpp/src/thrift/generate/t_go_generator.cc
index f3c7fee315..fab6545d86 100644
--- a/compiler/cpp/src/thrift/generate/t_go_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_go_generator.cc
@@ -42,7 +42,7 @@
 #include "thrift/generate/t_generator.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -126,27 +126,27 @@ class t_go_generator : public t_generator {
    */
 
   void generate_go_struct(t_struct* tstruct, bool is_exception);
-  void generate_go_struct_definition(std::ofstream& out,
+  void generate_go_struct_definition(std::ostream& out,
                                      t_struct* tstruct,
                                      bool is_xception = false,
                                      bool is_result = false,
                                      bool is_args = false);
-  void generate_go_struct_initializer(std::ofstream& out,
+  void generate_go_struct_initializer(std::ostream& out,
                                       t_struct* tstruct,
                                       bool is_args_or_result = false);
-  void generate_isset_helpers(std::ofstream& out,
+  void generate_isset_helpers(std::ostream& out,
                               t_struct* tstruct,
                               const string& tstruct_name,
                               bool is_result = false);
-  void generate_countsetfields_helper(std::ofstream& out,
+  void generate_countsetfields_helper(std::ostream& out,
                                       t_struct* tstruct,
                                       const string& tstruct_name,
                                       bool is_result = false);
-  void generate_go_struct_reader(std::ofstream& out,
+  void generate_go_struct_reader(std::ostream& out,
                                  t_struct* tstruct,
                                  const string& tstruct_name,
                                  bool is_result = false);
-  void generate_go_struct_writer(std::ofstream& out,
+  void generate_go_struct_writer(std::ostream& out,
                                  t_struct* tstruct,
                                  const string& tstruct_name,
                                  bool is_result = false,
@@ -171,7 +171,7 @@ class t_go_generator : public t_generator {
    * Serialization constructs
    */
 
-  void generate_deserialize_field(std::ofstream& out,
+  void generate_deserialize_field(std::ostream& out,
                                   t_field* tfield,
                                   bool declare,
                                   std::string prefix = "",
@@ -180,64 +180,64 @@ class t_go_generator : public t_generator {
                                   bool inkey = false,
                                   bool in_container = false);
 
-  void generate_deserialize_struct(std::ofstream& out,
+  void generate_deserialize_struct(std::ostream& out,
                                    t_struct* tstruct,
                                    bool is_pointer_field,
                                    bool declare,
                                    std::string prefix = "");
 
-  void generate_deserialize_container(std::ofstream& out,
+  void generate_deserialize_container(std::ostream& out,
                                       t_type* ttype,
                                       bool pointer_field,
                                       bool declare,
                                       std::string prefix = "");
 
-  void generate_deserialize_set_element(std::ofstream& out,
+  void generate_deserialize_set_element(std::ostream& out,
                                         t_set* tset,
                                         bool declare,
                                         std::string prefix = "");
 
-  void generate_deserialize_map_element(std::ofstream& out,
+  void generate_deserialize_map_element(std::ostream& out,
                                         t_map* tmap,
                                         bool declare,
                                         std::string prefix = "");
 
-  void generate_deserialize_list_element(std::ofstream& out,
+  void generate_deserialize_list_element(std::ostream& out,
                                          t_list* tlist,
                                          bool declare,
                                          std::string prefix = "");
 
-  void generate_serialize_field(std::ofstream& out,
+  void generate_serialize_field(std::ostream& out,
                                 t_field* tfield,
                                 std::string prefix = "",
                                 bool inkey = false);
 
-  void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_serialize_container(std::ofstream& out,
+  void generate_serialize_container(std::ostream& out,
                                     t_type* ttype,
                                     bool pointer_field,
                                     std::string prefix = "");
 
-  void generate_serialize_map_element(std::ofstream& out,
+  void generate_serialize_map_element(std::ostream& out,
                                       t_map* tmap,
                                       std::string kiter,
                                       std::string viter);
 
-  void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
+  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
 
-  void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
+  void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
 
-  void generate_go_docstring(std::ofstream& out, t_struct* tstruct);
+  void generate_go_docstring(std::ostream& out, t_struct* tstruct);
 
-  void generate_go_docstring(std::ofstream& out, t_function* tfunction);
+  void generate_go_docstring(std::ostream& out, t_function* tfunction);
 
-  void generate_go_docstring(std::ofstream& out,
+  void generate_go_docstring(std::ostream& out,
                              t_doc* tdoc,
                              t_struct* tstruct,
                              const char* subheader);
 
-  void generate_go_docstring(std::ofstream& out, t_doc* tdoc);
+  void generate_go_docstring(std::ostream& out, t_doc* tdoc);
 
   /**
    * Helper rendering functions
@@ -290,9 +290,9 @@ class t_go_generator : public t_generator {
    * File streams
    */
 
-  std::ofstream f_types_;
+  ofstream_with_content_based_conditional_update f_types_;
   std::string f_types_name_;
-  std::ofstream f_consts_;
+  ofstream_with_content_based_conditional_update f_consts_;
   std::string f_consts_name_;
   std::stringstream f_const_values_;
 
@@ -758,7 +758,7 @@ void t_go_generator::init_generator() {
 
   // Create file for the GoUnusedProtection__ variable
   string f_unused_prot_name_ = package_dir_ + "/" + "GoUnusedProtection__.go";
-  ofstream f_unused_prot_;
+  ofstream_with_content_based_conditional_update f_unused_prot_;
   f_unused_prot_.open(f_unused_prot_name_.c_str());
   f_unused_prot_ << go_autogen_comment() << go_package() << render_import_protection();
   f_unused_prot_.close();
@@ -1201,7 +1201,7 @@ void t_go_generator::get_publicized_name_and_def_value(t_field* tfield,
   *OUT_def_value = tfield->get_value();
 }
 
-void t_go_generator::generate_go_struct_initializer(ofstream& out,
+void t_go_generator::generate_go_struct_initializer(ostream& out,
                                                     t_struct* tstruct,
                                                     bool is_args_or_result) {
   out << publicize(type_name(tstruct), is_args_or_result) << "{";
@@ -1227,7 +1227,7 @@ void t_go_generator::generate_go_struct_initializer(ofstream& out,
  *
  * @param tstruct The struct definition
  */
-void t_go_generator::generate_go_struct_definition(ofstream& out,
+void t_go_generator::generate_go_struct_definition(ostream& out,
                                                    t_struct* tstruct,
                                                    bool is_exception,
                                                    bool is_result,
@@ -1384,7 +1384,7 @@ void t_go_generator::generate_go_struct_definition(ofstream& out,
 /**
  * Generates the IsSet helper methods for a struct
  */
-void t_go_generator::generate_isset_helpers(ofstream& out,
+void t_go_generator::generate_isset_helpers(ostream& out,
                                             t_struct* tstruct,
                                             const string& tstruct_name,
                                             bool is_result) {
@@ -1423,7 +1423,7 @@ void t_go_generator::generate_isset_helpers(ofstream& out,
 /**
  * Generates the CountSetFields helper method for a struct
  */
-void t_go_generator::generate_countsetfields_helper(ofstream& out,
+void t_go_generator::generate_countsetfields_helper(ostream& out,
                                                     t_struct* tstruct,
                                                     const string& tstruct_name,
                                                     bool is_result) {
@@ -1462,7 +1462,7 @@ void t_go_generator::generate_countsetfields_helper(ofstream& out,
 /**
  * Generates the read method for a struct
  */
-void t_go_generator::generate_go_struct_reader(ofstream& out,
+void t_go_generator::generate_go_struct_reader(ostream& out,
                                                t_struct* tstruct,
                                                const string& tstruct_name,
                                                bool is_result) {
@@ -1615,7 +1615,7 @@ void t_go_generator::generate_go_struct_reader(ofstream& out,
   }
 }
 
-void t_go_generator::generate_go_struct_writer(ofstream& out,
+void t_go_generator::generate_go_struct_writer(ostream& out,
                                                t_struct* tstruct,
                                                const string& tstruct_name,
                                                bool is_result,
@@ -2048,7 +2048,7 @@ void t_go_generator::generate_service_remote(t_service* tservice) {
   vector<t_function*>::iterator f_iter;
   string f_remote_name = f_remote_dir + "/"
                          + underscore(service_name_) + "-remote.go";
-  ofstream f_remote;
+  ofstream_with_content_based_conditional_update f_remote;
   f_remote.open(f_remote_name.c_str());
   string service_module = get_real_go_module(program_);
   string::size_type loc;
@@ -2777,7 +2777,7 @@ void t_go_generator::generate_process_function(t_service* tservice, t_function*
 /**
  * Deserializes a field of any type.
  */
-void t_go_generator::generate_deserialize_field(ofstream& out,
+void t_go_generator::generate_deserialize_field(ostream& out,
                                                 t_field* tfield,
                                                 bool declare,
                                                 string prefix,
@@ -2893,7 +2893,7 @@ void t_go_generator::generate_deserialize_field(ofstream& out,
 /**
  * Generates an unserializer for a struct, calling read()
  */
-void t_go_generator::generate_deserialize_struct(ofstream& out,
+void t_go_generator::generate_deserialize_struct(ostream& out,
                                                  t_struct* tstruct,
                                                  bool pointer_field,
                                                  bool declare,
@@ -2912,7 +2912,7 @@ void t_go_generator::generate_deserialize_struct(ofstream& out,
  * Serialize a container by writing out the header followed by
  * data and then a footer.
  */
-void t_go_generator::generate_deserialize_container(ofstream& out,
+void t_go_generator::generate_deserialize_container(ostream& out,
                                                     t_type* orig_type,
                                                     bool pointer_field,
                                                     bool declare,
@@ -2988,7 +2988,7 @@ void t_go_generator::generate_deserialize_container(ofstream& out,
 /**
  * Generates code to deserialize a map
  */
-void t_go_generator::generate_deserialize_map_element(ofstream& out,
+void t_go_generator::generate_deserialize_map_element(ostream& out,
                                                       t_map* tmap,
                                                       bool declare,
                                                       string prefix) {
@@ -3007,7 +3007,7 @@ void t_go_generator::generate_deserialize_map_element(ofstream& out,
 /**
  * Write a set element
  */
-void t_go_generator::generate_deserialize_set_element(ofstream& out,
+void t_go_generator::generate_deserialize_set_element(ostream& out,
                                                       t_set* tset,
                                                       bool declare,
                                                       string prefix) {
@@ -3022,7 +3022,7 @@ void t_go_generator::generate_deserialize_set_element(ofstream& out,
 /**
  * Write a list element
  */
-void t_go_generator::generate_deserialize_list_element(ofstream& out,
+void t_go_generator::generate_deserialize_list_element(ostream& out,
                                                        t_list* tlist,
                                                        bool declare,
                                                        string prefix) {
@@ -3040,7 +3040,7 @@ void t_go_generator::generate_deserialize_list_element(ofstream& out,
  * @param tfield The field to serialize
  * @param prefix Name to prepend to field name
  */
-void t_go_generator::generate_serialize_field(ofstream& out,
+void t_go_generator::generate_serialize_field(ostream& out,
                                               t_field* tfield,
                                               string prefix,
                                               bool inkey) {
@@ -3127,7 +3127,7 @@ void t_go_generator::generate_serialize_field(ofstream& out,
  * @param tstruct The struct to serialize
  * @param prefix  String prefix to attach to all fields
  */
-void t_go_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_go_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   (void)tstruct;
   out << indent() << "if err := " << prefix << "." << write_method_name_ << "(oprot); err != nil {" << endl;
   out << indent() << "  return thrift.PrependError(fmt.Sprintf(\"%T error writing struct: \", "
@@ -3135,7 +3135,7 @@ void t_go_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct,
   out << indent() << "}" << endl;
 }
 
-void t_go_generator::generate_serialize_container(ofstream& out,
+void t_go_generator::generate_serialize_container(ostream& out,
                                                   t_type* ttype,
                                                   bool pointer_field,
                                                   string prefix) {
@@ -3216,7 +3216,7 @@ void t_go_generator::generate_serialize_container(ofstream& out,
  * Serializes the members of a map.
  *
  */
-void t_go_generator::generate_serialize_map_element(ofstream& out,
+void t_go_generator::generate_serialize_map_element(ostream& out,
                                                     t_map* tmap,
                                                     string kiter,
                                                     string viter) {
@@ -3231,7 +3231,7 @@ void t_go_generator::generate_serialize_map_element(ofstream& out,
 /**
  * Serializes the members of a set.
  */
-void t_go_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string prefix) {
+void t_go_generator::generate_serialize_set_element(ostream& out, t_set* tset, string prefix) {
   t_field efield(tset->get_elem_type(), "");
   efield.set_req(t_field::T_OPT_IN_REQ_OUT);
   generate_serialize_field(out, &efield, prefix);
@@ -3240,7 +3240,7 @@ void t_go_generator::generate_serialize_set_element(ofstream& out, t_set* tset,
 /**
  * Serializes the members of a list.
  */
-void t_go_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string prefix) {
+void t_go_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string prefix) {
   t_field efield(tlist->get_elem_type(), "");
   efield.set_req(t_field::T_OPT_IN_REQ_OUT);
   generate_serialize_field(out, &efield, prefix);
@@ -3249,21 +3249,21 @@ void t_go_generator::generate_serialize_list_element(ofstream& out, t_list* tlis
 /**
  * Generates the docstring for a given struct.
  */
-void t_go_generator::generate_go_docstring(ofstream& out, t_struct* tstruct) {
+void t_go_generator::generate_go_docstring(ostream& out, t_struct* tstruct) {
   generate_go_docstring(out, tstruct, tstruct, "Attributes");
 }
 
 /**
  * Generates the docstring for a given function.
  */
-void t_go_generator::generate_go_docstring(ofstream& out, t_function* tfunction) {
+void t_go_generator::generate_go_docstring(ostream& out, t_function* tfunction) {
   generate_go_docstring(out, tfunction, tfunction->get_arglist(), "Parameters");
 }
 
 /**
  * Generates the docstring for a struct or function.
  */
-void t_go_generator::generate_go_docstring(ofstream& out,
+void t_go_generator::generate_go_docstring(ostream& out,
                                            t_doc* tdoc,
                                            t_struct* tstruct,
                                            const char* subheader) {
@@ -3306,7 +3306,7 @@ void t_go_generator::generate_go_docstring(ofstream& out,
 /**
  * Generates the docstring for a generic object.
  */
-void t_go_generator::generate_go_docstring(ofstream& out, t_doc* tdoc) {
+void t_go_generator::generate_go_docstring(ostream& out, t_doc* tdoc) {
   if (tdoc->has_doc()) {
     generate_docstring_comment(out, "", "//", tdoc->get_doc(), "");
   }
diff --git a/compiler/cpp/src/thrift/generate/t_gv_generator.cc b/compiler/cpp/src/thrift/generate/t_gv_generator.cc
index c2f8b5a9cb..7f8301a184 100644
--- a/compiler/cpp/src/thrift/generate/t_gv_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_gv_generator.cc
@@ -87,7 +87,7 @@ class t_gv_generator : public t_generator {
   void print_const_value(t_type* type, t_const_value* tvalue);
 
 private:
-  std::ofstream f_out_;
+  ofstream_with_content_based_conditional_update f_out_;
   std::list<string> edges;
   bool exception_arrows;
 };
diff --git a/compiler/cpp/src/thrift/generate/t_haxe_generator.cc b/compiler/cpp/src/thrift/generate/t_haxe_generator.cc
index ce3816d3a3..3b88c4da79 100644
--- a/compiler/cpp/src/thrift/generate/t_haxe_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_haxe_generator.cc
@@ -31,7 +31,7 @@
 #include "thrift/generate/t_oop_generator.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -89,13 +89,13 @@ class t_haxe_generator : public t_oop_generator {
   void generate_xception(t_struct* txception);
   void generate_service(t_service* tservice);
 
-  void print_const_value(std::ofstream& out,
+  void print_const_value(std::ostream& out,
                          std::string name,
                          t_type* type,
                          t_const_value* value,
                          bool in_static,
                          bool defval = false);
-  std::string render_const_value(ofstream& out,
+  std::string render_const_value(ostream& out,
                                  std::string name,
                                  t_type* type,
                                  t_const_value* value);
@@ -106,18 +106,18 @@ class t_haxe_generator : public t_oop_generator {
 
   void generate_haxe_struct(t_struct* tstruct, bool is_exception, bool is_result = false);
 
-  void generate_haxe_struct_definition(std::ofstream& out,
+  void generate_haxe_struct_definition(std::ostream& out,
                                        t_struct* tstruct,
                                        bool is_xception = false,
                                        bool is_result = false);
   // removed -- equality,compare_to
-  void generate_haxe_struct_reader(std::ofstream& out, t_struct* tstruct);
-  void generate_haxe_validator(std::ofstream& out, t_struct* tstruct);
-  void generate_haxe_struct_result_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_haxe_struct_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_haxe_struct_tostring(std::ofstream& out, t_struct* tstruct);
-  void generate_haxe_meta_data_map(std::ofstream& out, t_struct* tstruct);
-  void generate_field_value_meta_data(std::ofstream& out, t_type* type);
+  void generate_haxe_struct_reader(std::ostream& out, t_struct* tstruct);
+  void generate_haxe_validator(std::ostream& out, t_struct* tstruct);
+  void generate_haxe_struct_result_writer(std::ostream& out, t_struct* tstruct);
+  void generate_haxe_struct_writer(std::ostream& out, t_struct* tstruct);
+  void generate_haxe_struct_tostring(std::ostream& out, t_struct* tstruct);
+  void generate_haxe_meta_data_map(std::ostream& out, t_struct* tstruct);
+  void generate_field_value_meta_data(std::ostream& out, t_type* type);
   std::string get_haxe_type_string(t_type* type);
   void generate_reflection_setters(std::ostringstream& out,
                                    t_type* type,
@@ -127,15 +127,15 @@ class t_haxe_generator : public t_oop_generator {
                                    t_type* type,
                                    std::string field_name,
                                    std::string cap_name);
-  void generate_generic_field_getters_setters(std::ofstream& out, t_struct* tstruct);
-  void generate_generic_isset_method(std::ofstream& out, t_struct* tstruct);
-  void generate_property_getters_setters(std::ofstream& out, t_struct* tstruct);
+  void generate_generic_field_getters_setters(std::ostream& out, t_struct* tstruct);
+  void generate_generic_isset_method(std::ostream& out, t_struct* tstruct);
+  void generate_property_getters_setters(std::ostream& out, t_struct* tstruct);
 
   void generate_function_helpers(t_function* tfunction);
   std::string get_cap_name(std::string name);
   std::string generate_isset_check(t_field* field);
   std::string generate_isset_check(std::string field);
-  void generate_isset_set(ofstream& out, t_field* field);
+  void generate_isset_set(ostream& out, t_field* field);
   // removed std::string isset_field_id(t_field* field);
 
   void generate_service_interface(t_service* tservice);
@@ -149,30 +149,30 @@ class t_haxe_generator : public t_oop_generator {
    * Serialization constructs
    */
 
-  void generate_deserialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
-  void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
-  void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
-  void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
-  void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
-  void generate_deserialize_list_element(std::ofstream& out,
+  void generate_deserialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
+  void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
+  void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
+  void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
+  void generate_deserialize_list_element(std::ostream& out,
                                          t_list* tlist,
                                          std::string prefix = "");
 
-  void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
-  void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
-  void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
-  void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
-  void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
-  void generate_serialize_map_element(std::ofstream& out,
+  void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
+  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
+  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
+  void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
+  void generate_serialize_map_element(std::ostream& out,
                                       t_map* tmap,
                                       std::string iter,
                                       std::string map);
 
-  void generate_haxe_doc(std::ofstream& out, t_doc* tdoc);
-  void generate_haxe_doc(std::ofstream& out, t_function* tdoc);
+  void generate_haxe_doc(std::ostream& out, t_doc* tdoc);
+  void generate_haxe_doc(std::ostream& out, t_function* tdoc);
 
-  void generate_rtti_decoration(std::ofstream& out);
-  void generate_macro_decoration(std::ofstream& out);
+  void generate_rtti_decoration(std::ostream& out);
+  void generate_macro_decoration(std::ostream& out);
 
   /**
    * Helper rendering functions
@@ -229,7 +229,7 @@ class t_haxe_generator : public t_oop_generator {
    */
 
   std::string package_name_;
-  std::ofstream f_service_;
+  ofstream_with_content_based_conditional_update f_service_;
   std::string package_dir_;
 };
 
@@ -386,7 +386,7 @@ void t_haxe_generator::generate_typedef(t_typedef* ttypedef) {
 void t_haxe_generator::generate_enum(t_enum* tenum) {
   // Make output file
   string f_enum_name = package_dir_ + "/" + get_cap_name(tenum->get_name()) + ".hx";
-  ofstream f_enum;
+  ofstream_with_content_based_conditional_update f_enum;
   f_enum.open(f_enum_name.c_str());
 
   // Comment and package it
@@ -448,7 +448,7 @@ void t_haxe_generator::generate_consts(std::vector<t_const*> consts) {
   }
 
   string f_consts_name = package_dir_ + "/" + get_cap_name(program_name_) + "Constants.hx";
-  ofstream f_consts;
+  ofstream_with_content_based_conditional_update f_consts;
   f_consts.open(f_consts_name.c_str());
 
   // Print header
@@ -475,7 +475,7 @@ void t_haxe_generator::generate_consts(std::vector<t_const*> consts) {
   f_consts.close();
 }
 
-void t_haxe_generator::print_const_value(std::ofstream& out,
+void t_haxe_generator::print_const_value(std::ostream& out,
                                          string name,
                                          t_type* type,
                                          t_const_value* value,
@@ -599,7 +599,7 @@ void t_haxe_generator::print_const_value(std::ofstream& out,
   }
 }
 
-string t_haxe_generator::render_const_value(ofstream& out,
+string t_haxe_generator::render_const_value(ostream& out,
                                             string name,
                                             t_type* type,
                                             t_const_value* value) {
@@ -676,7 +676,7 @@ void t_haxe_generator::generate_xception(t_struct* txception) {
 void t_haxe_generator::generate_haxe_struct(t_struct* tstruct, bool is_exception, bool is_result) {
   // Make output file
   string f_struct_name = package_dir_ + "/" + get_cap_name(tstruct->get_name()) + ".hx";
-  ofstream f_struct;
+  ofstream_with_content_based_conditional_update f_struct;
   f_struct.open(f_struct_name.c_str());
 
   f_struct << autogen_comment() << haxe_package() << ";" << endl;
@@ -703,7 +703,7 @@ void t_haxe_generator::generate_haxe_struct(t_struct* tstruct, bool is_exception
  * @param in_class     If inside a class, needs to be static class
  * @param is_result    If this is a result it needs a different writer
  */
-void t_haxe_generator::generate_haxe_struct_definition(ofstream& out,
+void t_haxe_generator::generate_haxe_struct_definition(ostream& out,
                                                        t_struct* tstruct,
                                                        bool is_exception,
                                                        bool is_result) {
@@ -817,7 +817,7 @@ void t_haxe_generator::generate_haxe_struct_definition(ofstream& out,
  *
  * @param tstruct The struct definition
  */
-void t_haxe_generator::generate_haxe_struct_reader(ofstream& out, t_struct* tstruct) {
+void t_haxe_generator::generate_haxe_struct_reader(ostream& out, t_struct* tstruct) {
   out << indent() << "public function read( iprot : TProtocol) : Void {" << endl;
   indent_up();
 
@@ -910,7 +910,7 @@ void t_haxe_generator::generate_haxe_struct_reader(ofstream& out, t_struct* tstr
 
 // generates haxe method to perform various checks
 // (e.g. check that all required fields are set)
-void t_haxe_generator::generate_haxe_validator(ofstream& out, t_struct* tstruct) {
+void t_haxe_generator::generate_haxe_validator(ostream& out, t_struct* tstruct) {
   indent(out) << "public function validate() : Void {" << endl;
   indent_up();
 
@@ -961,7 +961,7 @@ void t_haxe_generator::generate_haxe_validator(ofstream& out, t_struct* tstruct)
  *
  * @param tstruct The struct definition
  */
-void t_haxe_generator::generate_haxe_struct_writer(ofstream& out, t_struct* tstruct) {
+void t_haxe_generator::generate_haxe_struct_writer(ostream& out, t_struct* tstruct) {
   out << indent() << "public function write(oprot:TProtocol) : Void {" << endl;
   indent_up();
 
@@ -1031,7 +1031,7 @@ void t_haxe_generator::generate_haxe_struct_writer(ofstream& out, t_struct* tstr
  *
  * @param tstruct The struct definition
  */
-void t_haxe_generator::generate_haxe_struct_result_writer(ofstream& out, t_struct* tstruct) {
+void t_haxe_generator::generate_haxe_struct_result_writer(ostream& out, t_struct* tstruct) {
   out << indent() << "public function write(oprot:TProtocol) : Void {" << endl;
   indent_up();
 
@@ -1116,7 +1116,7 @@ void t_haxe_generator::generate_reflection_setters(ostringstream& out,
   indent_down();
 }
 
-void t_haxe_generator::generate_generic_field_getters_setters(std::ofstream& out,
+void t_haxe_generator::generate_generic_field_getters_setters(std::ostream& out,
                                                               t_struct* tstruct) {
 
   std::ostringstream getter_stream;
@@ -1174,7 +1174,7 @@ void t_haxe_generator::generate_generic_field_getters_setters(std::ofstream& out
 }
 
 // Creates a generic isSet method that takes the field number as argument
-void t_haxe_generator::generate_generic_isset_method(std::ofstream& out, t_struct* tstruct) {
+void t_haxe_generator::generate_generic_isset_method(std::ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
@@ -1210,7 +1210,7 @@ void t_haxe_generator::generate_generic_isset_method(std::ofstream& out, t_struc
  *
  * @param tstruct The struct definition
  */
-void t_haxe_generator::generate_property_getters_setters(ofstream& out, t_struct* tstruct) {
+void t_haxe_generator::generate_property_getters_setters(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
   for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
@@ -1272,7 +1272,7 @@ void t_haxe_generator::generate_property_getters_setters(ofstream& out, t_struct
  *
  * @param tstruct The struct definition
  */
-void t_haxe_generator::generate_haxe_struct_tostring(ofstream& out, t_struct* tstruct) {
+void t_haxe_generator::generate_haxe_struct_tostring(ostream& out, t_struct* tstruct) {
   out << indent() << "public "
       << "function toString() : String {" << endl;
   indent_up();
@@ -1346,7 +1346,7 @@ void t_haxe_generator::generate_haxe_struct_tostring(ofstream& out, t_struct* ts
  *
  * @param tstruct The struct definition
  */
-void t_haxe_generator::generate_haxe_meta_data_map(ofstream& out, t_struct* tstruct) {
+void t_haxe_generator::generate_haxe_meta_data_map(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
@@ -1434,7 +1434,7 @@ std::string t_haxe_generator::get_haxe_type_string(t_type* type) {
   }
 }
 
-void t_haxe_generator::generate_field_value_meta_data(std::ofstream& out, t_type* type) {
+void t_haxe_generator::generate_field_value_meta_data(std::ostream& out, t_type* type) {
   out << endl;
   indent_up();
   indent_up();
@@ -2176,7 +2176,7 @@ void t_haxe_generator::generate_process_function(t_service* tservice, t_function
  * @param tfield The field
  * @param prefix The variable name or container for this field
  */
-void t_haxe_generator::generate_deserialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_haxe_generator::generate_deserialize_field(ostream& out, t_field* tfield, string prefix) {
   t_type* type = get_true_type(tfield->get_type());
 
   if (type->is_void()) {
@@ -2241,7 +2241,7 @@ void t_haxe_generator::generate_deserialize_field(ofstream& out, t_field* tfield
 /**
  * Generates an unserializer for a struct, invokes read()
  */
-void t_haxe_generator::generate_deserialize_struct(ofstream& out,
+void t_haxe_generator::generate_deserialize_struct(ostream& out,
                                                    t_struct* tstruct,
                                                    string prefix) {
   out << indent() << prefix << " = new " << get_cap_name(type_name(tstruct)) << "();" << endl
@@ -2251,7 +2251,7 @@ void t_haxe_generator::generate_deserialize_struct(ofstream& out,
 /**
  * Deserializes a container by reading its size and then iterating
  */
-void t_haxe_generator::generate_deserialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_haxe_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) {
   scope_up(out);
 
   string obj;
@@ -2309,7 +2309,7 @@ void t_haxe_generator::generate_deserialize_container(ofstream& out, t_type* tty
 /**
  * Generates code to deserialize a map
  */
-void t_haxe_generator::generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix) {
+void t_haxe_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix) {
   string key = tmp("_key");
   string val = tmp("_val");
   t_field fkey(tmap->get_key_type(), key);
@@ -2327,7 +2327,7 @@ void t_haxe_generator::generate_deserialize_map_element(ofstream& out, t_map* tm
 /**
  * Deserializes a set element
  */
-void t_haxe_generator::generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix) {
+void t_haxe_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) {
   string elem = tmp("_elem");
   t_field felem(tset->get_elem_type(), elem);
 
@@ -2341,7 +2341,7 @@ void t_haxe_generator::generate_deserialize_set_element(ofstream& out, t_set* ts
 /**
  * Deserializes a list element
  */
-void t_haxe_generator::generate_deserialize_list_element(ofstream& out,
+void t_haxe_generator::generate_deserialize_list_element(ostream& out,
                                                          t_list* tlist,
                                                          string prefix) {
   string elem = tmp("_elem");
@@ -2360,7 +2360,7 @@ void t_haxe_generator::generate_deserialize_list_element(ofstream& out,
  * @param tfield The field to serialize
  * @param prefix Name to prepend to field name
  */
-void t_haxe_generator::generate_serialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_haxe_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix) {
   t_type* type = get_true_type(tfield->get_type());
 
   // Do nothing for void types
@@ -2429,7 +2429,7 @@ void t_haxe_generator::generate_serialize_field(ofstream& out, t_field* tfield,
  * @param tstruct The struct to serialize
  * @param prefix  String prefix to attach to all fields
  */
-void t_haxe_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_haxe_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   (void)tstruct;
   out << indent() << prefix << ".write(oprot);" << endl;
 }
@@ -2440,7 +2440,7 @@ void t_haxe_generator::generate_serialize_struct(ofstream& out, t_struct* tstruc
  * @param ttype  The type of container
  * @param prefix String prefix for fields
  */
-void t_haxe_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_haxe_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
   scope_up(out);
 
   if (ttype->is_map()) {
@@ -2498,7 +2498,7 @@ void t_haxe_generator::generate_serialize_container(ofstream& out, t_type* ttype
 /**
  * Serializes the members of a map.
  */
-void t_haxe_generator::generate_serialize_map_element(ofstream& out,
+void t_haxe_generator::generate_serialize_map_element(ostream& out,
                                                       t_map* tmap,
                                                       string iter,
                                                       string map) {
@@ -2511,7 +2511,7 @@ void t_haxe_generator::generate_serialize_map_element(ofstream& out,
 /**
  * Serializes the members of a set.
  */
-void t_haxe_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
+void t_haxe_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
   t_field efield(tset->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "");
 }
@@ -2519,7 +2519,7 @@ void t_haxe_generator::generate_serialize_set_element(ofstream& out, t_set* tset
 /**
  * Serializes the members of a list.
  */
-void t_haxe_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string iter) {
+void t_haxe_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter) {
   t_field efield(tlist->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "");
 }
@@ -2661,7 +2661,7 @@ string t_haxe_generator::declare_field(t_field* tfield, bool init) {
   if (init) {
     t_type* ttype = get_true_type(tfield->get_type());
     if (ttype->is_base_type() && tfield->get_value() != NULL) {
-      ofstream dummy;
+      std::ofstream dummy;
       result += " = " + render_const_value(dummy, tfield->get_name(), ttype, tfield->get_value());
     } else if (ttype->is_base_type()) {
       t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base();
@@ -2904,7 +2904,7 @@ string t_haxe_generator::constant_name(string name) {
 /**
  * Enables RTTI for a class or interface
  */
-void t_haxe_generator::generate_rtti_decoration(ofstream& out) {
+void t_haxe_generator::generate_rtti_decoration(ostream& out) {
   if (rtti_) {
     out << "@:rtti" << endl;
   }
@@ -2913,7 +2913,7 @@ void t_haxe_generator::generate_rtti_decoration(ofstream& out) {
 /**
  * Adds build macros to a class or interface
  */
-void t_haxe_generator::generate_macro_decoration(ofstream& out) {
+void t_haxe_generator::generate_macro_decoration(ostream& out) {
   if (!buildmacro_.empty()) {
     out << "#if ! macro" << endl;
     out << "@:build( " << buildmacro_ << ")" << endl;     // current class/interface
@@ -2925,7 +2925,7 @@ void t_haxe_generator::generate_macro_decoration(ofstream& out) {
 /**
  * Emits a haxeDoc comment if the provided object has a doc in Thrift
  */
-void t_haxe_generator::generate_haxe_doc(ofstream& out, t_doc* tdoc) {
+void t_haxe_generator::generate_haxe_doc(ostream& out, t_doc* tdoc) {
   if (tdoc->has_doc()) {
     generate_docstring_comment(out, "/**\n", " * ", tdoc->get_doc(), " */\n");
   }
@@ -2934,7 +2934,7 @@ void t_haxe_generator::generate_haxe_doc(ofstream& out, t_doc* tdoc) {
 /**
  * Emits a haxeDoc comment if the provided function object has a doc in Thrift
  */
-void t_haxe_generator::generate_haxe_doc(ofstream& out, t_function* tfunction) {
+void t_haxe_generator::generate_haxe_doc(ostream& out, t_function* tfunction) {
   if (tfunction->has_doc()) {
     stringstream ss;
     ss << tfunction->get_doc();
@@ -2959,7 +2959,7 @@ std::string t_haxe_generator::generate_isset_check(std::string field_name) {
   return "is" + get_cap_name("set") + get_cap_name(field_name) + "()";
 }
 
-void t_haxe_generator::generate_isset_set(ofstream& out, t_field* field) {
+void t_haxe_generator::generate_isset_set(ostream& out, t_field* field) {
   if (!type_can_be_null(field->get_type())) {
     indent(out) << "this.__isset_" << field->get_name() << " = true;" << endl;
   }
diff --git a/compiler/cpp/src/thrift/generate/t_hs_generator.cc b/compiler/cpp/src/thrift/generate/t_hs_generator.cc
index 6c8cb7fc9d..ce7cd0c76c 100644
--- a/compiler/cpp/src/thrift/generate/t_hs_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_hs_generator.cc
@@ -33,7 +33,7 @@
 #include "thrift/generate/t_oop_generator.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -87,22 +87,22 @@ class t_hs_generator : public t_oop_generator {
 
   void generate_hs_struct(t_struct* tstruct, bool is_exception);
 
-  void generate_hs_struct_definition(ofstream& out,
+  void generate_hs_struct_definition(ostream& out,
                                      t_struct* tstruct,
                                      bool is_xception = false,
                                      bool helper = false);
 
-  void generate_hs_struct_reader(ofstream& out, t_struct* tstruct);
+  void generate_hs_struct_reader(ostream& out, t_struct* tstruct);
 
-  void generate_hs_struct_writer(ofstream& out, t_struct* tstruct);
+  void generate_hs_struct_writer(ostream& out, t_struct* tstruct);
 
-  void generate_hs_struct_arbitrary(ofstream& out, t_struct* tstruct);
+  void generate_hs_struct_arbitrary(ostream& out, t_struct* tstruct);
 
   void generate_hs_function_helpers(t_function* tfunction);
 
-  void generate_hs_typemap(ofstream& out, t_struct* tstruct);
+  void generate_hs_typemap(ostream& out, t_struct* tstruct);
 
-  void generate_hs_default(ofstream& out, t_struct* tstruct);
+  void generate_hs_default(ostream& out, t_struct* tstruct);
 
   /**
    * Service-level generation functions
@@ -118,29 +118,29 @@ class t_hs_generator : public t_oop_generator {
    * Serialization constructs
    */
 
-  void generate_deserialize_field(ofstream& out, t_field* tfield, string prefix);
+  void generate_deserialize_field(ostream& out, t_field* tfield, string prefix);
 
-  void generate_deserialize_struct(ofstream& out, t_struct* tstruct, string name = "");
+  void generate_deserialize_struct(ostream& out, t_struct* tstruct, string name = "");
 
-  void generate_deserialize_container(ofstream& out, t_type* ttype, string arg = "");
+  void generate_deserialize_container(ostream& out, t_type* ttype, string arg = "");
 
-  void generate_deserialize_set_element(ofstream& out, t_set* tset);
+  void generate_deserialize_set_element(ostream& out, t_set* tset);
 
-  void generate_deserialize_list_element(ofstream& out, t_list* tlist, string prefix = "");
+  void generate_deserialize_list_element(ostream& out, t_list* tlist, string prefix = "");
 
-  void generate_deserialize_type(ofstream& out, t_type* type, string arg = "");
+  void generate_deserialize_type(ostream& out, t_type* type, string arg = "");
 
-  void generate_serialize_type(ofstream& out, t_type* type, string name = "");
+  void generate_serialize_type(ostream& out, t_type* type, string name = "");
 
-  void generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix = "");
+  void generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix = "");
 
-  void generate_serialize_container(ofstream& out, t_type* ttype, string prefix = "");
+  void generate_serialize_container(ostream& out, t_type* ttype, string prefix = "");
 
-  void generate_serialize_map_element(ofstream& out, t_map* tmap, string kiter, string viter);
+  void generate_serialize_map_element(ostream& out, t_map* tmap, string kiter, string viter);
 
-  void generate_serialize_set_element(ofstream& out, t_set* tmap, string iter);
+  void generate_serialize_set_element(ostream& out, t_set* tmap, string iter);
 
-  void generate_serialize_list_element(ofstream& out, t_list* tlist, string iter);
+  void generate_serialize_list_element(ostream& out, t_list* tlist, string iter);
 
   /**
    * Helper rendering functions
@@ -170,11 +170,11 @@ class t_hs_generator : public t_oop_generator {
   string render_hs_type_for_function_name(t_type* type);
 
 private:
-  ofstream f_types_;
-  ofstream f_consts_;
-  ofstream f_service_;
-  ofstream f_iface_;
-  ofstream f_client_;
+  ofstream_with_content_based_conditional_update f_types_;
+  ofstream_with_content_based_conditional_update f_consts_;
+  ofstream_with_content_based_conditional_update f_service_;
+  ofstream_with_content_based_conditional_update f_iface_;
+  ofstream_with_content_based_conditional_update f_client_;
 };
 
 /**
@@ -530,7 +530,7 @@ void t_hs_generator::generate_hs_struct(t_struct* tstruct, bool is_exception) {
  *
  * @param tstruct The struct definition
  */
-void t_hs_generator::generate_hs_struct_definition(ofstream& out,
+void t_hs_generator::generate_hs_struct_definition(ostream& out,
                                                    t_struct* tstruct,
                                                    bool is_exception,
                                                    bool helper) {
@@ -586,7 +586,7 @@ void t_hs_generator::generate_hs_struct_definition(ofstream& out,
   generate_hs_default(out, tstruct);
 }
 
-void t_hs_generator::generate_hs_struct_arbitrary(ofstream& out, t_struct* tstruct) {
+void t_hs_generator::generate_hs_struct_arbitrary(ostream& out, t_struct* tstruct) {
   string tname = type_name(tstruct);
   string name = tstruct->get_name();
   const vector<t_field*>& members = tstruct->get_members();
@@ -652,7 +652,7 @@ void t_hs_generator::generate_hs_struct_arbitrary(ofstream& out, t_struct* tstru
 /**
  * Generates the read method for a struct
  */
-void t_hs_generator::generate_hs_struct_reader(ofstream& out, t_struct* tstruct) {
+void t_hs_generator::generate_hs_struct_reader(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
@@ -722,7 +722,7 @@ void t_hs_generator::generate_hs_struct_reader(ofstream& out, t_struct* tstruct)
   out << "T.deserializeVal iprot (T.T_STRUCT " << tmap << ") bs" << endl;
 }
 
-void t_hs_generator::generate_hs_struct_writer(ofstream& out, t_struct* tstruct) {
+void t_hs_generator::generate_hs_struct_writer(ostream& out, t_struct* tstruct) {
   string name = type_name(tstruct);
   const vector<t_field*>& fields = tstruct->get_sorted_members();
   vector<t_field*>::const_iterator f_iter;
@@ -906,7 +906,7 @@ void t_hs_generator::generate_hs_function_helpers(t_function* tfunction) {
  * Generate the map from field names to (type, id)
  * @param tstruct the Struct
  */
-void t_hs_generator::generate_hs_typemap(ofstream& out, t_struct* tstruct) {
+void t_hs_generator::generate_hs_typemap(ostream& out, t_struct* tstruct) {
   string name = type_name(tstruct);
   const vector<t_field*>& fields = tstruct->get_sorted_members();
   vector<t_field*>::const_iterator f_iter;
@@ -932,7 +932,7 @@ void t_hs_generator::generate_hs_typemap(ofstream& out, t_struct* tstruct) {
  * generate the struct with default values filled in
  * @param tstruct the Struct
  */
-void t_hs_generator::generate_hs_default(ofstream& out, t_struct* tstruct) {
+void t_hs_generator::generate_hs_default(ostream& out, t_struct* tstruct) {
   string name = type_name(tstruct);
   string fname = type_name(tstruct, "default_");
   const vector<t_field*>& fields = tstruct->get_sorted_members();
@@ -1342,7 +1342,7 @@ void t_hs_generator::generate_process_function(t_service* tservice, t_function*
 /**
  * Deserializes a field of any type.
  */
-void t_hs_generator::generate_deserialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_hs_generator::generate_deserialize_field(ostream& out, t_field* tfield, string prefix) {
   (void)prefix;
   t_type* type = tfield->get_type();
   generate_deserialize_type(out, type, prefix);
@@ -1351,7 +1351,7 @@ void t_hs_generator::generate_deserialize_field(ofstream& out, t_field* tfield,
 /**
  * Deserializes a field of any type.
  */
-void t_hs_generator::generate_deserialize_type(ofstream& out, t_type* type, string arg) {
+void t_hs_generator::generate_deserialize_type(ostream& out, t_type* type, string arg) {
   type = get_true_type(type);
   string val = tmp("_val");
   out << "(case " << arg << " of {" << type_to_constructor(type) << " " << val << " -> ";
@@ -1388,7 +1388,7 @@ void t_hs_generator::generate_deserialize_type(ofstream& out, t_type* type, stri
 /**
  * Generates an unserializer for a struct, calling read()
  */
-void t_hs_generator::generate_deserialize_struct(ofstream& out, t_struct* tstruct, string name) {
+void t_hs_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string name) {
 
   out << "(" << type_name(tstruct, "to_") << " (T.TStruct " << name << "))";
 }
@@ -1397,7 +1397,7 @@ void t_hs_generator::generate_deserialize_struct(ofstream& out, t_struct* tstruc
  * Serialize a container by writing out the header followed by
  * data and then a footer.
  */
-void t_hs_generator::generate_deserialize_container(ofstream& out, t_type* ttype, string arg) {
+void t_hs_generator::generate_deserialize_container(ostream& out, t_type* ttype, string arg) {
 
   string val = tmp("_v");
   // Declare variables, read header
@@ -1429,7 +1429,7 @@ void t_hs_generator::generate_deserialize_container(ofstream& out, t_type* ttype
  * @param tfield The field to serialize
  * @param prefix Name to prepend to field name
  */
-void t_hs_generator::generate_serialize_type(ofstream& out, t_type* type, string name) {
+void t_hs_generator::generate_serialize_type(ostream& out, t_type* type, string name) {
 
   type = get_true_type(type);
   // Do nothing for void types
@@ -1467,11 +1467,11 @@ void t_hs_generator::generate_serialize_type(ofstream& out, t_type* type, string
  * @param tstruct The struct to serialize
  * @param prefix  String prefix to attach to all fields
  */
-void t_hs_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_hs_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   out << type_name(tstruct, "from_") << " " << prefix;
 }
 
-void t_hs_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_hs_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
   string k = tmp("_k");
   string v = tmp("_v");
 
diff --git a/compiler/cpp/src/thrift/generate/t_html_generator.cc b/compiler/cpp/src/thrift/generate/t_html_generator.cc
index 5b063707f5..8dfa3897eb 100644
--- a/compiler/cpp/src/thrift/generate/t_html_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_html_generator.cc
@@ -90,7 +90,7 @@ class t_html_generator : public t_generator {
   std::string escape_html(std::string const& str);
   std::string escape_html_tags(std::string const& str);
   void generate_css();
-  void generate_css_content(std::ofstream& f_target);
+  void generate_css_content(std::ostream& f_target);
   void generate_style_tag();
   std::string make_file_link(std::string name);
   bool is_utf8_sequence(std::string const& str, size_t firstpos);
@@ -114,7 +114,7 @@ class t_html_generator : public t_generator {
   void print_fn_args_doc(t_function* tfunction);
 
 private:
-  std::ofstream f_out_;
+  ofstream_with_content_based_conditional_update f_out_;
   std::string current_file_;
   input_type input_type_;
   std::map<std::string, int> allowed_markup;
@@ -359,7 +359,7 @@ void t_html_generator::generate_css() {
   }
 }
 
-void t_html_generator::generate_css_content(std::ofstream& f_target) {
+void t_html_generator::generate_css_content(std::ostream& f_target) {
   f_target << BOOTSTRAP_CSS() << endl;
   f_target << "/* Auto-generated CSS for generated Thrift docs */" << endl;
   f_target << "h3, h4 { margin-bottom: 6px; }" << endl;
diff --git a/compiler/cpp/src/thrift/generate/t_java_generator.cc b/compiler/cpp/src/thrift/generate/t_java_generator.cc
index 754601f508..f11ae3b08e 100644
--- a/compiler/cpp/src/thrift/generate/t_java_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_java_generator.cc
@@ -36,7 +36,7 @@
 #include "thrift/generate/t_oop_generator.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::setfill;
 using std::setw;
@@ -135,13 +135,13 @@ class t_java_generator : public t_oop_generator {
   void generate_xception(t_struct* txception);
   void generate_service(t_service* tservice);
 
-  void print_const_value(std::ofstream& out,
+  void print_const_value(std::ostream& out,
                          std::string name,
                          t_type* type,
                          t_const_value* value,
                          bool in_static,
                          bool defval = false);
-  std::string render_const_value(std::ofstream& out, t_type* type, t_const_value* value);
+  std::string render_const_value(std::ostream& out, t_type* type, t_const_value* value);
 
   /**
    * Service-level generation functions
@@ -149,26 +149,26 @@ class t_java_generator : public t_oop_generator {
 
   void generate_java_struct(t_struct* tstruct, bool is_exception);
 
-  void generate_java_struct_definition(std::ofstream& out,
+  void generate_java_struct_definition(std::ostream& out,
                                        t_struct* tstruct,
                                        bool is_xception = false,
                                        bool in_class = false,
                                        bool is_result = false);
-  void generate_java_struct_parcelable(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_equality(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_compare_to(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_reader(std::ofstream& out, t_struct* tstruct);
-  void generate_java_validator(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_result_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_tostring(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_clear(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_write_object(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_read_object(std::ofstream& out, t_struct* tstruct);
-  void generate_java_meta_data_map(std::ofstream& out, t_struct* tstruct);
-  void generate_field_value_meta_data(std::ofstream& out, t_type* type);
+  void generate_java_struct_parcelable(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_equality(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_compare_to(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_reader(std::ostream& out, t_struct* tstruct);
+  void generate_java_validator(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_result_writer(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_writer(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_tostring(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_clear(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_write_object(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_read_object(std::ostream& out, t_struct* tstruct);
+  void generate_java_meta_data_map(std::ostream& out, t_struct* tstruct);
+  void generate_field_value_meta_data(std::ostream& out, t_type* type);
   std::string get_java_type_string(t_type* type);
-  void generate_java_struct_field_by_id(ofstream& out, t_struct* tstruct);
+  void generate_java_struct_field_by_id(ostream& out, t_struct* tstruct);
   void generate_reflection_setters(std::ostringstream& out,
                                    t_type* type,
                                    std::string field_name,
@@ -177,9 +177,9 @@ class t_java_generator : public t_oop_generator {
                                    t_type* type,
                                    std::string field_name,
                                    std::string cap_name);
-  void generate_generic_field_getters_setters(std::ofstream& out, t_struct* tstruct);
-  void generate_generic_isset_method(std::ofstream& out, t_struct* tstruct);
-  void generate_java_bean_boilerplate(std::ofstream& out, t_struct* tstruct);
+  void generate_generic_field_getters_setters(std::ostream& out, t_struct* tstruct);
+  void generate_generic_isset_method(std::ostream& out, t_struct* tstruct);
+  void generate_java_bean_boilerplate(std::ostream& out, t_struct* tstruct);
 
   void generate_function_helpers(t_function* tfunction);
   std::string as_camel_case(std::string name, bool ucfirst = true);
@@ -187,7 +187,7 @@ class t_java_generator : public t_oop_generator {
   std::string get_cap_name(std::string name);
   std::string generate_isset_check(t_field* field);
   std::string generate_isset_check(std::string field);
-  void generate_isset_set(ofstream& out, t_field* field, std::string prefix);
+  void generate_isset_set(ostream& out, t_field* field, std::string prefix);
   std::string isset_field_id(t_field* field);
 
   void generate_service_interface(t_service* tservice);
@@ -201,102 +201,102 @@ class t_java_generator : public t_oop_generator {
   void generate_process_async_function(t_service* tservice, t_function* tfunction);
 
   void generate_java_union(t_struct* tstruct);
-  void generate_union_constructor(ofstream& out, t_struct* tstruct);
-  void generate_union_getters_and_setters(ofstream& out, t_struct* tstruct);
-  void generate_union_is_set_methods(ofstream& out, t_struct* tstruct);
-  void generate_union_abstract_methods(ofstream& out, t_struct* tstruct);
-  void generate_check_type(ofstream& out, t_struct* tstruct);
-  void generate_standard_scheme_read_value(ofstream& out, t_struct* tstruct);
-  void generate_standard_scheme_write_value(ofstream& out, t_struct* tstruct);
-  void generate_tuple_scheme_read_value(ofstream& out, t_struct* tstruct);
-  void generate_tuple_scheme_write_value(ofstream& out, t_struct* tstruct);
-  void generate_get_field_desc(ofstream& out, t_struct* tstruct);
-  void generate_get_struct_desc(ofstream& out, t_struct* tstruct);
-  void generate_get_field_name(ofstream& out, t_struct* tstruct);
-
-  void generate_union_comparisons(ofstream& out, t_struct* tstruct);
-  void generate_union_hashcode(ofstream& out, t_struct* tstruct);
-
-  void generate_scheme_map(ofstream& out, t_struct* tstruct);
-  void generate_standard_writer(ofstream& out, t_struct* tstruct, bool is_result);
-  void generate_standard_reader(ofstream& out, t_struct* tstruct);
-  void generate_java_struct_standard_scheme(ofstream& out, t_struct* tstruct, bool is_result);
-
-  void generate_java_struct_tuple_scheme(ofstream& out, t_struct* tstruct);
-  void generate_java_struct_tuple_reader(ofstream& out, t_struct* tstruct);
-  void generate_java_struct_tuple_writer(ofstream& out, t_struct* tstruct);
-
-  void generate_java_scheme_lookup(ofstream& out);
-
-  void generate_javax_generated_annotation(ofstream& out);
+  void generate_union_constructor(ostream& out, t_struct* tstruct);
+  void generate_union_getters_and_setters(ostream& out, t_struct* tstruct);
+  void generate_union_is_set_methods(ostream& out, t_struct* tstruct);
+  void generate_union_abstract_methods(ostream& out, t_struct* tstruct);
+  void generate_check_type(ostream& out, t_struct* tstruct);
+  void generate_standard_scheme_read_value(ostream& out, t_struct* tstruct);
+  void generate_standard_scheme_write_value(ostream& out, t_struct* tstruct);
+  void generate_tuple_scheme_read_value(ostream& out, t_struct* tstruct);
+  void generate_tuple_scheme_write_value(ostream& out, t_struct* tstruct);
+  void generate_get_field_desc(ostream& out, t_struct* tstruct);
+  void generate_get_struct_desc(ostream& out, t_struct* tstruct);
+  void generate_get_field_name(ostream& out, t_struct* tstruct);
+
+  void generate_union_comparisons(ostream& out, t_struct* tstruct);
+  void generate_union_hashcode(ostream& out, t_struct* tstruct);
+
+  void generate_scheme_map(ostream& out, t_struct* tstruct);
+  void generate_standard_writer(ostream& out, t_struct* tstruct, bool is_result);
+  void generate_standard_reader(ostream& out, t_struct* tstruct);
+  void generate_java_struct_standard_scheme(ostream& out, t_struct* tstruct, bool is_result);
+
+  void generate_java_struct_tuple_scheme(ostream& out, t_struct* tstruct);
+  void generate_java_struct_tuple_reader(ostream& out, t_struct* tstruct);
+  void generate_java_struct_tuple_writer(ostream& out, t_struct* tstruct);
+
+  void generate_java_scheme_lookup(ostream& out);
+
+  void generate_javax_generated_annotation(ostream& out);
   /**
    * Serialization constructs
    */
 
-  void generate_deserialize_field(std::ofstream& out,
+  void generate_deserialize_field(std::ostream& out,
                                   t_field* tfield,
                                   std::string prefix = "",
                                   bool has_metadata = true);
 
-  void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_deserialize_container(std::ofstream& out,
+  void generate_deserialize_container(std::ostream& out,
                                       t_type* ttype,
                                       std::string prefix = "",
                                       bool has_metadata = true);
 
-  void generate_deserialize_set_element(std::ofstream& out,
+  void generate_deserialize_set_element(std::ostream& out,
                                         t_set* tset,
                                         std::string prefix = "",
                                         std::string obj = "",
                                         bool has_metadata = true);
 
-  void generate_deserialize_map_element(std::ofstream& out,
+  void generate_deserialize_map_element(std::ostream& out,
                                         t_map* tmap,
                                         std::string prefix = "",
                                         std::string obj = "",
                                         bool has_metadata = true);
 
-  void generate_deserialize_list_element(std::ofstream& out,
+  void generate_deserialize_list_element(std::ostream& out,
                                          t_list* tlist,
                                          std::string prefix = "",
                                          std::string obj = "",
                                          bool has_metadata = true);
 
-  void generate_serialize_field(std::ofstream& out,
+  void generate_serialize_field(std::ostream& out,
                                 t_field* tfield,
                                 std::string prefix = "",
                                 bool has_metadata = true);
 
-  void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_serialize_container(std::ofstream& out,
+  void generate_serialize_container(std::ostream& out,
                                     t_type* ttype,
                                     std::string prefix = "",
                                     bool has_metadata = true);
 
-  void generate_serialize_map_element(std::ofstream& out,
+  void generate_serialize_map_element(std::ostream& out,
                                       t_map* tmap,
                                       std::string iter,
                                       std::string map,
                                       bool has_metadata = true);
 
-  void generate_serialize_set_element(std::ofstream& out,
+  void generate_serialize_set_element(std::ostream& out,
                                       t_set* tmap,
                                       std::string iter,
                                       bool has_metadata = true);
 
-  void generate_serialize_list_element(std::ofstream& out,
+  void generate_serialize_list_element(std::ostream& out,
                                        t_list* tlist,
                                        std::string iter,
                                        bool has_metadata = true);
 
-  void generate_deep_copy_container(std::ofstream& out,
+  void generate_deep_copy_container(std::ostream& out,
                                     std::string source_name_p1,
                                     std::string source_name_p2,
                                     std::string result_name,
                                     t_type* type);
-  void generate_deep_copy_non_container(std::ofstream& out,
+  void generate_deep_copy_non_container(std::ostream& out,
                                         std::string source_name,
                                         std::string dest_name,
                                         t_type* type);
@@ -331,9 +331,9 @@ class t_java_generator : public t_oop_generator {
                                   t_type* ttype,
                                   bool include_types = false);
   std::string type_to_enum(t_type* ttype);
-  void generate_struct_desc(ofstream& out, t_struct* tstruct);
-  void generate_field_descs(ofstream& out, t_struct* tstruct);
-  void generate_field_name_constants(ofstream& out, t_struct* tstruct);
+  void generate_struct_desc(ostream& out, t_struct* tstruct);
+  void generate_field_descs(ostream& out, t_struct* tstruct);
+  void generate_field_name_constants(ostream& out, t_struct* tstruct);
 
   std::string make_valid_java_filename(std::string const& fromName);
   std::string make_valid_java_identifier(std::string const& fromName);
@@ -395,7 +395,7 @@ class t_java_generator : public t_oop_generator {
    */
 
   std::string package_name_;
-  std::ofstream f_service_;
+  ofstream_with_content_based_conditional_update f_service_;
   std::string package_dir_;
 
   bool bean_style_;
@@ -487,7 +487,7 @@ void t_java_generator::generate_enum(t_enum* tenum) {
   bool is_deprecated = this->is_deprecated(tenum->annotations_);
   // Make output file
   string f_enum_name = package_dir_ + "/" + make_valid_java_filename(tenum->get_name()) + ".java";
-  ofstream f_enum;
+  ofstream_with_content_based_conditional_update f_enum;
   f_enum.open(f_enum_name.c_str());
 
   // Comment and package it
@@ -579,7 +579,7 @@ void t_java_generator::generate_consts(std::vector<t_const*> consts) {
 
   string f_consts_name = package_dir_ + '/' + make_valid_java_filename(program_name_)
                          + "Constants.java";
-  ofstream f_consts;
+  ofstream_with_content_based_conditional_update f_consts;
   f_consts.open(f_consts_name.c_str());
 
   // Print header
@@ -608,7 +608,7 @@ void t_java_generator::generate_consts(std::vector<t_const*> consts) {
  * is NOT performed in this function as it is always run beforehand using the
  * validate_types method in main.cc
  */
-void t_java_generator::print_const_value(std::ofstream& out,
+void t_java_generator::print_const_value(std::ostream& out,
                                          string name,
                                          t_type* type,
                                          t_const_value* value,
@@ -713,7 +713,7 @@ void t_java_generator::print_const_value(std::ofstream& out,
   }
 }
 
-string t_java_generator::render_const_value(ofstream& out, t_type* type, t_const_value* value) {
+string t_java_generator::render_const_value(ostream& out, t_type* type, t_const_value* value) {
   type = get_true_type(type);
   std::ostringstream render;
 
@@ -795,7 +795,7 @@ void t_java_generator::generate_java_struct(t_struct* tstruct, bool is_exception
   // Make output file
   string f_struct_name = package_dir_ + "/" + make_valid_java_filename(tstruct->get_name())
                          + ".java";
-  ofstream f_struct;
+  ofstream_with_content_based_conditional_update f_struct;
   f_struct.open(f_struct_name.c_str());
 
   f_struct << autogen_comment() << java_package() << java_suppressions();
@@ -813,7 +813,7 @@ void t_java_generator::generate_java_union(t_struct* tstruct) {
   // Make output file
   string f_struct_name = package_dir_ + "/" + make_valid_java_filename(tstruct->get_name())
                          + ".java";
-  ofstream f_struct;
+  ofstream_with_content_based_conditional_update f_struct;
   f_struct.open(f_struct_name.c_str());
 
   f_struct << autogen_comment() << java_package() << java_suppressions();
@@ -884,7 +884,7 @@ void t_java_generator::generate_java_union(t_struct* tstruct) {
   f_struct.close();
 }
 
-void t_java_generator::generate_union_constructor(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_union_constructor(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& members = tstruct->get_members();
   vector<t_field*>::const_iterator m_iter;
 
@@ -942,7 +942,7 @@ void t_java_generator::generate_union_constructor(ofstream& out, t_struct* tstru
   }
 }
 
-void t_java_generator::generate_union_getters_and_setters(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_union_getters_and_setters(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& members = tstruct->get_members();
   vector<t_field*>::const_iterator m_iter;
 
@@ -1033,7 +1033,7 @@ void t_java_generator::generate_union_getters_and_setters(ofstream& out, t_struc
   }
 }
 
-void t_java_generator::generate_union_is_set_methods(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_union_is_set_methods(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& members = tstruct->get_members();
   vector<t_field*>::const_iterator m_iter;
 
@@ -1056,7 +1056,7 @@ void t_java_generator::generate_union_is_set_methods(ofstream& out, t_struct* ts
   }
 }
 
-void t_java_generator::generate_union_abstract_methods(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_union_abstract_methods(ostream& out, t_struct* tstruct) {
   generate_check_type(out, tstruct);
   out << endl;
   generate_standard_scheme_read_value(out, tstruct);
@@ -1077,7 +1077,7 @@ void t_java_generator::generate_union_abstract_methods(ofstream& out, t_struct*
   indent(out) << "}" << endl;
 }
 
-void t_java_generator::generate_check_type(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_check_type(ostream& out, t_struct* tstruct) {
   indent(out) << "@Override" << endl;
   indent(out)
       << "protected void checkType(_Fields setField, java.lang.Object value) throws java.lang.ClassCastException {"
@@ -1114,7 +1114,7 @@ void t_java_generator::generate_check_type(ofstream& out, t_struct* tstruct) {
   indent(out) << "}" << endl;
 }
 
-void t_java_generator::generate_standard_scheme_read_value(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_standard_scheme_read_value(ostream& out, t_struct* tstruct) {
   indent(out) << "@Override" << endl;
   indent(out) << "protected java.lang.Object standardSchemeReadValue(org.apache.thrift.protocol.TProtocol "
                  "iprot, org.apache.thrift.protocol.TField field) throws "
@@ -1170,7 +1170,7 @@ void t_java_generator::generate_standard_scheme_read_value(ofstream& out, t_stru
   indent(out) << "}" << endl;
 }
 
-void t_java_generator::generate_standard_scheme_write_value(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_standard_scheme_write_value(ostream& out, t_struct* tstruct) {
   indent(out) << "@Override" << endl;
   indent(out) << "protected void standardSchemeWriteValue(org.apache.thrift.protocol.TProtocol "
                  "oprot) throws org.apache.thrift.TException {" << endl;
@@ -1207,7 +1207,7 @@ void t_java_generator::generate_standard_scheme_write_value(ofstream& out, t_str
   indent(out) << "}" << endl;
 }
 
-void t_java_generator::generate_tuple_scheme_read_value(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_tuple_scheme_read_value(ostream& out, t_struct* tstruct) {
   indent(out) << "@Override" << endl;
   indent(out) << "protected java.lang.Object tupleSchemeReadValue(org.apache.thrift.protocol.TProtocol "
                  "iprot, short fieldID) throws org.apache.thrift.TException {" << endl;
@@ -1253,7 +1253,7 @@ void t_java_generator::generate_tuple_scheme_read_value(ofstream& out, t_struct*
   indent(out) << "}" << endl;
 }
 
-void t_java_generator::generate_tuple_scheme_write_value(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_tuple_scheme_write_value(ostream& out, t_struct* tstruct) {
   indent(out) << "@Override" << endl;
   indent(out) << "protected void tupleSchemeWriteValue(org.apache.thrift.protocol.TProtocol oprot) "
                  "throws org.apache.thrift.TException {" << endl;
@@ -1290,7 +1290,7 @@ void t_java_generator::generate_tuple_scheme_write_value(ofstream& out, t_struct
   indent(out) << "}" << endl;
 }
 
-void t_java_generator::generate_get_field_desc(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_get_field_desc(ostream& out, t_struct* tstruct) {
   indent(out) << "@Override" << endl;
   indent(out) << "protected org.apache.thrift.protocol.TField getFieldDesc(_Fields setField) {"
               << endl;
@@ -1318,7 +1318,7 @@ void t_java_generator::generate_get_field_desc(ofstream& out, t_struct* tstruct)
   indent(out) << "}" << endl;
 }
 
-void t_java_generator::generate_get_struct_desc(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_get_struct_desc(ostream& out, t_struct* tstruct) {
   (void)tstruct;
   indent(out) << "@Override" << endl;
   indent(out) << "protected org.apache.thrift.protocol.TStruct getStructDesc() {" << endl;
@@ -1326,7 +1326,7 @@ void t_java_generator::generate_get_struct_desc(ofstream& out, t_struct* tstruct
   indent(out) << "}" << endl;
 }
 
-void t_java_generator::generate_union_comparisons(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_union_comparisons(ostream& out, t_struct* tstruct) {
   // equality
   indent(out) << "public boolean equals(java.lang.Object other) {" << endl;
   indent(out) << "  if (other instanceof " << tstruct->get_name() << ") {" << endl;
@@ -1357,7 +1357,7 @@ void t_java_generator::generate_union_comparisons(ofstream& out, t_struct* tstru
   out << endl;
 }
 
-void t_java_generator::generate_union_hashcode(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_union_hashcode(ostream& out, t_struct* tstruct) {
   (void)tstruct;
   indent(out) << "@Override" << endl;
   indent(out) << "public int hashCode() {" << endl;
@@ -1387,7 +1387,7 @@ void t_java_generator::generate_union_hashcode(ofstream& out, t_struct* tstruct)
  * @param in_class     If inside a class, needs to be static class
  * @param is_result    If this is a result it needs a different writer
  */
-void t_java_generator::generate_java_struct_definition(ofstream& out,
+void t_java_generator::generate_java_struct_definition(ostream& out,
                                                        t_struct* tstruct,
                                                        bool is_exception,
                                                        bool in_class,
@@ -1646,7 +1646,7 @@ void t_java_generator::generate_java_struct_definition(ofstream& out,
 /**
  * generates parcelable interface implementation
  */
-void t_java_generator::generate_java_struct_parcelable(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_struct_parcelable(ostream& out, t_struct* tstruct) {
   string tname = tstruct->get_name();
 
   const vector<t_field*>& members = tstruct->get_members();
@@ -1862,7 +1862,7 @@ void t_java_generator::generate_java_struct_parcelable(ofstream& out, t_struct*
  *
  * @param tstruct The struct definition
  */
-void t_java_generator::generate_java_struct_equality(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_struct_equality(ostream& out, t_struct* tstruct) {
   out << indent() << "@Override" << endl << indent() << "public boolean equals(java.lang.Object that) {"
       << endl;
   indent_up();
@@ -1993,7 +1993,7 @@ void t_java_generator::generate_java_struct_equality(ofstream& out, t_struct* ts
   indent(out) << "}" << endl << endl;
 }
 
-void t_java_generator::generate_java_struct_compare_to(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_struct_compare_to(ostream& out, t_struct* tstruct) {
   indent(out) << "@Override" << endl;
   indent(out) << "public int compareTo(" << type_name(tstruct) << " other) {" << endl;
   indent_up();
@@ -2036,7 +2036,7 @@ void t_java_generator::generate_java_struct_compare_to(ofstream& out, t_struct*
  *
  * @param tstruct The struct definition
  */
-void t_java_generator::generate_java_struct_reader(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_struct_reader(ostream& out, t_struct* tstruct) {
   (void)tstruct;
   indent(out) << "public void read(org.apache.thrift.protocol.TProtocol iprot) throws "
                  "org.apache.thrift.TException {" << endl;
@@ -2048,7 +2048,7 @@ void t_java_generator::generate_java_struct_reader(ofstream& out, t_struct* tstr
 
 // generates java method to perform various checks
 // (e.g. check that all required fields are set)
-void t_java_generator::generate_java_validator(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_validator(ostream& out, t_struct* tstruct) {
   indent(out) << "public void validate() throws org.apache.thrift.TException {" << endl;
   indent_up();
 
@@ -2098,7 +2098,7 @@ void t_java_generator::generate_java_validator(ofstream& out, t_struct* tstruct)
  *
  * @param tstruct The struct definition
  */
-void t_java_generator::generate_java_struct_writer(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_struct_writer(ostream& out, t_struct* tstruct) {
   (void)tstruct;
   indent(out) << "public void write(org.apache.thrift.protocol.TProtocol oprot) throws "
                  "org.apache.thrift.TException {" << endl;
@@ -2117,7 +2117,7 @@ void t_java_generator::generate_java_struct_writer(ofstream& out, t_struct* tstr
  *
  * @param tstruct The struct definition
  */
-void t_java_generator::generate_java_struct_result_writer(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_struct_result_writer(ostream& out, t_struct* tstruct) {
   (void)tstruct;
   indent(out) << "public void write(org.apache.thrift.protocol.TProtocol oprot) throws "
                  "org.apache.thrift.TException {" << endl;
@@ -2128,7 +2128,7 @@ void t_java_generator::generate_java_struct_result_writer(ofstream& out, t_struc
   indent(out) << "  }" << endl << endl;
 }
 
-void t_java_generator::generate_java_struct_field_by_id(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_struct_field_by_id(ostream& out, t_struct* tstruct) {
   (void)tstruct;
   indent(out) << java_nullable_annotation() << endl;
   indent(out) << "public _Fields fieldForId(int fieldId) {" << endl;
@@ -2173,7 +2173,7 @@ void t_java_generator::generate_reflection_setters(ostringstream& out,
   indent_down();
 }
 
-void t_java_generator::generate_generic_field_getters_setters(std::ofstream& out,
+void t_java_generator::generate_generic_field_getters_setters(std::ostream& out,
                                                               t_struct* tstruct) {
   std::ostringstream getter_stream;
   std::ostringstream setter_stream;
@@ -2215,7 +2215,7 @@ void t_java_generator::generate_generic_field_getters_setters(std::ofstream& out
 }
 
 // Creates a generic isSet method that takes the field number as argument
-void t_java_generator::generate_generic_isset_method(std::ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_generic_isset_method(std::ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
@@ -2250,7 +2250,7 @@ void t_java_generator::generate_generic_isset_method(std::ofstream& out, t_struc
  *
  * @param tstruct The struct definition
  */
-void t_java_generator::generate_java_bean_boilerplate(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_bean_boilerplate(ostream& out, t_struct* tstruct) {
   isset_type issetType = needs_isset(tstruct);
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
@@ -2564,7 +2564,7 @@ void t_java_generator::generate_java_bean_boilerplate(ofstream& out, t_struct* t
  *
  * @param tstruct The struct definition
  */
-void t_java_generator::generate_java_struct_tostring(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_struct_tostring(ostream& out, t_struct* tstruct) {
   out << indent() << "@Override" << endl << indent() << "public java.lang.String toString() {" << endl;
   indent_up();
 
@@ -2635,7 +2635,7 @@ void t_java_generator::generate_java_struct_tostring(ofstream& out, t_struct* ts
  *
  * @param tstruct The struct definition
  */
-void t_java_generator::generate_java_meta_data_map(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_meta_data_map(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
@@ -2736,7 +2736,7 @@ std::string t_java_generator::get_java_type_string(t_type* type) {
   }
 }
 
-void t_java_generator::generate_field_value_meta_data(std::ofstream& out, t_type* type) {
+void t_java_generator::generate_field_value_meta_data(std::ostream& out, t_type* type) {
   out << endl;
   indent_up();
   indent_up();
@@ -3685,7 +3685,7 @@ void t_java_generator::generate_process_function(t_service* tservice, t_function
  * @param tfield The field
  * @param prefix The variable name or container for this field
  */
-void t_java_generator::generate_deserialize_field(ofstream& out,
+void t_java_generator::generate_deserialize_field(ostream& out,
                                                   t_field* tfield,
                                                   string prefix,
                                                   bool has_metadata) {
@@ -3752,7 +3752,7 @@ void t_java_generator::generate_deserialize_field(ofstream& out,
 /**
  * Generates an unserializer for a struct, invokes read()
  */
-void t_java_generator::generate_deserialize_struct(ofstream& out,
+void t_java_generator::generate_deserialize_struct(ostream& out,
                                                    t_struct* tstruct,
                                                    string prefix) {
 
@@ -3771,7 +3771,7 @@ void t_java_generator::generate_deserialize_struct(ofstream& out,
 /**
  * Deserializes a container by reading its size and then iterating
  */
-void t_java_generator::generate_deserialize_container(ofstream& out,
+void t_java_generator::generate_deserialize_container(ostream& out,
                                                       t_type* ttype,
                                                       string prefix,
                                                       bool has_metadata) {
@@ -3874,7 +3874,7 @@ void t_java_generator::generate_deserialize_container(ofstream& out,
 /**
  * Generates code to deserialize a map
  */
-void t_java_generator::generate_deserialize_map_element(ofstream& out,
+void t_java_generator::generate_deserialize_map_element(ostream& out,
                                                         t_map* tmap,
                                                         string prefix,
                                                         string obj,
@@ -3921,7 +3921,7 @@ void t_java_generator::generate_deserialize_map_element(ofstream& out,
 /**
  * Deserializes a set element
  */
-void t_java_generator::generate_deserialize_set_element(ofstream& out,
+void t_java_generator::generate_deserialize_set_element(ostream& out,
                                                         t_set* tset,
                                                         string prefix,
                                                         string obj,
@@ -3959,7 +3959,7 @@ void t_java_generator::generate_deserialize_set_element(ofstream& out,
 /**
  * Deserializes a list element
  */
-void t_java_generator::generate_deserialize_list_element(ofstream& out,
+void t_java_generator::generate_deserialize_list_element(ostream& out,
                                                          t_list* tlist,
                                                          string prefix,
                                                          string obj,
@@ -4000,7 +4000,7 @@ void t_java_generator::generate_deserialize_list_element(ofstream& out,
  * @param tfield The field to serialize
  * @param prefix Name to prepend to field name
  */
-void t_java_generator::generate_serialize_field(ofstream& out,
+void t_java_generator::generate_serialize_field(ostream& out,
                                                 t_field* tfield,
                                                 string prefix,
                                                 bool has_metadata) {
@@ -4073,7 +4073,7 @@ void t_java_generator::generate_serialize_field(ofstream& out,
  * @param tstruct The struct to serialize
  * @param prefix  String prefix to attach to all fields
  */
-void t_java_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_java_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   (void)tstruct;
   out << indent() << prefix << ".write(oprot);" << endl;
 }
@@ -4084,7 +4084,7 @@ void t_java_generator::generate_serialize_struct(ofstream& out, t_struct* tstruc
  * @param ttype  The type of container
  * @param prefix String prefix for fields
  */
-void t_java_generator::generate_serialize_container(ofstream& out,
+void t_java_generator::generate_serialize_container(ostream& out,
                                                     t_type* ttype,
                                                     string prefix,
                                                     bool has_metadata) {
@@ -4149,7 +4149,7 @@ void t_java_generator::generate_serialize_container(ofstream& out,
 /**
  * Serializes the members of a map.
  */
-void t_java_generator::generate_serialize_map_element(ofstream& out,
+void t_java_generator::generate_serialize_map_element(ostream& out,
                                                       t_map* tmap,
                                                       string iter,
                                                       string map,
@@ -4164,7 +4164,7 @@ void t_java_generator::generate_serialize_map_element(ofstream& out,
 /**
  * Serializes the members of a set.
  */
-void t_java_generator::generate_serialize_set_element(ofstream& out,
+void t_java_generator::generate_serialize_set_element(ostream& out,
                                                       t_set* tset,
                                                       string iter,
                                                       bool has_metadata) {
@@ -4175,7 +4175,7 @@ void t_java_generator::generate_serialize_set_element(ofstream& out,
 /**
  * Serializes the members of a list.
  */
-void t_java_generator::generate_serialize_list_element(ofstream& out,
+void t_java_generator::generate_serialize_list_element(ostream& out,
                                                        t_list* tlist,
                                                        string iter,
                                                        bool has_metadata) {
@@ -4303,7 +4303,7 @@ string t_java_generator::declare_field(t_field* tfield, bool init, bool comment)
   result += type_name(tfield->get_type()) + " " + tfield->get_name();
   if (init) {
     if (ttype->is_base_type() && tfield->get_value() != NULL) {
-      ofstream dummy;
+      std::ofstream dummy;
       result += " = " + render_const_value(dummy, ttype, tfield->get_value());
     } else if (ttype->is_base_type()) {
       t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base();
@@ -4619,7 +4619,7 @@ string t_java_generator::constant_name(string name) {
   return constant_name;
 }
 
-void t_java_generator::generate_deep_copy_container(ofstream& out,
+void t_java_generator::generate_deep_copy_container(ostream& out,
                                                     std::string source_name_p1,
                                                     std::string source_name_p2,
                                                     std::string result_name,
@@ -4769,7 +4769,7 @@ void t_java_generator::generate_deep_copy_container(ofstream& out,
   }
 }
 
-void t_java_generator::generate_deep_copy_non_container(ofstream& out,
+void t_java_generator::generate_deep_copy_non_container(ostream& out,
                                                         std::string source_name,
                                                         std::string dest_name,
                                                         t_type* type) {
@@ -4799,19 +4799,19 @@ std::string t_java_generator::generate_isset_check(std::string field_name) {
   return "is" + get_cap_name("set") + get_cap_name(field_name) + "()";
 }
 
-void t_java_generator::generate_isset_set(ofstream& out, t_field* field, string prefix) {
+void t_java_generator::generate_isset_set(ostream& out, t_field* field, string prefix) {
   if (!type_can_be_null(field->get_type())) {
     indent(out) << prefix << "set" << get_cap_name(field->get_name()) << get_cap_name("isSet")
                 << "(true);" << endl;
   }
 }
 
-void t_java_generator::generate_struct_desc(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_struct_desc(ostream& out, t_struct* tstruct) {
   indent(out) << "private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new "
                  "org.apache.thrift.protocol.TStruct(\"" << tstruct->get_name() << "\");" << endl;
 }
 
-void t_java_generator::generate_field_descs(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_field_descs(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& members = tstruct->get_members();
   vector<t_field*>::const_iterator m_iter;
 
@@ -4824,14 +4824,14 @@ void t_java_generator::generate_field_descs(ofstream& out, t_struct* tstruct) {
   }
 }
 
-void t_java_generator::generate_scheme_map(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_scheme_map(ostream& out, t_struct* tstruct) {
   indent(out) << "private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new "
       << tstruct->get_name() << "StandardSchemeFactory();" << endl;
   indent(out) << "private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new "
       << tstruct->get_name() << "TupleSchemeFactory();" << endl;
 }
 
-void t_java_generator::generate_field_name_constants(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_field_name_constants(ostream& out, t_struct* tstruct) {
   indent(out) << "/** The set of fields this struct contains, along with convenience methods for "
                  "finding and manipulating them. */" << endl;
   indent(out) << "public enum _Fields implements org.apache.thrift.TFieldIdEnum {" << endl;
@@ -4959,7 +4959,7 @@ t_java_generator::isset_type t_java_generator::needs_isset(t_struct* tstruct,
   }
 }
 
-void t_java_generator::generate_java_struct_clear(std::ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_struct_clear(std::ostream& out, t_struct* tstruct) {
   if (!java5_) {
     indent(out) << "@Override" << endl;
   }
@@ -5023,7 +5023,7 @@ void t_java_generator::generate_java_struct_clear(std::ofstream& out, t_struct*
 }
 
 // generates java method to serialize (in the Java sense) the object
-void t_java_generator::generate_java_struct_write_object(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_struct_write_object(ostream& out, t_struct* tstruct) {
   (void)tstruct;
   indent(out)
       << "private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {"
@@ -5039,7 +5039,7 @@ void t_java_generator::generate_java_struct_write_object(ofstream& out, t_struct
 }
 
 // generates java method to serialize (in the Java sense) the object
-void t_java_generator::generate_java_struct_read_object(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_struct_read_object(ostream& out, t_struct* tstruct) {
   indent(out) << "private void readObject(java.io.ObjectInputStream in) throws "
                  "java.io.IOException, java.lang.ClassNotFoundException {" << endl;
   indent(out) << "  try {" << endl;
@@ -5068,7 +5068,7 @@ void t_java_generator::generate_java_struct_read_object(ofstream& out, t_struct*
   indent(out) << "}" << endl << endl;
 }
 
-void t_java_generator::generate_standard_reader(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_standard_reader(ostream& out, t_struct* tstruct) {
   out << indent() << "public void read(org.apache.thrift.protocol.TProtocol iprot, "
       << tstruct->get_name() << " struct) throws org.apache.thrift.TException {" << endl;
   indent_up();
@@ -5158,7 +5158,7 @@ void t_java_generator::generate_standard_reader(ofstream& out, t_struct* tstruct
   out << indent() << "}" << endl;
 }
 
-void t_java_generator::generate_standard_writer(ofstream& out, t_struct* tstruct, bool is_result) {
+void t_java_generator::generate_standard_writer(ostream& out, t_struct* tstruct, bool is_result) {
   indent_up();
   out << indent() << "public void write(org.apache.thrift.protocol.TProtocol oprot, "
       << tstruct->get_name() << " struct) throws org.apache.thrift.TException {" << endl;
@@ -5211,7 +5211,7 @@ void t_java_generator::generate_standard_writer(ofstream& out, t_struct* tstruct
   indent_down();
 }
 
-void t_java_generator::generate_java_struct_standard_scheme(ofstream& out,
+void t_java_generator::generate_java_struct_standard_scheme(ostream& out,
                                                             t_struct* tstruct,
                                                             bool is_result) {
   indent(out) << "private static class " << tstruct->get_name()
@@ -5236,7 +5236,7 @@ void t_java_generator::generate_java_struct_standard_scheme(ofstream& out,
   out << indent() << "}" << endl << endl;
 }
 
-void t_java_generator::generate_java_struct_tuple_reader(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_struct_tuple_reader(ostream& out, t_struct* tstruct) {
   indent(out) << "@Override" << endl;
   indent(out) << "public void read(org.apache.thrift.protocol.TProtocol prot, "
               << tstruct->get_name() << " struct) throws org.apache.thrift.TException {" << endl;
@@ -5277,7 +5277,7 @@ void t_java_generator::generate_java_struct_tuple_reader(ofstream& out, t_struct
   indent(out) << "}" << endl;
 }
 
-void t_java_generator::generate_java_struct_tuple_writer(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_struct_tuple_writer(ostream& out, t_struct* tstruct) {
   indent(out) << "@Override" << endl;
   indent(out) << "public void write(org.apache.thrift.protocol.TProtocol prot, "
               << tstruct->get_name() << " struct) throws org.apache.thrift.TException {" << endl;
@@ -5331,7 +5331,7 @@ void t_java_generator::generate_java_struct_tuple_writer(ofstream& out, t_struct
   indent(out) << "}" << endl;
 }
 
-void t_java_generator::generate_java_struct_tuple_scheme(ofstream& out, t_struct* tstruct) {
+void t_java_generator::generate_java_struct_tuple_scheme(ostream& out, t_struct* tstruct) {
   indent(out) << "private static class " << tstruct->get_name()
               << "TupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {" << endl;
   indent_up();
@@ -5352,7 +5352,7 @@ void t_java_generator::generate_java_struct_tuple_scheme(ofstream& out, t_struct
   out << indent() << "}" << endl << endl;
 }
 
-void t_java_generator::generate_java_scheme_lookup(ofstream& out) {
+void t_java_generator::generate_java_scheme_lookup(ostream& out) {
   indent(out) << "private static <S extends org.apache.thrift.scheme.IScheme> S scheme("
       << "org.apache.thrift.protocol.TProtocol proto) {" << endl;
   indent_up();
@@ -5364,7 +5364,7 @@ void t_java_generator::generate_java_scheme_lookup(ofstream& out) {
   indent(out) << "}" << endl;
 }
 
-void t_java_generator::generate_javax_generated_annotation(ofstream& out) {
+void t_java_generator::generate_javax_generated_annotation(ostream& out) {
   time_t seconds = time(NULL);
   struct tm* now = localtime(&seconds);
   indent(out) << "@javax.annotation.Generated(value = \"" << autogen_summary() << "\"";
diff --git a/compiler/cpp/src/thrift/generate/t_javame_generator.cc b/compiler/cpp/src/thrift/generate/t_javame_generator.cc
index 0f4181dc3b..fa743ca3d3 100644
--- a/compiler/cpp/src/thrift/generate/t_javame_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_javame_generator.cc
@@ -31,7 +31,7 @@
 #include "thrift/generate/t_oop_generator.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -81,13 +81,13 @@ class t_javame_generator : public t_oop_generator {
   void generate_xception(t_struct* txception);
   void generate_service(t_service* tservice);
 
-  void print_const_value(std::ofstream& out,
+  void print_const_value(std::ostream& out,
                          std::string name,
                          t_type* type,
                          t_const_value* value,
                          bool in_static,
                          bool defval = false);
-  std::string render_const_value(std::ofstream& out,
+  std::string render_const_value(std::ostream& out,
                                  std::string name,
                                  t_type* type,
                                  t_const_value* value);
@@ -98,20 +98,20 @@ class t_javame_generator : public t_oop_generator {
 
   void generate_java_struct(t_struct* tstruct, bool is_exception);
 
-  void generate_java_struct_definition(std::ofstream& out,
+  void generate_java_struct_definition(std::ostream& out,
                                        t_struct* tstruct,
                                        bool is_xception = false,
                                        bool in_class = false,
                                        bool is_result = false);
-  void generate_java_struct_equality(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_compare_to(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_reader(std::ofstream& out, t_struct* tstruct);
-  void generate_java_validator(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_result_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_tostring(std::ofstream& out, t_struct* tstruct);
-  void generate_java_struct_clear(std::ofstream& out, t_struct* tstruct);
-  void generate_field_value_meta_data(std::ofstream& out, t_type* type);
+  void generate_java_struct_equality(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_compare_to(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_reader(std::ostream& out, t_struct* tstruct);
+  void generate_java_validator(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_result_writer(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_writer(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_tostring(std::ostream& out, t_struct* tstruct);
+  void generate_java_struct_clear(std::ostream& out, t_struct* tstruct);
+  void generate_field_value_meta_data(std::ostream& out, t_type* type);
   std::string get_java_type_string(t_type* type);
   void generate_reflection_setters(std::ostringstream& out,
                                    t_type* type,
@@ -121,14 +121,14 @@ class t_javame_generator : public t_oop_generator {
                                    t_type* type,
                                    std::string field_name,
                                    std::string cap_name);
-  void generate_generic_field_getters_setters(std::ofstream& out, t_struct* tstruct);
-  void generate_java_bean_boilerplate(std::ofstream& out, t_struct* tstruct);
+  void generate_generic_field_getters_setters(std::ostream& out, t_struct* tstruct);
+  void generate_java_bean_boilerplate(std::ostream& out, t_struct* tstruct);
 
   void generate_function_helpers(t_function* tfunction);
   std::string get_cap_name(std::string name);
   std::string generate_isset_check(t_field* field);
   std::string generate_isset_check(std::string field);
-  void generate_isset_set(ofstream& out, t_field* field);
+  void generate_isset_set(ostream& out, t_field* field);
   std::string isset_field_id(t_field* field);
 
   void generate_primitive_service_interface(t_service* tservice);
@@ -139,66 +139,66 @@ class t_javame_generator : public t_oop_generator {
   void generate_process_function(t_service* tservice, t_function* tfunction);
 
   void generate_java_union(t_struct* tstruct);
-  void generate_union_constructor(ofstream& out, t_struct* tstruct);
-  void generate_union_getters_and_setters(ofstream& out, t_struct* tstruct);
-  void generate_union_abstract_methods(ofstream& out, t_struct* tstruct);
-  void generate_check_type(ofstream& out, t_struct* tstruct);
-  void generate_read_value(ofstream& out, t_struct* tstruct);
-  void generate_write_value(ofstream& out, t_struct* tstruct);
-  void generate_get_field_desc(ofstream& out, t_struct* tstruct);
-  void generate_get_struct_desc(ofstream& out, t_struct* tstruct);
-  void generate_get_field_name(ofstream& out, t_struct* tstruct);
-
-  void generate_union_comparisons(ofstream& out, t_struct* tstruct);
-  void generate_union_hashcode(ofstream& out, t_struct* tstruct);
+  void generate_union_constructor(ostream& out, t_struct* tstruct);
+  void generate_union_getters_and_setters(ostream& out, t_struct* tstruct);
+  void generate_union_abstract_methods(ostream& out, t_struct* tstruct);
+  void generate_check_type(ostream& out, t_struct* tstruct);
+  void generate_read_value(ostream& out, t_struct* tstruct);
+  void generate_write_value(ostream& out, t_struct* tstruct);
+  void generate_get_field_desc(ostream& out, t_struct* tstruct);
+  void generate_get_struct_desc(ostream& out, t_struct* tstruct);
+  void generate_get_field_name(ostream& out, t_struct* tstruct);
+
+  void generate_union_comparisons(ostream& out, t_struct* tstruct);
+  void generate_union_hashcode(ostream& out, t_struct* tstruct);
 
   /**
    * Serialization constructs
    */
 
-  void generate_deserialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
+  void generate_deserialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
 
-  void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
+  void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
 
-  void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
+  void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
 
-  void generate_deserialize_list_element(std::ofstream& out,
+  void generate_deserialize_list_element(std::ostream& out,
                                          t_list* tlist,
                                          std::string prefix = "");
 
-  void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
+  void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
 
-  void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_serialize_map_element(std::ofstream& out,
+  void generate_serialize_map_element(std::ostream& out,
                                       t_map* tmap,
                                       std::string iter,
                                       std::string map);
 
-  void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
+  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
 
-  void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
+  void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
 
-  void generate_java_doc(std::ofstream& out, t_field* field);
+  void generate_java_doc(std::ostream& out, t_field* field);
 
-  void generate_java_doc(std::ofstream& out, t_doc* tdoc);
+  void generate_java_doc(std::ostream& out, t_doc* tdoc);
 
-  void generate_java_doc(std::ofstream& out, t_function* tdoc);
+  void generate_java_doc(std::ostream& out, t_function* tdoc);
 
-  void generate_java_docstring_comment(std::ofstream& out, string contents);
+  void generate_java_docstring_comment(std::ostream& out, string contents);
 
-  void generate_deep_copy_container(std::ofstream& out,
+  void generate_deep_copy_container(std::ostream& out,
                                     std::string source_name_p1,
                                     std::string source_name_p2,
                                     std::string result_name,
                                     t_type* type);
-  void generate_deep_copy_non_container(std::ofstream& out,
+  void generate_deep_copy_non_container(std::ostream& out,
                                         std::string source_name,
                                         std::string dest_name,
                                         t_type* type);
@@ -222,8 +222,8 @@ class t_javame_generator : public t_oop_generator {
   std::string argument_list(t_struct* tstruct, bool include_types = true);
   std::string type_to_enum(t_type* ttype);
   std::string get_enum_class_name(t_type* type);
-  void generate_struct_desc(ofstream& out, t_struct* tstruct);
-  void generate_field_descs(ofstream& out, t_struct* tstruct);
+  void generate_struct_desc(ostream& out, t_struct* tstruct);
+  void generate_field_descs(ostream& out, t_struct* tstruct);
   std::string box_type(t_type* type, string value);
 
   bool type_can_be_null(t_type* ttype) {
@@ -241,7 +241,7 @@ class t_javame_generator : public t_oop_generator {
    */
 
   std::string package_name_;
-  std::ofstream f_service_;
+  ofstream_with_content_based_conditional_update f_service_;
   std::string package_dir_;
 };
 
@@ -329,7 +329,7 @@ void t_javame_generator::generate_typedef(t_typedef* ttypedef) {
 void t_javame_generator::generate_enum(t_enum* tenum) {
   // Make output file
   string f_enum_name = package_dir_ + "/" + (tenum->get_name()) + ".java";
-  ofstream f_enum;
+  ofstream_with_content_based_conditional_update f_enum;
   f_enum.open(f_enum_name.c_str());
 
   // Comment and package it
@@ -408,7 +408,7 @@ void t_javame_generator::generate_consts(std::vector<t_const*> consts) {
   }
 
   string f_consts_name = package_dir_ + "/" + program_name_ + "Constants.java";
-  ofstream f_consts;
+  ofstream_with_content_based_conditional_update f_consts;
   f_consts.open(f_consts_name.c_str());
 
   // Print header
@@ -434,7 +434,7 @@ void t_javame_generator::generate_consts(std::vector<t_const*> consts) {
  * is NOT performed in this function as it is always run beforehand using the
  * validate_types method in main.cc
  */
-void t_javame_generator::print_const_value(std::ofstream& out,
+void t_javame_generator::print_const_value(std::ostream& out,
                                            string name,
                                            t_type* type,
                                            t_const_value* value,
@@ -535,7 +535,7 @@ void t_javame_generator::print_const_value(std::ofstream& out,
   }
 }
 
-string t_javame_generator::render_const_value(ofstream& out,
+string t_javame_generator::render_const_value(ostream& out,
                                               string name,
                                               t_type* type,
                                               t_const_value* value) {
@@ -638,7 +638,7 @@ void t_javame_generator::generate_xception(t_struct* txception) {
 void t_javame_generator::generate_java_struct(t_struct* tstruct, bool is_exception) {
   // Make output file
   string f_struct_name = package_dir_ + "/" + (tstruct->get_name()) + ".java";
-  ofstream f_struct;
+  ofstream_with_content_based_conditional_update f_struct;
   f_struct.open(f_struct_name.c_str());
 
   f_struct << autogen_comment() << java_package() << java_type_imports() << java_thrift_imports();
@@ -655,7 +655,7 @@ void t_javame_generator::generate_java_struct(t_struct* tstruct, bool is_excepti
 void t_javame_generator::generate_java_union(t_struct* tstruct) {
   // Make output file
   string f_struct_name = package_dir_ + "/" + (tstruct->get_name()) + ".java";
-  ofstream f_struct;
+  ofstream_with_content_based_conditional_update f_struct;
   f_struct.open(f_struct_name.c_str());
 
   f_struct << autogen_comment() << java_package() << java_type_imports() << java_thrift_imports();
@@ -699,7 +699,7 @@ void t_javame_generator::generate_java_union(t_struct* tstruct) {
   f_struct.close();
 }
 
-void t_javame_generator::generate_union_constructor(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_union_constructor(ostream& out, t_struct* tstruct) {
   indent(out) << "public " << type_name(tstruct) << "() {" << endl;
   indent(out) << "  super();" << endl;
   indent(out) << "}" << endl << endl;
@@ -730,7 +730,7 @@ void t_javame_generator::generate_union_constructor(ofstream& out, t_struct* tst
   }
 }
 
-void t_javame_generator::generate_union_getters_and_setters(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_union_getters_and_setters(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& members = tstruct->get_members();
   vector<t_field*>::const_iterator m_iter;
 
@@ -772,7 +772,7 @@ void t_javame_generator::generate_union_getters_and_setters(ofstream& out, t_str
   }
 }
 
-void t_javame_generator::generate_union_abstract_methods(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_union_abstract_methods(ostream& out, t_struct* tstruct) {
   generate_check_type(out, tstruct);
   out << endl;
   generate_read_value(out, tstruct);
@@ -785,7 +785,7 @@ void t_javame_generator::generate_union_abstract_methods(ofstream& out, t_struct
   out << endl;
 }
 
-void t_javame_generator::generate_check_type(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_check_type(ostream& out, t_struct* tstruct) {
   indent(out)
       << "protected void checkType(_Fields setField, Object value) throws ClassCastException {"
       << endl;
@@ -821,7 +821,7 @@ void t_javame_generator::generate_check_type(ofstream& out, t_struct* tstruct) {
   indent(out) << "}" << endl;
 }
 
-void t_javame_generator::generate_read_value(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_read_value(ostream& out, t_struct* tstruct) {
   indent(out) << "protected Object readValue(TProtocol iprot, TField field) throws TException {"
               << endl;
 
@@ -875,7 +875,7 @@ void t_javame_generator::generate_read_value(ofstream& out, t_struct* tstruct) {
   indent(out) << "}" << endl;
 }
 
-void t_javame_generator::generate_write_value(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_write_value(ostream& out, t_struct* tstruct) {
   indent(out) << "protected void writeValue(TProtocol oprot) throws TException {" << endl;
 
   indent_up();
@@ -910,7 +910,7 @@ void t_javame_generator::generate_write_value(ofstream& out, t_struct* tstruct)
   indent(out) << "}" << endl;
 }
 
-void t_javame_generator::generate_get_field_desc(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_get_field_desc(ostream& out, t_struct* tstruct) {
   indent(out) << "protected TField getFieldDesc(_Fields setField) {" << endl;
   indent_up();
 
@@ -936,14 +936,14 @@ void t_javame_generator::generate_get_field_desc(ofstream& out, t_struct* tstruc
   indent(out) << "}" << endl;
 }
 
-void t_javame_generator::generate_get_struct_desc(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_get_struct_desc(ostream& out, t_struct* tstruct) {
   (void)tstruct;
   indent(out) << "protected TStruct getStructDesc() {" << endl;
   indent(out) << "  return STRUCT_DESC;" << endl;
   indent(out) << "}" << endl;
 }
 
-void t_javame_generator::generate_union_comparisons(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_union_comparisons(ostream& out, t_struct* tstruct) {
   // equality
   indent(out) << "public boolean equals(Object other) {" << endl;
   indent(out) << "  if (other instanceof " << tstruct->get_name() << ") {" << endl;
@@ -973,7 +973,7 @@ void t_javame_generator::generate_union_comparisons(ofstream& out, t_struct* tst
   out << endl;
 }
 
-void t_javame_generator::generate_union_hashcode(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_union_hashcode(ostream& out, t_struct* tstruct) {
   (void)tstruct;
   indent(out) << "/**" << endl;
   indent(out)
@@ -995,7 +995,7 @@ void t_javame_generator::generate_union_hashcode(ofstream& out, t_struct* tstruc
  * @param in_class     If inside a class, needs to be static class
  * @param is_result    If this is a result it needs a different writer
  */
-void t_javame_generator::generate_java_struct_definition(ofstream& out,
+void t_javame_generator::generate_java_struct_definition(ostream& out,
                                                          t_struct* tstruct,
                                                          bool is_exception,
                                                          bool in_class,
@@ -1177,7 +1177,7 @@ void t_javame_generator::generate_java_struct_definition(ofstream& out,
  *
  * @param tstruct The struct definition
  */
-void t_javame_generator::generate_java_struct_equality(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_java_struct_equality(ostream& out, t_struct* tstruct) {
   out << indent() << "public boolean equals(Object that) {" << endl;
   indent_up();
   out << indent() << "if (that == null)" << endl << indent() << "  return false;" << endl
@@ -1246,7 +1246,7 @@ void t_javame_generator::generate_java_struct_equality(ofstream& out, t_struct*
   indent(out) << "}" << endl << endl;
 }
 
-void t_javame_generator::generate_java_struct_compare_to(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_java_struct_compare_to(ostream& out, t_struct* tstruct) {
   indent(out) << "public int compareTo(Object otherObject) {" << endl;
   //  indent(out) << "public int compareTo(" << type_name(tstruct) << " other) {" << endl;
   indent_up();
@@ -1297,7 +1297,7 @@ void t_javame_generator::generate_java_struct_compare_to(ofstream& out, t_struct
  *
  * @param tstruct The struct definition
  */
-void t_javame_generator::generate_java_struct_reader(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_java_struct_reader(ostream& out, t_struct* tstruct) {
   out << indent() << "public void read(TProtocol iprot) throws TException {" << endl;
   indent_up();
 
@@ -1365,7 +1365,7 @@ void t_javame_generator::generate_java_struct_reader(ofstream& out, t_struct* ts
 
 // generates java method to perform various checks
 // (e.g. check that all required fields are set)
-void t_javame_generator::generate_java_validator(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_java_validator(ostream& out, t_struct* tstruct) {
   indent(out) << "public void validate() throws TException {" << endl;
   indent_up();
 
@@ -1390,7 +1390,7 @@ void t_javame_generator::generate_java_validator(ofstream& out, t_struct* tstruc
  *
  * @param tstruct The struct definition
  */
-void t_javame_generator::generate_java_struct_writer(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_java_struct_writer(ostream& out, t_struct* tstruct) {
   out << indent() << "public void write(TProtocol oprot) throws TException {" << endl;
   indent_up();
 
@@ -1449,7 +1449,7 @@ void t_javame_generator::generate_java_struct_writer(ofstream& out, t_struct* ts
  *
  * @param tstruct The struct definition
  */
-void t_javame_generator::generate_java_struct_result_writer(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_java_struct_result_writer(ostream& out, t_struct* tstruct) {
   out << indent() << "public void write(TProtocol oprot) throws TException {" << endl;
   indent_up();
 
@@ -1527,7 +1527,7 @@ void t_javame_generator::generate_reflection_setters(ostringstream& out,
   indent_down();
 }
 
-void t_javame_generator::generate_generic_field_getters_setters(std::ofstream& out,
+void t_javame_generator::generate_generic_field_getters_setters(std::ostream& out,
                                                                 t_struct* tstruct) {
   (void)out;
   std::ostringstream getter_stream;
@@ -1555,7 +1555,7 @@ void t_javame_generator::generate_generic_field_getters_setters(std::ofstream& o
  *
  * @param tstruct The struct definition
  */
-void t_javame_generator::generate_java_bean_boilerplate(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_java_bean_boilerplate(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
   for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
@@ -1708,7 +1708,7 @@ void t_javame_generator::generate_java_bean_boilerplate(ofstream& out, t_struct*
  *
  * @param tstruct The struct definition
  */
-void t_javame_generator::generate_java_struct_tostring(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_java_struct_tostring(ostream& out, t_struct* tstruct) {
   out << indent() << "public String toString() {" << endl;
   indent_up();
 
@@ -1819,7 +1819,7 @@ std::string t_javame_generator::get_java_type_string(t_type* type) {
   }
 }
 
-void t_javame_generator::generate_field_value_meta_data(std::ofstream& out, t_type* type) {
+void t_javame_generator::generate_field_value_meta_data(std::ostream& out, t_type* type) {
   out << endl;
   indent_up();
   indent_up();
@@ -1894,7 +1894,7 @@ void t_javame_generator::generate_primitive_service_interface(t_service* tservic
              << endl << endl;
 
   string f_interface_name = package_dir_ + "/" + service_name_ + "Iface.java";
-  std::ofstream f_iface;
+  ofstream_with_content_based_conditional_update f_iface;
   f_iface.open(f_interface_name.c_str());
 
   string extends_iface = "";
@@ -2391,7 +2391,7 @@ void t_javame_generator::generate_process_function(t_service* tservice, t_functi
  * @param tfield The field
  * @param prefix The variable name or container for this field
  */
-void t_javame_generator::generate_deserialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_javame_generator::generate_deserialize_field(ostream& out, t_field* tfield, string prefix) {
   t_type* type = get_true_type(tfield->get_type());
 
   if (type->is_void()) {
@@ -2455,7 +2455,7 @@ void t_javame_generator::generate_deserialize_field(ofstream& out, t_field* tfie
 /**
  * Generates an unserializer for a struct, invokes read()
  */
-void t_javame_generator::generate_deserialize_struct(ofstream& out,
+void t_javame_generator::generate_deserialize_struct(ostream& out,
                                                      t_struct* tstruct,
                                                      string prefix) {
   out << indent() << prefix << " = new " << type_name(tstruct) << "();" << endl << indent()
@@ -2465,7 +2465,7 @@ void t_javame_generator::generate_deserialize_struct(ofstream& out,
 /**
  * Deserializes a container by reading its size and then iterating
  */
-void t_javame_generator::generate_deserialize_container(ofstream& out,
+void t_javame_generator::generate_deserialize_container(ostream& out,
                                                         t_type* ttype,
                                                         string prefix) {
   scope_up(out);
@@ -2527,7 +2527,7 @@ void t_javame_generator::generate_deserialize_container(ofstream& out,
 /**
  * Generates code to deserialize a map
  */
-void t_javame_generator::generate_deserialize_map_element(ofstream& out,
+void t_javame_generator::generate_deserialize_map_element(ostream& out,
                                                           t_map* tmap,
                                                           string prefix) {
   string key = tmp("_key");
@@ -2548,7 +2548,7 @@ void t_javame_generator::generate_deserialize_map_element(ofstream& out,
 /**
  * Deserializes a set element
  */
-void t_javame_generator::generate_deserialize_set_element(ofstream& out,
+void t_javame_generator::generate_deserialize_set_element(ostream& out,
                                                           t_set* tset,
                                                           string prefix) {
   string elem = tmp("_elem");
@@ -2565,7 +2565,7 @@ void t_javame_generator::generate_deserialize_set_element(ofstream& out,
 /**
  * Deserializes a list element
  */
-void t_javame_generator::generate_deserialize_list_element(ofstream& out,
+void t_javame_generator::generate_deserialize_list_element(ostream& out,
                                                            t_list* tlist,
                                                            string prefix) {
   string elem = tmp("_elem");
@@ -2584,7 +2584,7 @@ void t_javame_generator::generate_deserialize_list_element(ofstream& out,
  * @param tfield The field to serialize
  * @param prefix Name to prepend to field name
  */
-void t_javame_generator::generate_serialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_javame_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix) {
   t_type* type = get_true_type(tfield->get_type());
 
   // Do nothing for void types
@@ -2654,7 +2654,7 @@ void t_javame_generator::generate_serialize_field(ofstream& out, t_field* tfield
  * @param tstruct The struct to serialize
  * @param prefix  String prefix to attach to all fields
  */
-void t_javame_generator::generate_serialize_struct(ofstream& out,
+void t_javame_generator::generate_serialize_struct(ostream& out,
                                                    t_struct* tstruct,
                                                    string prefix) {
   (void)tstruct;
@@ -2667,7 +2667,7 @@ void t_javame_generator::generate_serialize_struct(ofstream& out,
  * @param ttype  The type of container
  * @param prefix String prefix for fields
  */
-void t_javame_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_javame_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
   scope_up(out);
 
   if (ttype->is_map()) {
@@ -2733,7 +2733,7 @@ void t_javame_generator::generate_serialize_container(ofstream& out, t_type* tty
 /**
  * Serializes the members of a map.
  */
-void t_javame_generator::generate_serialize_map_element(ofstream& out,
+void t_javame_generator::generate_serialize_map_element(ostream& out,
                                                         t_map* tmap,
                                                         string iter,
                                                         string map) {
@@ -2747,7 +2747,7 @@ void t_javame_generator::generate_serialize_map_element(ofstream& out,
 /**
  * Serializes the members of a set.
  */
-void t_javame_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
+void t_javame_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
   t_field efield(tset->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "");
 }
@@ -2755,7 +2755,7 @@ void t_javame_generator::generate_serialize_set_element(ofstream& out, t_set* ts
 /**
  * Serializes the members of a list.
  */
-void t_javame_generator::generate_serialize_list_element(ofstream& out,
+void t_javame_generator::generate_serialize_list_element(ostream& out,
                                                          t_list* tlist,
                                                          string iter) {
   t_field efield(tlist->get_elem_type(), iter);
@@ -2847,7 +2847,7 @@ string t_javame_generator::declare_field(t_field* tfield, bool init) {
   if (init) {
     t_type* ttype = get_true_type(tfield->get_type());
     if (ttype->is_base_type() && tfield->get_value() != NULL) {
-      ofstream dummy;
+      std::ofstream dummy;
       result += " = " + render_const_value(dummy, tfield->get_name(), ttype, tfield->get_value());
     } else if (ttype->is_base_type()) {
       t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base();
@@ -2997,11 +2997,11 @@ string t_javame_generator::constant_name(string name) {
   return constant_name;
 }
 
-void t_javame_generator::generate_java_docstring_comment(ofstream& out, string contents) {
+void t_javame_generator::generate_java_docstring_comment(ostream& out, string contents) {
   generate_docstring_comment(out, "/**\n", " * ", contents, " */\n");
 }
 
-void t_javame_generator::generate_java_doc(ofstream& out, t_field* field) {
+void t_javame_generator::generate_java_doc(ostream& out, t_field* field) {
   if (field->get_type()->is_enum()) {
     string combined_message = field->get_doc() + "\n@see " + get_enum_class_name(field->get_type());
     generate_java_docstring_comment(out, combined_message);
@@ -3013,7 +3013,7 @@ void t_javame_generator::generate_java_doc(ofstream& out, t_field* field) {
 /**
  * Emits a JavaDoc comment if the provided object has a doc in Thrift
  */
-void t_javame_generator::generate_java_doc(ofstream& out, t_doc* tdoc) {
+void t_javame_generator::generate_java_doc(ostream& out, t_doc* tdoc) {
   if (tdoc->has_doc()) {
     generate_java_docstring_comment(out, tdoc->get_doc());
   }
@@ -3022,7 +3022,7 @@ void t_javame_generator::generate_java_doc(ofstream& out, t_doc* tdoc) {
 /**
  * Emits a JavaDoc comment if the provided function object has a doc in Thrift
  */
-void t_javame_generator::generate_java_doc(ofstream& out, t_function* tfunction) {
+void t_javame_generator::generate_java_doc(ostream& out, t_function* tfunction) {
   if (tfunction->has_doc()) {
     stringstream ss;
     ss << tfunction->get_doc();
@@ -3039,7 +3039,7 @@ void t_javame_generator::generate_java_doc(ofstream& out, t_function* tfunction)
   }
 }
 
-void t_javame_generator::generate_deep_copy_container(ofstream& out,
+void t_javame_generator::generate_deep_copy_container(ostream& out,
                                                       std::string source_name_p1,
                                                       std::string source_name_p2,
                                                       std::string result_name,
@@ -3169,7 +3169,7 @@ void t_javame_generator::generate_deep_copy_container(ofstream& out,
   }
 }
 
-void t_javame_generator::generate_deep_copy_non_container(ofstream& out,
+void t_javame_generator::generate_deep_copy_non_container(ostream& out,
                                                           std::string source_name,
                                                           std::string dest_name,
                                                           t_type* type) {
@@ -3200,7 +3200,7 @@ std::string t_javame_generator::generate_isset_check(std::string field_name) {
   return "is" + get_cap_name("set") + get_cap_name(field_name) + "()";
 }
 
-void t_javame_generator::generate_isset_set(ofstream& out, t_field* field) {
+void t_javame_generator::generate_isset_set(ostream& out, t_field* field) {
   if (!type_can_be_null(field->get_type())) {
     indent(out) << "set" << get_cap_name(field->get_name()) << get_cap_name("isSet") << "(true);"
                 << endl;
@@ -3216,12 +3216,12 @@ std::string t_javame_generator::get_enum_class_name(t_type* type) {
   return package + type->get_name();
 }
 
-void t_javame_generator::generate_struct_desc(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_struct_desc(ostream& out, t_struct* tstruct) {
   indent(out) << "private static final TStruct STRUCT_DESC = new TStruct(\"" << tstruct->get_name()
               << "\");" << endl;
 }
 
-void t_javame_generator::generate_field_descs(ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_field_descs(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& members = tstruct->get_members();
   vector<t_field*>::const_iterator m_iter;
 
@@ -3245,7 +3245,7 @@ bool t_javame_generator::has_bit_vector(t_struct* tstruct) {
   return false;
 }
 
-void t_javame_generator::generate_java_struct_clear(std::ofstream& out, t_struct* tstruct) {
+void t_javame_generator::generate_java_struct_clear(std::ostream& out, t_struct* tstruct) {
   indent(out) << "public void clear() {" << endl;
 
   const vector<t_field*>& members = tstruct->get_members();
diff --git a/compiler/cpp/src/thrift/generate/t_js_generator.cc b/compiler/cpp/src/thrift/generate/t_js_generator.cc
index 7d160b9119..6f73c1c352 100644
--- a/compiler/cpp/src/thrift/generate/t_js_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_js_generator.cc
@@ -34,7 +34,7 @@
 #include "thrift/version.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -135,12 +135,12 @@ class t_js_generator : public t_oop_generator {
    * Structs!
    */
   void generate_js_struct(t_struct* tstruct, bool is_exception);
-  void generate_js_struct_definition(std::ofstream& out,
+  void generate_js_struct_definition(std::ostream& out,
                                      t_struct* tstruct,
                                      bool is_xception = false,
                                      bool is_exported = true);
-  void generate_js_struct_reader(std::ofstream& out, t_struct* tstruct);
-  void generate_js_struct_writer(std::ofstream& out, t_struct* tstruct);
+  void generate_js_struct_reader(std::ostream& out, t_struct* tstruct);
+  void generate_js_struct_writer(std::ostream& out, t_struct* tstruct);
   void generate_js_function_helpers(t_function* tfunction);
 
   /**
@@ -157,37 +157,37 @@ class t_js_generator : public t_oop_generator {
    * Serialization constructs
    */
 
-  void generate_deserialize_field(std::ofstream& out,
+  void generate_deserialize_field(std::ostream& out,
                                   t_field* tfield,
                                   std::string prefix = "",
                                   bool inclass = false);
 
-  void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
+  void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
 
-  void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
+  void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
 
-  void generate_deserialize_list_element(std::ofstream& out,
+  void generate_deserialize_list_element(std::ostream& out,
                                          t_list* tlist,
                                          std::string prefix = "");
 
-  void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
+  void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
 
-  void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_serialize_map_element(std::ofstream& out,
+  void generate_serialize_map_element(std::ostream& out,
                                       t_map* tmap,
                                       std::string kiter,
                                       std::string viter);
 
-  void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
+  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
 
-  void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
+  void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
 
   /**
    * Helper rendering functions
@@ -354,10 +354,10 @@ class t_js_generator : public t_oop_generator {
   /**
    * File streams
    */
-  std::ofstream f_types_;
-  std::ofstream f_service_;
-  std::ofstream f_types_ts_;
-  std::ofstream f_service_ts_;
+  ofstream_with_content_based_conditional_update f_types_;
+  ofstream_with_content_based_conditional_update f_service_;
+  ofstream_with_content_based_conditional_update f_types_ts_;
+  ofstream_with_content_based_conditional_update f_service_ts_;
 };
 
 /**
@@ -686,7 +686,7 @@ t_type* t_js_generator::get_contained_type(t_type* t) {
  *
  * @param tstruct The struct definition
  */
-void t_js_generator::generate_js_struct_definition(ofstream& out,
+void t_js_generator::generate_js_struct_definition(ostream& out,
                                                    t_struct* tstruct,
                                                    bool is_exception,
                                                    bool is_exported) {
@@ -848,7 +848,7 @@ void t_js_generator::generate_js_struct_definition(ofstream& out,
 /**
  * Generates the read() method for a struct
  */
-void t_js_generator::generate_js_struct_reader(ofstream& out, t_struct* tstruct) {
+void t_js_generator::generate_js_struct_reader(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
@@ -927,7 +927,7 @@ void t_js_generator::generate_js_struct_reader(ofstream& out, t_struct* tstruct)
 /**
  * Generates the write() method for a struct
  */
-void t_js_generator::generate_js_struct_writer(ofstream& out, t_struct* tstruct) {
+void t_js_generator::generate_js_struct_writer(ostream& out, t_struct* tstruct) {
   string name = tstruct->get_name();
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
@@ -1712,7 +1712,7 @@ std::string t_js_generator::render_recv_return(std::string var) {
 /**
  * Deserializes a field of any type.
  */
-void t_js_generator::generate_deserialize_field(ofstream& out,
+void t_js_generator::generate_deserialize_field(ostream& out,
                                                 t_field* tfield,
                                                 string prefix,
                                                 bool inclass) {
@@ -1784,12 +1784,12 @@ void t_js_generator::generate_deserialize_field(ofstream& out,
  * buffer for deserialization, and that there is a variable protocol which
  * is a reference to a TProtocol serialization object.
  */
-void t_js_generator::generate_deserialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_js_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   out << indent() << prefix << " = new " << js_type_namespace(tstruct->get_program())
       << tstruct->get_name() << "();" << endl << indent() << prefix << ".read(input);" << endl;
 }
 
-void t_js_generator::generate_deserialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_js_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) {
   string size = tmp("_size");
   string ktype = tmp("_ktype");
   string vtype = tmp("_vtype");
@@ -1863,7 +1863,7 @@ void t_js_generator::generate_deserialize_container(ofstream& out, t_type* ttype
 /**
  * Generates code to deserialize a map
  */
-void t_js_generator::generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix) {
+void t_js_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix) {
   string key = tmp("key");
   string val = tmp("val");
   t_field fkey(tmap->get_key_type(), key);
@@ -1878,7 +1878,7 @@ void t_js_generator::generate_deserialize_map_element(ofstream& out, t_map* tmap
   indent(out) << prefix << "[" << key << "] = " << val << ";" << endl;
 }
 
-void t_js_generator::generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix) {
+void t_js_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) {
   string elem = tmp("elem");
   t_field felem(tset->get_elem_type(), elem);
 
@@ -1889,7 +1889,7 @@ void t_js_generator::generate_deserialize_set_element(ofstream& out, t_set* tset
   indent(out) << prefix << ".push(" << elem << ");" << endl;
 }
 
-void t_js_generator::generate_deserialize_list_element(ofstream& out,
+void t_js_generator::generate_deserialize_list_element(ostream& out,
                                                        t_list* tlist,
                                                        string prefix) {
   string elem = tmp("elem");
@@ -1908,7 +1908,7 @@ void t_js_generator::generate_deserialize_list_element(ofstream& out,
  * @param tfield The field to serialize
  * @param prefix Name to prepend to field name
  */
-void t_js_generator::generate_serialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_js_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix) {
   t_type* type = get_true_type(tfield->get_type());
 
   // Do nothing for void types
@@ -1979,7 +1979,7 @@ void t_js_generator::generate_serialize_field(ofstream& out, t_field* tfield, st
  * @param tstruct The struct to serialize
  * @param prefix  String prefix to attach to all fields
  */
-void t_js_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_js_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   (void)tstruct;
   indent(out) << prefix << ".write(output);" << endl;
 }
@@ -1987,7 +1987,7 @@ void t_js_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct,
 /**
  * Writes out a container
  */
-void t_js_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_js_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
   if (ttype->is_map()) {
     indent(out) << "output.writeMapBegin(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", "
                 << type_to_enum(((t_map*)ttype)->get_val_type()) << ", "
@@ -2050,7 +2050,7 @@ void t_js_generator::generate_serialize_container(ofstream& out, t_type* ttype,
  * Serializes the members of a map.
  *
  */
-void t_js_generator::generate_serialize_map_element(ofstream& out,
+void t_js_generator::generate_serialize_map_element(ostream& out,
                                                     t_map* tmap,
                                                     string kiter,
                                                     string viter) {
@@ -2064,7 +2064,7 @@ void t_js_generator::generate_serialize_map_element(ofstream& out,
 /**
  * Serializes the members of a set.
  */
-void t_js_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
+void t_js_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
   t_field efield(tset->get_elem_type(), iter);
   generate_serialize_field(out, &efield);
 }
@@ -2072,7 +2072,7 @@ void t_js_generator::generate_serialize_set_element(ofstream& out, t_set* tset,
 /**
  * Serializes the members of a list.
  */
-void t_js_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string iter) {
+void t_js_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter) {
   t_field efield(tlist->get_elem_type(), iter);
   generate_serialize_field(out, &efield);
 }
diff --git a/compiler/cpp/src/thrift/generate/t_json_generator.cc b/compiler/cpp/src/thrift/generate/t_json_generator.cc
index cf5f80185f..cd5361274c 100644
--- a/compiler/cpp/src/thrift/generate/t_json_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_json_generator.cc
@@ -89,7 +89,7 @@ class t_json_generator : public t_generator {
 private:
   bool should_merge_includes_;
 
-  std::ofstream f_json_;
+  ofstream_with_content_based_conditional_update f_json_;
   std::stack<bool> comma_needed_;
 
   template <typename T>
diff --git a/compiler/cpp/src/thrift/generate/t_lua_generator.cc b/compiler/cpp/src/thrift/generate/t_lua_generator.cc
index b4a6793eb0..adee8968a6 100644
--- a/compiler/cpp/src/thrift/generate/t_lua_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_lua_generator.cc
@@ -21,7 +21,7 @@
 #include "thrift/platform.h"
 #include "thrift/generate/t_oop_generator.h"
 
-using std::ofstream;
+using std::ostream;
 using std::string;
 using std::vector;
 using std::map;
@@ -80,65 +80,65 @@ class t_lua_generator : public t_oop_generator {
   /**
    * Struct-level generation functions
    */
-  void generate_lua_struct_definition(std::ofstream& out,
+  void generate_lua_struct_definition(std::ostream& out,
                                       t_struct* tstruct,
                                       bool is_xception = false);
-  void generate_lua_struct_reader(std::ofstream& out, t_struct* tstruct);
-  void generate_lua_struct_writer(std::ofstream& out, t_struct* tstruct);
+  void generate_lua_struct_reader(std::ostream& out, t_struct* tstruct);
+  void generate_lua_struct_writer(std::ostream& out, t_struct* tstruct);
 
   /**
    * Service-level generation functions
    */
-  void generate_service_client(std::ofstream& out, t_service* tservice);
-  void generate_service_interface(std::ofstream& out, t_service* tservice);
-  void generate_service_processor(std::ofstream& out, t_service* tservice);
-  void generate_process_function(std::ofstream& out, t_service* tservice, t_function* tfunction);
-  void generate_service_helpers(ofstream& out, t_service* tservice);
-  void generate_function_helpers(ofstream& out, t_function* tfunction);
+  void generate_service_client(std::ostream& out, t_service* tservice);
+  void generate_service_interface(std::ostream& out, t_service* tservice);
+  void generate_service_processor(std::ostream& out, t_service* tservice);
+  void generate_process_function(std::ostream& out, t_service* tservice, t_function* tfunction);
+  void generate_service_helpers(ostream& out, t_service* tservice);
+  void generate_function_helpers(ostream& out, t_function* tfunction);
 
   /**
    * Deserialization (Read)
    */
-  void generate_deserialize_field(std::ofstream& out,
+  void generate_deserialize_field(std::ostream& out,
                                   t_field* tfield,
                                   bool local,
                                   std::string prefix = "");
 
-  void generate_deserialize_struct(std::ofstream& out,
+  void generate_deserialize_struct(std::ostream& out,
                                    t_struct* tstruct,
                                    bool local,
                                    std::string prefix = "");
 
-  void generate_deserialize_container(std::ofstream& out,
+  void generate_deserialize_container(std::ostream& out,
                                       t_type* ttype,
                                       bool local,
                                       std::string prefix = "");
 
-  void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
+  void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
 
-  void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
+  void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
 
-  void generate_deserialize_list_element(std::ofstream& out,
+  void generate_deserialize_list_element(std::ostream& out,
                                          t_list* tlist,
                                          std::string prefix = "");
 
   /**
    * Serialization (Write)
    */
-  void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
+  void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
 
-  void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_serialize_map_element(std::ofstream& out,
+  void generate_serialize_map_element(std::ostream& out,
                                       t_map* tmap,
                                       std::string kiter,
                                       std::string viter);
 
-  void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
+  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
 
-  void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
+  void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
 
   /**
    * Helper rendering functions
@@ -159,9 +159,9 @@ class t_lua_generator : public t_oop_generator {
   /**
    * File streams
    */
-  std::ofstream f_types_;
-  std::ofstream f_consts_;
-  std::ofstream f_service_;
+  ofstream_with_content_based_conditional_update f_types_;
+  ofstream_with_content_based_conditional_update f_consts_;
+  ofstream_with_content_based_conditional_update f_service_;
 };
 
 /**
@@ -366,7 +366,7 @@ void t_lua_generator::generate_xception(t_struct* txception) {
 /**
  * Generate a thrift struct or exception (lua table)
  */
-void t_lua_generator::generate_lua_struct_definition(ofstream& out,
+void t_lua_generator::generate_lua_struct_definition(ostream& out,
                                                      t_struct* tstruct,
                                                      bool is_exception) {
   vector<t_field*>::const_iterator m_iter;
@@ -402,7 +402,7 @@ void t_lua_generator::generate_lua_struct_definition(ofstream& out,
 /**
  * Generate a struct/exception reader
  */
-void t_lua_generator::generate_lua_struct_reader(ofstream& out, t_struct* tstruct) {
+void t_lua_generator::generate_lua_struct_reader(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
@@ -459,7 +459,7 @@ void t_lua_generator::generate_lua_struct_reader(ofstream& out, t_struct* tstruc
 /**
  * Generate a struct/exception writer
  */
-void t_lua_generator::generate_lua_struct_writer(ofstream& out, t_struct* tstruct) {
+void t_lua_generator::generate_lua_struct_writer(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
@@ -527,7 +527,7 @@ void t_lua_generator::generate_service(t_service* tservice) {
   f_service_.close();
 }
 
-void t_lua_generator::generate_service_interface(ofstream& out, t_service* tservice) {
+void t_lua_generator::generate_service_interface(ostream& out, t_service* tservice) {
   string classname = tservice->get_name() + "Iface";
   t_service* extends_s = tservice->get_extends();
 
@@ -541,7 +541,7 @@ void t_lua_generator::generate_service_interface(ofstream& out, t_service* tserv
   out << "  __type = '" << classname << "'" << endl << "}" << endl << endl;
 }
 
-void t_lua_generator::generate_service_client(ofstream& out, t_service* tservice) {
+void t_lua_generator::generate_service_client(ostream& out, t_service* tservice) {
   string classname = tservice->get_name() + "Client";
   t_service* extends_s = tservice->get_extends();
 
@@ -637,7 +637,7 @@ void t_lua_generator::generate_service_client(ofstream& out, t_service* tservice
   }
 }
 
-void t_lua_generator::generate_service_processor(ofstream& out, t_service* tservice) {
+void t_lua_generator::generate_service_processor(ostream& out, t_service* tservice) {
   string classname = tservice->get_name() + "Processor";
   t_service* extends_s = tservice->get_extends();
 
@@ -680,7 +680,7 @@ void t_lua_generator::generate_service_processor(ofstream& out, t_service* tserv
   }
 }
 
-void t_lua_generator::generate_process_function(ofstream& out,
+void t_lua_generator::generate_process_function(ostream& out,
                                                 t_service* tservice,
                                                 t_function* tfunction) {
   string classname = tservice->get_name() + "Processor";
@@ -731,7 +731,7 @@ void t_lua_generator::generate_process_function(ofstream& out,
 }
 
 // Service helpers
-void t_lua_generator::generate_service_helpers(ofstream& out, t_service* tservice) {
+void t_lua_generator::generate_service_helpers(ostream& out, t_service* tservice) {
   vector<t_function*> functions = tservice->get_functions();
   vector<t_function*>::iterator f_iter;
 
@@ -743,7 +743,7 @@ void t_lua_generator::generate_service_helpers(ofstream& out, t_service* tservic
   }
 }
 
-void t_lua_generator::generate_function_helpers(ofstream& out, t_function* tfunction) {
+void t_lua_generator::generate_function_helpers(ostream& out, t_function* tfunction) {
   if (!tfunction->is_oneway()) {
     t_struct result(program_, tfunction->get_name() + "_result");
     t_field success(tfunction->get_returntype(), "success", 0);
@@ -764,7 +764,7 @@ void t_lua_generator::generate_function_helpers(ofstream& out, t_function* tfunc
 /**
  * Deserialize (Read)
  */
-void t_lua_generator::generate_deserialize_field(ofstream& out,
+void t_lua_generator::generate_deserialize_field(ostream& out,
                                                  t_field* tfield,
                                                  bool local,
                                                  string prefix) {
@@ -825,7 +825,7 @@ void t_lua_generator::generate_deserialize_field(ofstream& out,
   }
 }
 
-void t_lua_generator::generate_deserialize_struct(ofstream& out,
+void t_lua_generator::generate_deserialize_struct(ostream& out,
                                                   t_struct* tstruct,
                                                   bool local,
                                                   string prefix) {
@@ -833,7 +833,7 @@ void t_lua_generator::generate_deserialize_struct(ofstream& out,
               << endl << indent() << prefix << ":read(iprot)" << endl;
 }
 
-void t_lua_generator::generate_deserialize_container(ofstream& out,
+void t_lua_generator::generate_deserialize_container(ostream& out,
                                                      t_type* ttype,
                                                      bool local,
                                                      string prefix) {
@@ -883,7 +883,7 @@ void t_lua_generator::generate_deserialize_container(ofstream& out,
   }
 }
 
-void t_lua_generator::generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix) {
+void t_lua_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix) {
   // A map is represented by a table indexable by any lua type
   string key = tmp("_key");
   string val = tmp("_val");
@@ -896,7 +896,7 @@ void t_lua_generator::generate_deserialize_map_element(ofstream& out, t_map* tma
   indent(out) << prefix << "[" << key << "] = " << val << endl;
 }
 
-void t_lua_generator::generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix) {
+void t_lua_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) {
   // A set is represented by a table indexed by the value
   string elem = tmp("_elem");
   t_field felem(tset->get_elem_type(), elem);
@@ -906,7 +906,7 @@ void t_lua_generator::generate_deserialize_set_element(ofstream& out, t_set* tse
   indent(out) << prefix << "[" << elem << "] = " << elem << endl;
 }
 
-void t_lua_generator::generate_deserialize_list_element(ofstream& out,
+void t_lua_generator::generate_deserialize_list_element(ostream& out,
                                                         t_list* tlist,
                                                         string prefix) {
   // A list is represented by a table indexed by integer values
@@ -922,7 +922,7 @@ void t_lua_generator::generate_deserialize_list_element(ofstream& out,
 /**
  * Serialize (Write)
  */
-void t_lua_generator::generate_serialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_lua_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix) {
   t_type* type = get_true_type(tfield->get_type());
   string name = prefix + tfield->get_name();
 
@@ -979,12 +979,12 @@ void t_lua_generator::generate_serialize_field(ofstream& out, t_field* tfield, s
   }
 }
 
-void t_lua_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_lua_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   (void)tstruct;
   indent(out) << prefix << ":write(oprot)" << endl;
 }
 
-void t_lua_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_lua_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
   // Begin writing
   if (ttype->is_map()) {
     indent(out) << "oprot:writeMapBegin(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", "
@@ -1034,7 +1034,7 @@ void t_lua_generator::generate_serialize_container(ofstream& out, t_type* ttype,
   }
 }
 
-void t_lua_generator::generate_serialize_map_element(ofstream& out,
+void t_lua_generator::generate_serialize_map_element(ostream& out,
                                                      t_map* tmap,
                                                      string kiter,
                                                      string viter) {
@@ -1045,12 +1045,12 @@ void t_lua_generator::generate_serialize_map_element(ofstream& out,
   generate_serialize_field(out, &vfield, "");
 }
 
-void t_lua_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
+void t_lua_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
   t_field efield(tset->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "");
 }
 
-void t_lua_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string iter) {
+void t_lua_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter) {
   t_field efield(tlist->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "");
 }
diff --git a/compiler/cpp/src/thrift/generate/t_netcore_generator.cc b/compiler/cpp/src/thrift/generate/t_netcore_generator.cc
index dbf2fd0cef..d2e7da0cb9 100644
--- a/compiler/cpp/src/thrift/generate/t_netcore_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_netcore_generator.cc
@@ -38,7 +38,7 @@
 #include "thrift/generate/t_netcore_generator.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -332,7 +332,7 @@ void t_netcore_generator::init_keywords()
 	netcore_keywords["when"] = 1;
 }
 
-void t_netcore_generator::start_netcore_namespace(ofstream& out)
+void t_netcore_generator::start_netcore_namespace(ostream& out)
 {
     if (!namespace_name_.empty())
     {
@@ -341,7 +341,7 @@ void t_netcore_generator::start_netcore_namespace(ofstream& out)
     }
 }
 
-void t_netcore_generator::end_netcore_namespace(ofstream& out)
+void t_netcore_generator::end_netcore_namespace(ostream& out)
 {
     if (!namespace_name_.empty())
     {
@@ -398,7 +398,7 @@ void t_netcore_generator::generate_enum(t_enum* tenum)
 	int ic = indent_count();
     string f_enum_name = namespace_dir_ + "/" + tenum->get_name() + ".cs";
 
-    ofstream f_enum;
+    ofstream_with_content_based_conditional_update f_enum;
     f_enum.open(f_enum_name.c_str());
 
 	generate_enum(f_enum, tenum);
@@ -407,7 +407,7 @@ void t_netcore_generator::generate_enum(t_enum* tenum)
 	indent_validate(ic, "generate_enum");
 }
 
-void t_netcore_generator::generate_enum(ofstream& out, t_enum* tenum)
+void t_netcore_generator::generate_enum(ostream& out, t_enum* tenum)
 {
 	out << autogen_comment() << endl;
 
@@ -439,7 +439,7 @@ void t_netcore_generator::generate_consts(vector<t_const*> consts)
     }
 
     string f_consts_name = namespace_dir_ + '/' + program_name_ + ".Constants.cs";
-    ofstream f_consts;
+    ofstream_with_content_based_conditional_update f_consts;
     f_consts.open(f_consts_name.c_str());
 
     generate_consts(f_consts, consts);
@@ -447,7 +447,7 @@ void t_netcore_generator::generate_consts(vector<t_const*> consts)
     f_consts.close();
 }
 
-void t_netcore_generator::generate_consts(ofstream& out, vector<t_const*> consts)
+void t_netcore_generator::generate_consts(ostream& out, vector<t_const*> consts)
 {
     if (consts.empty())
     {
@@ -482,7 +482,7 @@ void t_netcore_generator::generate_consts(ofstream& out, vector<t_const*> consts
     end_netcore_namespace(out);
 }
 
-void t_netcore_generator::print_const_def_value(ofstream& out, string name, t_type* type, t_const_value* value)
+void t_netcore_generator::print_const_def_value(ostream& out, string name, t_type* type, t_const_value* value)
 {
     if (type->is_struct() || type->is_xception())
     {
@@ -552,7 +552,7 @@ void t_netcore_generator::print_const_def_value(ofstream& out, string name, t_ty
     }
 }
 
-void t_netcore_generator::print_const_constructor(ofstream& out, vector<t_const*> consts)
+void t_netcore_generator::print_const_constructor(ostream& out, vector<t_const*> consts)
 {
     out << indent() << "static " << make_valid_csharp_identifier(program_name_).c_str() << "Constants()" << endl;
     scope_up(out);
@@ -569,7 +569,7 @@ void t_netcore_generator::print_const_constructor(ofstream& out, vector<t_const*
     scope_down(out);
 }
 
-bool t_netcore_generator::print_const_value(ofstream& out, string name, t_type* type, t_const_value* value, bool in_static, bool defval, bool needtype)
+bool t_netcore_generator::print_const_value(ostream& out, string name, t_type* type, t_const_value* value, bool in_static, bool defval, bool needtype)
 {
     out << indent();
     bool need_static_construction = !in_static;
@@ -615,7 +615,7 @@ bool t_netcore_generator::print_const_value(ofstream& out, string name, t_type*
     return need_static_construction;
 }
 
-string t_netcore_generator::render_const_value(ofstream& out, string name, t_type* type, t_const_value* value)
+string t_netcore_generator::render_const_value(ostream& out, string name, t_type* type, t_const_value* value)
 {
     (void)name;
     ostringstream render;
@@ -687,7 +687,7 @@ void t_netcore_generator::generate_netcore_struct(t_struct* tstruct, bool is_exc
     int ic = indent_count();
 
     string f_struct_name = namespace_dir_ + "/" + (tstruct->get_name()) + ".cs";
-    ofstream f_struct;
+    ofstream_with_content_based_conditional_update f_struct;
 
     f_struct.open(f_struct_name.c_str());
 
@@ -700,7 +700,7 @@ void t_netcore_generator::generate_netcore_struct(t_struct* tstruct, bool is_exc
     indent_validate(ic, "generate_netcore_struct");
 }
 
-void t_netcore_generator::generate_netcore_struct_definition(ofstream& out, t_struct* tstruct, bool is_exception, bool in_class, bool is_result)
+void t_netcore_generator::generate_netcore_struct_definition(ostream& out, t_struct* tstruct, bool is_exception, bool in_class, bool is_result)
 {
     if (!in_class)
     {
@@ -929,7 +929,7 @@ void t_netcore_generator::generate_netcore_struct_definition(ofstream& out, t_st
     }
 }
 
-void t_netcore_generator::generate_netcore_wcffault(ofstream& out, t_struct* tstruct)
+void t_netcore_generator::generate_netcore_wcffault(ostream& out, t_struct* tstruct)
 {
     out << endl;
     out << indent() << "[DataContract]" << endl;
@@ -959,7 +959,7 @@ void t_netcore_generator::generate_netcore_wcffault(ofstream& out, t_struct* tst
     out << indent() << "}" << endl << endl;
 }
 
-void t_netcore_generator::generate_netcore_struct_reader(ofstream& out, t_struct* tstruct)
+void t_netcore_generator::generate_netcore_struct_reader(ostream& out, t_struct* tstruct)
 {
     out << indent() << "public async Task ReadAsync(TProtocol iprot, CancellationToken cancellationToken)" << endl
         << indent() << "{" << endl;
@@ -1063,7 +1063,7 @@ void t_netcore_generator::generate_netcore_struct_reader(ofstream& out, t_struct
     out << indent() << "}" << endl << endl;
 }
 
-void t_netcore_generator::generate_netcore_struct_writer(ofstream& out, t_struct* tstruct)
+void t_netcore_generator::generate_netcore_struct_writer(ostream& out, t_struct* tstruct)
 {
     out << indent() << "public async Task WriteAsync(TProtocol oprot, CancellationToken cancellationToken)" << endl
         << indent() << "{" << endl;
@@ -1140,7 +1140,7 @@ void t_netcore_generator::generate_netcore_struct_writer(ofstream& out, t_struct
     out << indent() << "}" << endl << endl;
 }
 
-void t_netcore_generator::generate_netcore_struct_result_writer(ofstream& out, t_struct* tstruct)
+void t_netcore_generator::generate_netcore_struct_result_writer(ostream& out, t_struct* tstruct)
 {
     out << indent() << "public async Task WriteAsync(TProtocol oprot, CancellationToken cancellationToken)" << endl
         << indent() << "{" << endl;
@@ -1228,7 +1228,7 @@ void t_netcore_generator::generate_netcore_struct_result_writer(ofstream& out, t
     out << indent() << "}" << endl << endl;
 }
 
-void t_netcore_generator::generate_netcore_struct_tostring(ofstream& out, t_struct* tstruct)
+void t_netcore_generator::generate_netcore_struct_tostring(ostream& out, t_struct* tstruct)
 {
     out << indent() << "public override string ToString()" << endl
         << indent() << "{" << endl;
@@ -1324,7 +1324,7 @@ void t_netcore_generator::generate_netcore_union(t_struct* tunion)
     int ic = indent_count();
 
     string f_union_name = namespace_dir_ + "/" + (tunion->get_name()) + ".cs";
-    ofstream f_union;
+    ofstream_with_content_based_conditional_update f_union;
 
     f_union.open(f_union_name.c_str());
 
@@ -1337,7 +1337,7 @@ void t_netcore_generator::generate_netcore_union(t_struct* tunion)
     indent_validate(ic, "generate_netcore_union.");
 }
 
-void t_netcore_generator::generate_netcore_union_definition(ofstream& out, t_struct* tunion)
+void t_netcore_generator::generate_netcore_union_definition(ostream& out, t_struct* tunion)
 {
     // Let's define the class first
     start_netcore_namespace(out);
@@ -1388,7 +1388,7 @@ void t_netcore_generator::generate_netcore_union_definition(ofstream& out, t_str
     end_netcore_namespace(out);
 }
 
-void t_netcore_generator::generate_netcore_union_class(ofstream& out, t_struct* tunion, t_field* tfield)
+void t_netcore_generator::generate_netcore_union_class(ostream& out, t_struct* tunion, t_field* tfield)
 {
     out << indent() << "public class " << tfield->get_name() << " : " << tunion->get_name() << endl
         << indent() << "{" << endl;
@@ -1438,7 +1438,7 @@ void t_netcore_generator::generate_netcore_union_class(ofstream& out, t_struct*
     out << indent() << "}" << endl << endl;
 }
 
-void t_netcore_generator::generate_netcore_struct_equals(ofstream& out, t_struct* tstruct)
+void t_netcore_generator::generate_netcore_struct_equals(ostream& out, t_struct* tstruct)
 {
     out << indent() << "public override bool Equals(object that)" << endl
         << indent() << "{" << endl;
@@ -1500,7 +1500,7 @@ void t_netcore_generator::generate_netcore_struct_equals(ofstream& out, t_struct
     out << indent() << "}" << endl << endl;
 }
 
-void t_netcore_generator::generate_netcore_struct_hashcode(ofstream& out, t_struct* tstruct)
+void t_netcore_generator::generate_netcore_struct_hashcode(ostream& out, t_struct* tstruct)
 {
     out << indent() << "public override int GetHashCode() {" << endl;
     indent_up();
@@ -1552,7 +1552,7 @@ void t_netcore_generator::generate_service(t_service* tservice)
     int ic = indent_count();
 
     string f_service_name = namespace_dir_ + "/" + service_name_ + ".cs";
-    ofstream f_service;
+    ofstream_with_content_based_conditional_update f_service;
     f_service.open(f_service_name.c_str());
 
     f_service << autogen_comment() << netcore_type_usings() << netcore_thrift_usings() << endl;
@@ -1577,7 +1577,7 @@ void t_netcore_generator::generate_service(t_service* tservice)
     indent_validate(ic, "generate_service.");
 }
 
-void t_netcore_generator::generate_service_interface(ofstream& out, t_service* tservice)
+void t_netcore_generator::generate_service_interface(ostream& out, t_service* tservice)
 {
     string extends = "";
     string extends_iface = "";
@@ -1625,7 +1625,7 @@ void t_netcore_generator::generate_service_interface(ofstream& out, t_service* t
     out << indent() << "}" << endl << endl;
 }
 
-void t_netcore_generator::generate_service_helpers(ofstream& out, t_service* tservice)
+void t_netcore_generator::generate_service_helpers(ostream& out, t_service* tservice)
 {
     vector<t_function*> functions = tservice->get_functions();
     vector<t_function*>::iterator f_iter;
@@ -1638,7 +1638,7 @@ void t_netcore_generator::generate_service_helpers(ofstream& out, t_service* tse
     }
 }
 
-void t_netcore_generator::generate_service_client(ofstream& out, t_service* tservice)
+void t_netcore_generator::generate_service_client(ostream& out, t_service* tservice)
 {
     string extends = "";
     string extends_client = "";
@@ -1809,7 +1809,7 @@ void t_netcore_generator::generate_service_client(ofstream& out, t_service* tser
     out << indent() << "}" << endl << endl;
 }
 
-void t_netcore_generator::generate_service_server(ofstream& out, t_service* tservice)
+void t_netcore_generator::generate_service_server(ostream& out, t_service* tservice)
 {
     vector<t_function*> functions = tservice->get_functions();
     vector<t_function*>::iterator f_iter;
@@ -1937,7 +1937,7 @@ void t_netcore_generator::generate_service_server(ofstream& out, t_service* tser
     out << indent() << "}" << endl << endl;
 }
 
-void t_netcore_generator::generate_function_helpers(ofstream& out, t_function* tfunction)
+void t_netcore_generator::generate_function_helpers(ostream& out, t_function* tfunction)
 {
     if (tfunction->is_oneway())
     {
@@ -1962,7 +1962,7 @@ void t_netcore_generator::generate_function_helpers(ofstream& out, t_function* t
     generate_netcore_struct_definition(out, &result, false, true, true);
 }
 
-void t_netcore_generator::generate_process_function_async(ofstream& out, t_service* tservice, t_function* tfunction)
+void t_netcore_generator::generate_process_function_async(ostream& out, t_service* tservice, t_function* tfunction)
 {
     (void)tservice;
     out << indent() << "public async Task " << tfunction->get_name()
@@ -2104,7 +2104,7 @@ void t_netcore_generator::generate_process_function_async(ofstream& out, t_servi
     out << indent() << "}" << endl << endl;
 }
 
-void t_netcore_generator::generate_netcore_union_reader(ofstream& out, t_struct* tunion)
+void t_netcore_generator::generate_netcore_union_reader(ostream& out, t_struct* tunion)
 {
     // Thanks to THRIFT-1768, we don't need to check for required fields in the union
     const vector<t_field*>& fields = tunion->get_members();
@@ -2180,7 +2180,7 @@ void t_netcore_generator::generate_netcore_union_reader(ofstream& out, t_struct*
     out << indent() << "}" << endl << endl;
 }
 
-void t_netcore_generator::generate_deserialize_field(ofstream& out, t_field* tfield, string prefix, bool is_propertyless)
+void t_netcore_generator::generate_deserialize_field(ostream& out, t_field* tfield, string prefix, bool is_propertyless)
 {
     t_type* type = tfield->get_type();
     while (type->is_typedef())
@@ -2266,7 +2266,7 @@ void t_netcore_generator::generate_deserialize_field(ofstream& out, t_field* tfi
     }
 }
 
-void t_netcore_generator::generate_deserialize_struct(ofstream& out, t_struct* tstruct, string prefix)
+void t_netcore_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix)
 {
     if (union_ && tstruct->is_union())
     {
@@ -2279,7 +2279,7 @@ void t_netcore_generator::generate_deserialize_struct(ofstream& out, t_struct* t
     }
 }
 
-void t_netcore_generator::generate_deserialize_container(ofstream& out, t_type* ttype, string prefix)
+void t_netcore_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix)
 {
     out << indent() << "{" << endl;
     indent_up();
@@ -2351,7 +2351,7 @@ void t_netcore_generator::generate_deserialize_container(ofstream& out, t_type*
     out << indent() << "}" << endl;
 }
 
-void t_netcore_generator::generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix)
+void t_netcore_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix)
 {
     string key = tmp("_key");
     string val = tmp("_val");
@@ -2368,7 +2368,7 @@ void t_netcore_generator::generate_deserialize_map_element(ofstream& out, t_map*
     out << indent() << prefix << "[" << key << "] = " << val << ";" << endl;
 }
 
-void t_netcore_generator::generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix)
+void t_netcore_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix)
 {
     string elem = tmp("_elem");
     t_field felem(tset->get_elem_type(), elem);
@@ -2380,7 +2380,7 @@ void t_netcore_generator::generate_deserialize_set_element(ofstream& out, t_set*
     out << indent() << prefix << ".Add(" << elem << ");" << endl;
 }
 
-void t_netcore_generator::generate_deserialize_list_element(ofstream& out, t_list* tlist, string prefix)
+void t_netcore_generator::generate_deserialize_list_element(ostream& out, t_list* tlist, string prefix)
 {
     string elem = tmp("_elem");
     t_field felem(tlist->get_elem_type(), elem);
@@ -2392,7 +2392,7 @@ void t_netcore_generator::generate_deserialize_list_element(ofstream& out, t_lis
     out << indent() << prefix << ".Add(" << elem << ");" << endl;
 }
 
-void t_netcore_generator::generate_serialize_field(ofstream& out, t_field* tfield, string prefix, bool is_element, bool is_propertyless)
+void t_netcore_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix, bool is_element, bool is_propertyless)
 {
     t_type* type = tfield->get_type();
     while (type->is_typedef())
@@ -2473,13 +2473,13 @@ void t_netcore_generator::generate_serialize_field(ofstream& out, t_field* tfiel
     }
 }
 
-void t_netcore_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix)
+void t_netcore_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix)
 {
     (void)tstruct;
     out << indent() << "await " << prefix << ".WriteAsync(oprot, cancellationToken);" << endl;
 }
 
-void t_netcore_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix)
+void t_netcore_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix)
 {
     out << indent() << "{" << endl;
     indent_up();
@@ -2556,7 +2556,7 @@ void t_netcore_generator::generate_serialize_container(ofstream& out, t_type* tt
     out << indent() << "}" << endl;
 }
 
-void t_netcore_generator::generate_serialize_map_element(ofstream& out, t_map* tmap, string iter, string map)
+void t_netcore_generator::generate_serialize_map_element(ostream& out, t_map* tmap, string iter, string map)
 {
     t_field kfield(tmap->get_key_type(), iter);
     generate_serialize_field(out, &kfield, "", true);
@@ -2564,24 +2564,24 @@ void t_netcore_generator::generate_serialize_map_element(ofstream& out, t_map* t
     generate_serialize_field(out, &vfield, "", true);
 }
 
-void t_netcore_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter)
+void t_netcore_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter)
 {
     t_field efield(tset->get_elem_type(), iter);
     generate_serialize_field(out, &efield, "", true);
 }
 
-void t_netcore_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string iter)
+void t_netcore_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter)
 {
     t_field efield(tlist->get_elem_type(), iter);
     generate_serialize_field(out, &efield, "", true);
 }
 
-void t_netcore_generator::generate_property(ofstream& out, t_field* tfield, bool isPublic, bool generateIsset)
+void t_netcore_generator::generate_property(ostream& out, t_field* tfield, bool isPublic, bool generateIsset)
 {
     generate_netcore_property(out, tfield, isPublic, generateIsset, "_");
 }
 
-void t_netcore_generator::generate_netcore_property(ofstream& out, t_field* tfield, bool isPublic, bool generateIsset, string fieldPrefix)
+void t_netcore_generator::generate_netcore_property(ostream& out, t_field* tfield, bool isPublic, bool generateIsset, string fieldPrefix)
 {
     if ((serialize_ || wcf_) && isPublic)
     {
@@ -2866,7 +2866,7 @@ string t_netcore_generator::declare_field(t_field* tfield, bool init, string pre
         }
         if (ttype->is_base_type() && field_has_default(tfield))
         {
-            ofstream dummy;
+            std::ofstream dummy;
             result += " = " + render_const_value(dummy, tfield->get_name(), ttype, tfield->get_value());
         }
         else if (ttype->is_base_type())
@@ -3011,12 +3011,12 @@ string t_netcore_generator::type_to_enum(t_type* type)
     throw "INVALID TYPE IN type_to_enum: " + type->get_name();
 }
 
-void t_netcore_generator::generate_netcore_docstring_comment(ofstream& out, string contents)
+void t_netcore_generator::generate_netcore_docstring_comment(ostream& out, string contents)
 {
     docstring_comment(out, "/// <summary>" + endl, "/// ", contents, "/// </summary>" + endl);
 }
 
-void t_netcore_generator::generate_netcore_doc(ofstream& out, t_field* field)
+void t_netcore_generator::generate_netcore_doc(ostream& out, t_field* field)
 {
     if (field->get_type()->is_enum())
     {
@@ -3029,7 +3029,7 @@ void t_netcore_generator::generate_netcore_doc(ofstream& out, t_field* field)
     }
 }
 
-void t_netcore_generator::generate_netcore_doc(ofstream& out, t_doc* tdoc)
+void t_netcore_generator::generate_netcore_doc(ostream& out, t_doc* tdoc)
 {
     if (tdoc->has_doc())
     {
@@ -3037,7 +3037,7 @@ void t_netcore_generator::generate_netcore_doc(ofstream& out, t_doc* tdoc)
     }
 }
 
-void t_netcore_generator::generate_netcore_doc(ofstream& out, t_function* tfunction)
+void t_netcore_generator::generate_netcore_doc(ostream& out, t_function* tfunction)
 {
     if (tfunction->has_doc())
     {
@@ -3065,7 +3065,7 @@ void t_netcore_generator::generate_netcore_doc(ofstream& out, t_function* tfunct
     }
 }
 
-void t_netcore_generator::docstring_comment(ofstream& out, const string& comment_start, const string& line_prefix, const string& contents, const string& comment_end)
+void t_netcore_generator::docstring_comment(ostream& out, const string& comment_start, const string& line_prefix, const string& contents, const string& comment_end)
 {
     if (comment_start != "")
     {
diff --git a/compiler/cpp/src/thrift/generate/t_netcore_generator.h b/compiler/cpp/src/thrift/generate/t_netcore_generator.h
index 8d52307f1a..6efc922b74 100644
--- a/compiler/cpp/src/thrift/generate/t_netcore_generator.h
+++ b/compiler/cpp/src/thrift/generate/t_netcore_generator.h
@@ -14,7 +14,7 @@
 #include "thrift/generate/t_oop_generator.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -47,58 +47,58 @@ class t_netcore_generator : public t_oop_generator
     void init_generator();
     void close_generator();
     void generate_consts(vector<t_const*> consts);
-    void generate_consts(ofstream& out, vector<t_const*> consts);
+    void generate_consts(ostream& out, vector<t_const*> consts);
     void generate_typedef(t_typedef* ttypedef);
     void generate_enum(t_enum* tenum);
-    void generate_enum(ofstream& out, t_enum* tenum);
+    void generate_enum(ostream& out, t_enum* tenum);
     void generate_struct(t_struct* tstruct);
     void generate_xception(t_struct* txception);
     void generate_service(t_service* tservice);
 
-    void generate_property(ofstream& out, t_field* tfield, bool isPublic, bool generateIsset);
-    void generate_netcore_property(ofstream& out, t_field* tfield, bool isPublic, bool includeIsset = true, string fieldPrefix = "");
-    bool print_const_value(ofstream& out, string name, t_type* type, t_const_value* value, bool in_static, bool defval = false, bool needtype = false);
-    string render_const_value(ofstream& out, string name, t_type* type, t_const_value* value);
-    void print_const_constructor(ofstream& out, vector<t_const*> consts);
-    void print_const_def_value(ofstream& out, string name, t_type* type, t_const_value* value);
+    void generate_property(ostream& out, t_field* tfield, bool isPublic, bool generateIsset);
+    void generate_netcore_property(ostream& out, t_field* tfield, bool isPublic, bool includeIsset = true, string fieldPrefix = "");
+    bool print_const_value(ostream& out, string name, t_type* type, t_const_value* value, bool in_static, bool defval = false, bool needtype = false);
+    string render_const_value(ostream& out, string name, t_type* type, t_const_value* value);
+    void print_const_constructor(ostream& out, vector<t_const*> consts);
+    void print_const_def_value(ostream& out, string name, t_type* type, t_const_value* value);
     void generate_netcore_struct(t_struct* tstruct, bool is_exception);
     void generate_netcore_union(t_struct* tunion);
-    void generate_netcore_struct_definition(ofstream& out, t_struct* tstruct, bool is_xception = false, bool in_class = false, bool is_result = false);
-    void generate_netcore_union_definition(ofstream& out, t_struct* tunion);
-    void generate_netcore_union_class(ofstream& out, t_struct* tunion, t_field* tfield);
-    void generate_netcore_wcffault(ofstream& out, t_struct* tstruct);
-    void generate_netcore_struct_reader(ofstream& out, t_struct* tstruct);
-    void generate_netcore_struct_result_writer(ofstream& out, t_struct* tstruct);
-    void generate_netcore_struct_writer(ofstream& out, t_struct* tstruct);
-    void generate_netcore_struct_tostring(ofstream& out, t_struct* tstruct);
-    void generate_netcore_struct_equals(ofstream& out, t_struct* tstruct);
-    void generate_netcore_struct_hashcode(ofstream& out, t_struct* tstruct);
-    void generate_netcore_union_reader(ofstream& out, t_struct* tunion);
-    void generate_function_helpers(ofstream& out, t_function* tfunction);
-    void generate_service_interface(ofstream& out, t_service* tservice);
-    void generate_service_helpers(ofstream& out, t_service* tservice);
-    void generate_service_client(ofstream& out, t_service* tservice);
-    void generate_service_server(ofstream& out, t_service* tservice);
-    void generate_process_function_async(ofstream& out, t_service* tservice, t_function* function);
-    void generate_deserialize_field(ofstream& out, t_field* tfield, string prefix = "", bool is_propertyless = false);
-    void generate_deserialize_struct(ofstream& out, t_struct* tstruct, string prefix = "");
-    void generate_deserialize_container(ofstream& out, t_type* ttype, string prefix = "");
-    void generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix = "");
-    void generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix = "");
-    void generate_deserialize_list_element(ofstream& out, t_list* list, string prefix = "");
-    void generate_serialize_field(ofstream& out, t_field* tfield, string prefix = "", bool is_element = false, bool is_propertyless = false);
-    void generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix = "");
-    void generate_serialize_container(ofstream& out, t_type* ttype, string prefix = "");
-    void generate_serialize_map_element(ofstream& out, t_map* tmap, string iter, string map);
-    void generate_serialize_set_element(ofstream& out, t_set* tmap, string iter);
-    void generate_serialize_list_element(ofstream& out, t_list* tlist, string iter);
-    void generate_netcore_doc(ofstream& out, t_field* field);
-    void generate_netcore_doc(ofstream& out, t_doc* tdoc);
-    void generate_netcore_doc(ofstream& out, t_function* tdoc);
-    void generate_netcore_docstring_comment(ofstream& out, string contents);
-    void docstring_comment(ofstream& out, const string& comment_start, const string& line_prefix, const string& contents, const string& comment_end);
-    void start_netcore_namespace(ofstream& out);
-    void end_netcore_namespace(ofstream& out);
+    void generate_netcore_struct_definition(ostream& out, t_struct* tstruct, bool is_xception = false, bool in_class = false, bool is_result = false);
+    void generate_netcore_union_definition(ostream& out, t_struct* tunion);
+    void generate_netcore_union_class(ostream& out, t_struct* tunion, t_field* tfield);
+    void generate_netcore_wcffault(ostream& out, t_struct* tstruct);
+    void generate_netcore_struct_reader(ostream& out, t_struct* tstruct);
+    void generate_netcore_struct_result_writer(ostream& out, t_struct* tstruct);
+    void generate_netcore_struct_writer(ostream& out, t_struct* tstruct);
+    void generate_netcore_struct_tostring(ostream& out, t_struct* tstruct);
+    void generate_netcore_struct_equals(ostream& out, t_struct* tstruct);
+    void generate_netcore_struct_hashcode(ostream& out, t_struct* tstruct);
+    void generate_netcore_union_reader(ostream& out, t_struct* tunion);
+    void generate_function_helpers(ostream& out, t_function* tfunction);
+    void generate_service_interface(ostream& out, t_service* tservice);
+    void generate_service_helpers(ostream& out, t_service* tservice);
+    void generate_service_client(ostream& out, t_service* tservice);
+    void generate_service_server(ostream& out, t_service* tservice);
+    void generate_process_function_async(ostream& out, t_service* tservice, t_function* function);
+    void generate_deserialize_field(ostream& out, t_field* tfield, string prefix = "", bool is_propertyless = false);
+    void generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix = "");
+    void generate_deserialize_container(ostream& out, t_type* ttype, string prefix = "");
+    void generate_deserialize_set_element(ostream& out, t_set* tset, string prefix = "");
+    void generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix = "");
+    void generate_deserialize_list_element(ostream& out, t_list* list, string prefix = "");
+    void generate_serialize_field(ostream& out, t_field* tfield, string prefix = "", bool is_element = false, bool is_propertyless = false);
+    void generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix = "");
+    void generate_serialize_container(ostream& out, t_type* ttype, string prefix = "");
+    void generate_serialize_map_element(ostream& out, t_map* tmap, string iter, string map);
+    void generate_serialize_set_element(ostream& out, t_set* tmap, string iter);
+    void generate_serialize_list_element(ostream& out, t_list* tlist, string iter);
+    void generate_netcore_doc(ostream& out, t_field* field);
+    void generate_netcore_doc(ostream& out, t_doc* tdoc);
+    void generate_netcore_doc(ostream& out, t_function* tdoc);
+    void generate_netcore_docstring_comment(ostream& out, string contents);
+    void docstring_comment(ostream& out, const string& comment_start, const string& line_prefix, const string& contents, const string& comment_end);
+    void start_netcore_namespace(ostream& out);
+    void end_netcore_namespace(ostream& out);
 
     string netcore_type_usings() const;
     string netcore_thrift_usings() const;
diff --git a/compiler/cpp/src/thrift/generate/t_ocaml_generator.cc b/compiler/cpp/src/thrift/generate/t_ocaml_generator.cc
index 2bf85d1c2d..0ec81ba5eb 100644
--- a/compiler/cpp/src/thrift/generate/t_ocaml_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_ocaml_generator.cc
@@ -32,7 +32,7 @@
 
 using std::ios;
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -90,16 +90,16 @@ class t_ocaml_generator : public t_oop_generator {
    */
 
   void generate_ocaml_struct(t_struct* tstruct, bool is_exception);
-  void generate_ocaml_struct_definition(std::ofstream& out,
+  void generate_ocaml_struct_definition(std::ostream& out,
                                         t_struct* tstruct,
                                         bool is_xception = false);
-  void generate_ocaml_struct_member(std::ofstream& out, string tname, t_field* tmember);
-  void generate_ocaml_struct_sig(std::ofstream& out, t_struct* tstruct, bool is_exception);
-  void generate_ocaml_struct_reader(std::ofstream& out, t_struct* tstruct);
-  void generate_ocaml_struct_writer(std::ofstream& out, t_struct* tstruct);
+  void generate_ocaml_struct_member(std::ostream& out, string tname, t_field* tmember);
+  void generate_ocaml_struct_sig(std::ostream& out, t_struct* tstruct, bool is_exception);
+  void generate_ocaml_struct_reader(std::ostream& out, t_struct* tstruct);
+  void generate_ocaml_struct_writer(std::ostream& out, t_struct* tstruct);
   void generate_ocaml_function_helpers(t_function* tfunction);
-  void generate_ocaml_method_copy(std::ofstream& out, const vector<t_field*>& members);
-  void generate_ocaml_member_copy(std::ofstream& out, t_field* member);
+  void generate_ocaml_method_copy(std::ostream& out, const vector<t_field*>& members);
+  void generate_ocaml_member_copy(std::ostream& out, t_field* member);
 
   /**
    * Service-level generation functions
@@ -115,33 +115,33 @@ class t_ocaml_generator : public t_oop_generator {
    * Serialization constructs
    */
 
-  void generate_deserialize_field(std::ofstream& out, t_field* tfield, std::string prefix);
+  void generate_deserialize_field(std::ostream& out, t_field* tfield, std::string prefix);
 
-  void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct);
+  void generate_deserialize_struct(std::ostream& out, t_struct* tstruct);
 
-  void generate_deserialize_container(std::ofstream& out, t_type* ttype);
+  void generate_deserialize_container(std::ostream& out, t_type* ttype);
 
-  void generate_deserialize_set_element(std::ofstream& out, t_set* tset);
+  void generate_deserialize_set_element(std::ostream& out, t_set* tset);
 
-  void generate_deserialize_list_element(std::ofstream& out,
+  void generate_deserialize_list_element(std::ostream& out,
                                          t_list* tlist,
                                          std::string prefix = "");
-  void generate_deserialize_type(std::ofstream& out, t_type* type);
+  void generate_deserialize_type(std::ostream& out, t_type* type);
 
-  void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string name = "");
+  void generate_serialize_field(std::ostream& out, t_field* tfield, std::string name = "");
 
-  void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_serialize_map_element(std::ofstream& out,
+  void generate_serialize_map_element(std::ostream& out,
                                       t_map* tmap,
                                       std::string kiter,
                                       std::string viter);
 
-  void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
+  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
 
-  void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
+  void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
 
   /**
    * Helper rendering functions
@@ -161,12 +161,12 @@ class t_ocaml_generator : public t_oop_generator {
    * File streams
    */
 
-  std::ofstream f_types_;
-  std::ofstream f_consts_;
-  std::ofstream f_service_;
+  ofstream_with_content_based_conditional_update f_types_;
+  ofstream_with_content_based_conditional_update f_consts_;
+  ofstream_with_content_based_conditional_update f_service_;
 
-  std::ofstream f_types_i_;
-  std::ofstream f_service_i_;
+  ofstream_with_content_based_conditional_update f_types_i_;
+  ofstream_with_content_based_conditional_update f_service_i_;
 };
 
 /*
@@ -499,7 +499,7 @@ void t_ocaml_generator::generate_ocaml_struct(t_struct* tstruct, bool is_excepti
   generate_ocaml_struct_sig(f_types_i_, tstruct, is_exception);
 }
 
-void t_ocaml_generator::generate_ocaml_method_copy(ofstream& out, const vector<t_field*>& members) {
+void t_ocaml_generator::generate_ocaml_method_copy(ostream& out, const vector<t_field*>& members) {
   vector<t_field*>::const_iterator m_iter;
 
   /* Create a copy of the current object */
@@ -555,7 +555,7 @@ string t_ocaml_generator::struct_member_copy_of(t_type* type, string what) {
   return what;
 }
 
-void t_ocaml_generator::generate_ocaml_member_copy(ofstream& out, t_field* tmember) {
+void t_ocaml_generator::generate_ocaml_member_copy(ostream& out, t_field* tmember) {
   string mname = decapitalize(tmember->get_name());
   t_type* type = get_true_type(tmember->get_type());
 
@@ -576,7 +576,7 @@ void t_ocaml_generator::generate_ocaml_member_copy(ofstream& out, t_field* tmemb
  *
  * @param tstruct The struct definition
  */
-void t_ocaml_generator::generate_ocaml_struct_definition(ofstream& out,
+void t_ocaml_generator::generate_ocaml_struct_definition(ostream& out,
                                                          t_struct* tstruct,
                                                          bool is_exception) {
   const vector<t_field*>& members = tstruct->get_members();
@@ -611,7 +611,7 @@ void t_ocaml_generator::generate_ocaml_struct_definition(ofstream& out,
  * @param tname Name of the parent structure for the member
  * @param tmember Member definition
  */
-void t_ocaml_generator::generate_ocaml_struct_member(ofstream& out,
+void t_ocaml_generator::generate_ocaml_struct_member(ostream& out,
                                                      string tname,
                                                      t_field* tmember) {
   string x = tmp("_x");
@@ -713,7 +713,7 @@ bool t_ocaml_generator::struct_member_default_cheaply_comparable(t_field* tmembe
  *
  * @param tstruct The struct definition
  */
-void t_ocaml_generator::generate_ocaml_struct_sig(ofstream& out,
+void t_ocaml_generator::generate_ocaml_struct_sig(ostream& out,
                                                   t_struct* tstruct,
                                                   bool is_exception) {
   const vector<t_field*>& members = tstruct->get_members();
@@ -752,7 +752,7 @@ void t_ocaml_generator::generate_ocaml_struct_sig(ofstream& out,
 /**
  * Generates the read method for a struct
  */
-void t_ocaml_generator::generate_ocaml_struct_reader(ofstream& out, t_struct* tstruct) {
+void t_ocaml_generator::generate_ocaml_struct_reader(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
   string sname = type_name(tstruct);
@@ -812,7 +812,7 @@ void t_ocaml_generator::generate_ocaml_struct_reader(ofstream& out, t_struct* ts
   indent_down();
 }
 
-void t_ocaml_generator::generate_ocaml_struct_writer(ofstream& out, t_struct* tstruct) {
+void t_ocaml_generator::generate_ocaml_struct_writer(ostream& out, t_struct* tstruct) {
   string name = tstruct->get_name();
   const vector<t_field*>& fields = tstruct->get_sorted_members();
   vector<t_field*>::const_iterator f_iter;
@@ -1309,7 +1309,7 @@ void t_ocaml_generator::generate_process_function(t_service* tservice, t_functio
 /**
  * Deserializes a field of any type.
  */
-void t_ocaml_generator::generate_deserialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_ocaml_generator::generate_deserialize_field(ostream& out, t_field* tfield, string prefix) {
   t_type* type = tfield->get_type();
 
   string name = decapitalize(tfield->get_name());
@@ -1321,7 +1321,7 @@ void t_ocaml_generator::generate_deserialize_field(ofstream& out, t_field* tfiel
 /**
  * Deserializes a field of any type.
  */
-void t_ocaml_generator::generate_deserialize_type(ofstream& out, t_type* type) {
+void t_ocaml_generator::generate_deserialize_type(ostream& out, t_type* type) {
   type = get_true_type(type);
 
   if (type->is_void()) {
@@ -1374,7 +1374,7 @@ void t_ocaml_generator::generate_deserialize_type(ofstream& out, t_type* type) {
 /**
  * Generates an unserializer for a struct, calling read()
  */
-void t_ocaml_generator::generate_deserialize_struct(ofstream& out, t_struct* tstruct) {
+void t_ocaml_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct) {
   string prefix = "";
   t_program* program = tstruct->get_program();
   if (program != NULL && program != program_) {
@@ -1388,7 +1388,7 @@ void t_ocaml_generator::generate_deserialize_struct(ofstream& out, t_struct* tst
  * Serialize a container by writing out the header followed by
  * data and then a footer.
  */
-void t_ocaml_generator::generate_deserialize_container(ofstream& out, t_type* ttype) {
+void t_ocaml_generator::generate_deserialize_container(ostream& out, t_type* ttype) {
   string size = tmp("_size");
   string ktype = tmp("_ktype");
   string vtype = tmp("_vtype");
@@ -1454,7 +1454,7 @@ void t_ocaml_generator::generate_deserialize_container(ofstream& out, t_type* tt
  * @param tfield The field to serialize
  * @param prefix Name to prepend to field name
  */
-void t_ocaml_generator::generate_serialize_field(ofstream& out, t_field* tfield, string name) {
+void t_ocaml_generator::generate_serialize_field(ostream& out, t_field* tfield, string name) {
   t_type* type = get_true_type(tfield->get_type());
 
   // Do nothing for void types
@@ -1523,12 +1523,12 @@ void t_ocaml_generator::generate_serialize_field(ofstream& out, t_field* tfield,
  * @param tstruct The struct to serialize
  * @param prefix  String prefix to attach to all fields
  */
-void t_ocaml_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_ocaml_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   (void)tstruct;
   indent(out) << prefix << "#write(oprot)";
 }
 
-void t_ocaml_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_ocaml_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
   if (ttype->is_map()) {
     indent(out) << "oprot#writeMapBegin(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ",";
     out << type_to_enum(((t_map*)ttype)->get_val_type()) << ",";
@@ -1579,7 +1579,7 @@ void t_ocaml_generator::generate_serialize_container(ofstream& out, t_type* ttyp
  * Serializes the members of a map.
  *
  */
-void t_ocaml_generator::generate_serialize_map_element(ofstream& out,
+void t_ocaml_generator::generate_serialize_map_element(ostream& out,
                                                        t_map* tmap,
                                                        string kiter,
                                                        string viter) {
@@ -1593,7 +1593,7 @@ void t_ocaml_generator::generate_serialize_map_element(ofstream& out,
 /**
  * Serializes the members of a set.
  */
-void t_ocaml_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
+void t_ocaml_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
   t_field efield(tset->get_elem_type(), iter);
   generate_serialize_field(out, &efield);
 }
@@ -1601,7 +1601,7 @@ void t_ocaml_generator::generate_serialize_set_element(ofstream& out, t_set* tse
 /**
  * Serializes the members of a list.
  */
-void t_ocaml_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string iter) {
+void t_ocaml_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter) {
   t_field efield(tlist->get_elem_type(), iter);
   generate_serialize_field(out, &efield);
 }
diff --git a/compiler/cpp/src/thrift/generate/t_oop_generator.h b/compiler/cpp/src/thrift/generate/t_oop_generator.h
index 8fb580dfd4..f8da547920 100644
--- a/compiler/cpp/src/thrift/generate/t_oop_generator.h
+++ b/compiler/cpp/src/thrift/generate/t_oop_generator.h
@@ -65,11 +65,11 @@ class t_oop_generator : public t_generator {
     return package + type->get_name();
   }
 
-  virtual void generate_java_docstring_comment(std::ofstream& out, std::string contents) {
+  virtual void generate_java_docstring_comment(std::ostream& out, std::string contents) {
     generate_docstring_comment(out, "/**\n", " * ", contents, " */\n");
   }
 
-  virtual void generate_java_doc(std::ofstream& out, t_field* field) {
+  virtual void generate_java_doc(std::ostream& out, t_field* field) {
     if (field->get_type()->is_enum()) {
       std::string combined_message = field->get_doc() + "\n@see "
                                      + get_enum_class_name(field->get_type());
@@ -82,7 +82,7 @@ class t_oop_generator : public t_generator {
   /**
    * Emits a JavaDoc comment if the provided object has a doc in Thrift
    */
-  virtual void generate_java_doc(std::ofstream& out, t_doc* tdoc) {
+  virtual void generate_java_doc(std::ostream& out, t_doc* tdoc) {
     if (tdoc->has_doc()) {
       generate_java_docstring_comment(out, tdoc->get_doc());
     }
@@ -91,7 +91,7 @@ class t_oop_generator : public t_generator {
   /**
    * Emits a JavaDoc comment if the provided function object has a doc in Thrift
    */
-  virtual void generate_java_doc(std::ofstream& out, t_function* tfunction) {
+  virtual void generate_java_doc(std::ostream& out, t_function* tfunction) {
     if (tfunction->has_doc()) {
       std::stringstream ss;
       ss << tfunction->get_doc();
diff --git a/compiler/cpp/src/thrift/generate/t_perl_generator.cc b/compiler/cpp/src/thrift/generate/t_perl_generator.cc
index 76d343e898..5a308cfea1 100644
--- a/compiler/cpp/src/thrift/generate/t_perl_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_perl_generator.cc
@@ -31,7 +31,7 @@
 #include "thrift/generate/t_oop_generator.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -87,11 +87,11 @@ class t_perl_generator : public t_oop_generator {
    */
 
   void generate_perl_struct(t_struct* tstruct, bool is_exception);
-  void generate_perl_struct_definition(std::ofstream& out,
+  void generate_perl_struct_definition(std::ostream& out,
                                        t_struct* tstruct,
                                        bool is_xception = false);
-  void generate_perl_struct_reader(std::ofstream& out, t_struct* tstruct);
-  void generate_perl_struct_writer(std::ofstream& out, t_struct* tstruct);
+  void generate_perl_struct_reader(std::ostream& out, t_struct* tstruct);
+  void generate_perl_struct_writer(std::ostream& out, t_struct* tstruct);
   void generate_perl_function_helpers(t_function* tfunction);
 
   /**
@@ -110,37 +110,37 @@ class t_perl_generator : public t_oop_generator {
    * Serialization constructs
    */
 
-  void generate_deserialize_field(std::ofstream& out,
+  void generate_deserialize_field(std::ostream& out,
                                   t_field* tfield,
                                   std::string prefix = "",
                                   bool inclass = false);
 
-  void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
+  void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
 
-  void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
+  void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
 
-  void generate_deserialize_list_element(std::ofstream& out,
+  void generate_deserialize_list_element(std::ostream& out,
                                          t_list* tlist,
                                          std::string prefix = "");
 
-  void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
+  void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
 
-  void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_serialize_map_element(std::ofstream& out,
+  void generate_serialize_map_element(std::ostream& out,
                                       t_map* tmap,
                                       std::string kiter,
                                       std::string viter);
 
-  void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
+  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
 
-  void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
+  void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
 
   /**
    * Helper rendering functions
@@ -208,10 +208,10 @@ class t_perl_generator : public t_oop_generator {
   /**
    * File streams
    */
-  std::ofstream f_types_;
-  std::ofstream f_consts_;
-  std::ofstream f_helpers_;
-  std::ofstream f_service_;
+  ofstream_with_content_based_conditional_update f_types_;
+  ofstream_with_content_based_conditional_update f_consts_;
+  ofstream_with_content_based_conditional_update f_helpers_;
+  ofstream_with_content_based_conditional_update f_service_;
 
   bool f_types_use_includes_emitted_;
 };
@@ -453,7 +453,7 @@ void t_perl_generator::generate_perl_struct(t_struct* tstruct, bool is_exception
  *
  * @param tstruct The struct definition
  */
-void t_perl_generator::generate_perl_struct_definition(ofstream& out,
+void t_perl_generator::generate_perl_struct_definition(ostream& out,
                                                        t_struct* tstruct,
                                                        bool is_exception) {
   const vector<t_field*>& members = tstruct->get_members();
@@ -531,7 +531,7 @@ void t_perl_generator::generate_perl_struct_definition(ofstream& out,
 /**
  * Generates the read() method for a struct
  */
-void t_perl_generator::generate_perl_struct_reader(ofstream& out, t_struct* tstruct) {
+void t_perl_generator::generate_perl_struct_reader(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
@@ -601,7 +601,7 @@ void t_perl_generator::generate_perl_struct_reader(ofstream& out, t_struct* tstr
 /**
  * Generates the write() method for a struct
  */
-void t_perl_generator::generate_perl_struct_writer(ofstream& out, t_struct* tstruct) {
+void t_perl_generator::generate_perl_struct_writer(ostream& out, t_struct* tstruct) {
   string name = tstruct->get_name();
   const vector<t_field*>& fields = tstruct->get_sorted_members();
   vector<t_field*>::const_iterator f_iter;
@@ -1183,7 +1183,7 @@ void t_perl_generator::generate_service_client(t_service* tservice) {
 /**
  * Deserializes a field of any type.
  */
-void t_perl_generator::generate_deserialize_field(ofstream& out,
+void t_perl_generator::generate_deserialize_field(ostream& out,
                                                   t_field* tfield,
                                                   string prefix,
                                                   bool inclass) {
@@ -1256,7 +1256,7 @@ void t_perl_generator::generate_deserialize_field(ofstream& out,
  * buffer for deserialization, and that there is a variable protocol which
  * is a reference to a TProtocol serialization object.
  */
-void t_perl_generator::generate_deserialize_struct(ofstream& out,
+void t_perl_generator::generate_deserialize_struct(ostream& out,
                                                    t_struct* tstruct,
                                                    string prefix) {
   out << indent() << "$" << prefix << " = " << perl_namespace(tstruct->get_program())
@@ -1264,7 +1264,7 @@ void t_perl_generator::generate_deserialize_struct(ofstream& out,
       << "->read($input);" << endl;
 }
 
-void t_perl_generator::generate_deserialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_perl_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) {
   scope_up(out);
 
   string size = tmp("_size");
@@ -1332,7 +1332,7 @@ void t_perl_generator::generate_deserialize_container(ofstream& out, t_type* tty
 /**
  * Generates code to deserialize a map
  */
-void t_perl_generator::generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix) {
+void t_perl_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix) {
   string key = tmp("key");
   string val = tmp("val");
   t_field fkey(tmap->get_key_type(), key);
@@ -1347,7 +1347,7 @@ void t_perl_generator::generate_deserialize_map_element(ofstream& out, t_map* tm
   indent(out) << "$" << prefix << "->{$" << key << "} = $" << val << ";" << endl;
 }
 
-void t_perl_generator::generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix) {
+void t_perl_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) {
   string elem = tmp("elem");
   t_field felem(tset->get_elem_type(), elem);
 
@@ -1358,7 +1358,7 @@ void t_perl_generator::generate_deserialize_set_element(ofstream& out, t_set* ts
   indent(out) << "$" << prefix << "->{$" << elem << "} = 1;" << endl;
 }
 
-void t_perl_generator::generate_deserialize_list_element(ofstream& out,
+void t_perl_generator::generate_deserialize_list_element(ostream& out,
                                                          t_list* tlist,
                                                          string prefix) {
   string elem = tmp("elem");
@@ -1377,7 +1377,7 @@ void t_perl_generator::generate_deserialize_list_element(ofstream& out,
  * @param tfield The field to serialize
  * @param prefix Name to prepend to field name
  */
-void t_perl_generator::generate_serialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_perl_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix) {
   t_type* type = get_true_type(tfield->get_type());
 
   // Do nothing for void types
@@ -1448,7 +1448,7 @@ void t_perl_generator::generate_serialize_field(ofstream& out, t_field* tfield,
  * @param tstruct The struct to serialize
  * @param prefix  String prefix to attach to all fields
  */
-void t_perl_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_perl_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   (void)tstruct;
   indent(out) << "$xfer += $" << prefix << "->write($output);" << endl;
 }
@@ -1456,7 +1456,7 @@ void t_perl_generator::generate_serialize_struct(ofstream& out, t_struct* tstruc
 /**
  * Writes out a container
  */
-void t_perl_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_perl_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
   scope_up(out);
 
   if (ttype->is_map()) {
@@ -1520,7 +1520,7 @@ void t_perl_generator::generate_serialize_container(ofstream& out, t_type* ttype
  * Serializes the members of a map.
  *
  */
-void t_perl_generator::generate_serialize_map_element(ofstream& out,
+void t_perl_generator::generate_serialize_map_element(ostream& out,
                                                       t_map* tmap,
                                                       string kiter,
                                                       string viter) {
@@ -1534,7 +1534,7 @@ void t_perl_generator::generate_serialize_map_element(ofstream& out,
 /**
  * Serializes the members of a set.
  */
-void t_perl_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
+void t_perl_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
   t_field efield(tset->get_elem_type(), iter);
   generate_serialize_field(out, &efield);
 }
@@ -1542,7 +1542,7 @@ void t_perl_generator::generate_serialize_set_element(ofstream& out, t_set* tset
 /**
  * Serializes the members of a list.
  */
-void t_perl_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string iter) {
+void t_perl_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter) {
   t_field efield(tlist->get_elem_type(), iter);
   generate_serialize_field(out, &efield);
 }
diff --git a/compiler/cpp/src/thrift/generate/t_php_generator.cc b/compiler/cpp/src/thrift/generate/t_php_generator.cc
index 6ab6bf8eb2..50a4415517 100644
--- a/compiler/cpp/src/thrift/generate/t_php_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_php_generator.cc
@@ -29,7 +29,7 @@
 #include "thrift/generate/t_oop_generator.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -130,26 +130,26 @@ class t_php_generator : public t_oop_generator {
    */
 
   void generate_php_struct(t_struct* tstruct, bool is_exception);
-  void generate_php_struct_definition(std::ofstream& out,
+  void generate_php_struct_definition(std::ostream& out,
                                       t_struct* tstruct,
                                       bool is_xception = false,
                                       bool is_result = false);
-  void generate_php_struct_reader(std::ofstream& out, t_struct* tstruct, bool is_result);
-  void generate_php_struct_writer(std::ofstream& out, t_struct* tstruct, bool is_result);
+  void generate_php_struct_reader(std::ostream& out, t_struct* tstruct, bool is_result);
+  void generate_php_struct_writer(std::ostream& out, t_struct* tstruct, bool is_result);
   void generate_php_function_helpers(t_service* tservice, t_function* tfunction);
-  void generate_php_struct_required_validator(ofstream& out,
+  void generate_php_struct_required_validator(ostream& out,
                                               t_struct* tstruct,
                                               std::string method_name,
                                               bool write_mode);
-  void generate_php_struct_read_validator(ofstream& out, t_struct* tstruct);
-  void generate_php_struct_write_validator(ofstream& out, t_struct* tstruct);
-  void generate_php_struct_json_serialize(ofstream& out, t_struct* tstruct, bool is_result);
+  void generate_php_struct_read_validator(ostream& out, t_struct* tstruct);
+  void generate_php_struct_write_validator(ostream& out, t_struct* tstruct);
+  void generate_php_struct_json_serialize(ostream& out, t_struct* tstruct, bool is_result);
   bool needs_php_write_validator(t_struct* tstruct, bool is_result);
   bool needs_php_read_validator(t_struct* tstruct, bool is_result);
   int get_php_num_required_fields(const vector<t_field*>& fields, bool write_mode);
 
-  void generate_php_type_spec(std::ofstream& out, t_type* t);
-  void generate_php_struct_spec(std::ofstream& out, t_struct* tstruct);
+  void generate_php_type_spec(std::ostream& out, t_type* t);
+  void generate_php_struct_spec(std::ostream& out, t_struct* tstruct);
 
   /**
    * Service-level generation functions
@@ -160,53 +160,53 @@ class t_php_generator : public t_oop_generator {
   void generate_service_rest(t_service* tservice);
   void generate_service_client(t_service* tservice);
   void generate_service_processor(t_service* tservice);
-  void generate_process_function(std::ofstream& out, t_service* tservice, t_function* tfunction);
-  void generate_service_header(t_service* tservice, std::ofstream& file);
-  void generate_program_header(std::ofstream& file);
+  void generate_process_function(std::ostream& out, t_service* tservice, t_function* tfunction);
+  void generate_service_header(t_service* tservice, std::ostream& file);
+  void generate_program_header(std::ostream& file);
 
   /**
    * Serialization constructs
    */
 
-  void generate_deserialize_field(std::ofstream& out,
+  void generate_deserialize_field(std::ostream& out,
                                   t_field* tfield,
                                   std::string prefix = "",
                                   bool inclass = false);
 
-  void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
+  void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
 
-  void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
+  void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
 
-  void generate_deserialize_list_element(std::ofstream& out,
+  void generate_deserialize_list_element(std::ostream& out,
                                          t_list* tlist,
                                          std::string prefix = "");
 
-  void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
+  void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
 
-  void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_serialize_map_element(std::ofstream& out,
+  void generate_serialize_map_element(std::ostream& out,
                                       t_map* tmap,
                                       std::string kiter,
                                       std::string viter);
 
-  void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
+  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
 
-  void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
+  void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
 
-  void generate_php_doc(std::ofstream& out, t_doc* tdoc);
+  void generate_php_doc(std::ostream& out, t_doc* tdoc);
 
-  void generate_php_doc(std::ofstream& out, t_field* tfield);
+  void generate_php_doc(std::ostream& out, t_field* tfield);
 
-  void generate_php_doc(std::ofstream& out, t_function* tfunction);
+  void generate_php_doc(std::ostream& out, t_function* tfunction);
 
-  void generate_php_docstring_comment(std::ofstream& out, string contents);
+  void generate_php_docstring_comment(std::ostream& out, string contents);
 
   /**
    * Helper rendering functions
@@ -357,8 +357,8 @@ class t_php_generator : public t_oop_generator {
   /**
    * File streams
    */
-  std::ofstream f_types_;
-  std::ofstream f_service_;
+  ofstream_with_content_based_conditional_update f_types_;
+  ofstream_with_content_based_conditional_update f_service_;
 
   std::string package_dir_;
   /**
@@ -477,7 +477,7 @@ void t_php_generator::generate_typedef(t_typedef* ttypedef) {
 /**
  * Generates service header contains namespace suffix and includes inside file specified
  */
-void t_php_generator::generate_service_header(t_service* tservice, std::ofstream& file) {
+void t_php_generator::generate_service_header(t_service* tservice, std::ostream& file) {
   file << "<?php" << endl;
   if (!php_namespace_suffix(tservice->get_program()).empty()) {
     file << "namespace " << php_namespace_suffix(tservice->get_program()) << ";" << endl
@@ -491,7 +491,7 @@ void t_php_generator::generate_service_header(t_service* tservice, std::ofstream
 /**
  * Generates program header contains namespace suffix and includes inside file specified
  */
-void t_php_generator::generate_program_header(std::ofstream& file) {
+void t_php_generator::generate_program_header(std::ostream& file) {
   file << "<?php" << endl;
   if (!php_namespace_suffix(get_program()).empty()) {
     file << "namespace " << php_namespace_suffix(get_program()) << ";" << endl
@@ -509,7 +509,7 @@ void t_php_generator::generate_program_header(std::ofstream& file) {
  * @param tenum The enumeration
  */
 void t_php_generator::generate_enum(t_enum* tenum) {
-  std::ofstream& f_enum = f_types_;
+  ofstream_with_content_based_conditional_update& f_enum = f_types_;
   if (!classmap_) {
     string f_enum_name = package_dir_ + tenum->get_name() + ".php";
     f_enum.open(f_enum_name.c_str());
@@ -563,7 +563,7 @@ void t_php_generator::generate_consts(vector<t_const*> consts) {
   // Create class only if needed
   if (consts.size() > 0) {
 
-    std::ofstream& f_consts = f_types_;
+    ofstream_with_content_based_conditional_update& f_consts = f_types_;
     if (!classmap_) {
       string f_consts_name = package_dir_ + "Constant.php";
       f_consts.open(f_consts_name.c_str());
@@ -730,7 +730,7 @@ void t_php_generator::generate_xception(t_struct* txception) {
  * Structs can be normal or exceptions.
  */
 void t_php_generator::generate_php_struct(t_struct* tstruct, bool is_exception) {
-  std::ofstream& f_struct = f_types_;
+  ofstream_with_content_based_conditional_update& f_struct = f_types_;
   if (!classmap_) {
     string f_struct_name = package_dir_ + tstruct->get_name() + ".php";
     f_struct.open(f_struct_name.c_str());
@@ -742,7 +742,7 @@ void t_php_generator::generate_php_struct(t_struct* tstruct, bool is_exception)
   }
 }
 
-void t_php_generator::generate_php_type_spec(ofstream& out, t_type* t) {
+void t_php_generator::generate_php_type_spec(ostream& out, t_type* t) {
   t = get_true_type(t);
   indent(out) << "'type' => " << type_to_enum(t) << "," << endl;
 
@@ -788,7 +788,7 @@ void t_php_generator::generate_php_type_spec(ofstream& out, t_type* t) {
  * Generates the struct specification structure, which fully qualifies enough
  * type information to generalize serialization routines.
  */
-void t_php_generator::generate_php_struct_spec(ofstream& out, t_struct* tstruct) {
+void t_php_generator::generate_php_struct_spec(ostream& out, t_struct* tstruct) {
   indent(out) << "static public $_TSPEC = array(" << endl;
   indent_up();
 
@@ -816,7 +816,7 @@ void t_php_generator::generate_php_struct_spec(ofstream& out, t_struct* tstruct)
  *
  * @param tstruct The struct definition
  */
-void t_php_generator::generate_php_struct_definition(ofstream& out,
+void t_php_generator::generate_php_struct_definition(ostream& out,
                                                      t_struct* tstruct,
                                                      bool is_exception,
                                                      bool is_result) {
@@ -924,7 +924,7 @@ void t_php_generator::generate_php_struct_definition(ofstream& out,
 /**
  * Generates the read() method for a struct
  */
-void t_php_generator::generate_php_struct_reader(ofstream& out, t_struct* tstruct, bool is_result) {
+void t_php_generator::generate_php_struct_reader(ostream& out, t_struct* tstruct, bool is_result) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
@@ -1044,7 +1044,7 @@ void t_php_generator::generate_php_struct_reader(ofstream& out, t_struct* tstruc
 /**
  * Generates the write() method for a struct
  */
-void t_php_generator::generate_php_struct_writer(ofstream& out, t_struct* tstruct, bool is_result) {
+void t_php_generator::generate_php_struct_writer(ostream& out, t_struct* tstruct, bool is_result) {
   string name = tstruct->get_name();
   const vector<t_field*>& fields = tstruct->get_sorted_members();
   vector<t_field*>::const_iterator f_iter;
@@ -1132,15 +1132,15 @@ void t_php_generator::generate_php_struct_writer(ofstream& out, t_struct* tstruc
   out << indent() << "}" << endl;
 }
 
-void t_php_generator::generate_php_struct_read_validator(ofstream& out, t_struct* tstruct) {
+void t_php_generator::generate_php_struct_read_validator(ostream& out, t_struct* tstruct) {
   generate_php_struct_required_validator(out, tstruct, "_validateForRead", false);
 }
 
-void t_php_generator::generate_php_struct_write_validator(ofstream& out, t_struct* tstruct) {
+void t_php_generator::generate_php_struct_write_validator(ostream& out, t_struct* tstruct) {
   generate_php_struct_required_validator(out, tstruct, "_validateForWrite", true);
 }
 
-void t_php_generator::generate_php_struct_required_validator(ofstream& out,
+void t_php_generator::generate_php_struct_required_validator(ostream& out,
                                                              t_struct* tstruct,
                                                              std::string method_name,
                                                              bool write_mode) {
@@ -1170,7 +1170,7 @@ void t_php_generator::generate_php_struct_required_validator(ofstream& out,
   indent(out) << "}" << endl;
 }
 
-void t_php_generator::generate_php_struct_json_serialize(ofstream& out,
+void t_php_generator::generate_php_struct_json_serialize(ostream& out,
                                                          t_struct* tstruct,
                                                          bool is_result) {
   indent(out) << "public function jsonSerialize() {" << endl;
@@ -1280,7 +1280,7 @@ void t_php_generator::generate_service(t_service* tservice) {
  * @param tservice The service to generate a server for.
  */
 void t_php_generator::generate_service_processor(t_service* tservice) {
-  std::ofstream& f_service_processor = f_service_;
+  ofstream_with_content_based_conditional_update& f_service_processor = f_service_;
   if (!classmap_) {
     string f_service_processor_name = package_dir_ + service_name_ + "Processor.php";
     f_service_processor.open(f_service_processor_name.c_str());
@@ -1386,7 +1386,7 @@ void t_php_generator::generate_service_processor(t_service* tservice) {
  *
  * @param tfunction The function to write a dispatcher for
  */
-void t_php_generator::generate_process_function(std::ofstream& out, t_service* tservice, t_function* tfunction) {
+void t_php_generator::generate_process_function(std::ostream& out, t_service* tservice, t_function* tfunction) {
   // Open function
   out << indent() << "protected function process_" << tfunction->get_name() << "($seqid, $input, $output)" << endl
       << indent() << "{" << endl;
@@ -1544,7 +1544,7 @@ void t_php_generator::generate_service_helpers(t_service* tservice) {
   vector<t_function*> functions = tservice->get_functions();
   vector<t_function*>::iterator f_iter;
 
-  std::ofstream& f_struct_definition = f_service_;
+  ofstream_with_content_based_conditional_update& f_struct_definition = f_service_;
   if (classmap_) {
     f_struct_definition << "// HELPER FUNCTIONS AND STRUCTURES" << endl << endl;
   }
@@ -1590,7 +1590,7 @@ void t_php_generator::generate_php_function_helpers(t_service* tservice, t_funct
       result.append(*f_iter);
     }
 
-    std::ofstream& f_struct_helper = f_service_;
+    ofstream_with_content_based_conditional_update& f_struct_helper = f_service_;
     if (!classmap_) {
       string f_struct_helper_name = package_dir_ + result.get_name() + ".php";
       f_struct_helper.open(f_struct_helper_name.c_str());
@@ -1609,7 +1609,7 @@ void t_php_generator::generate_php_function_helpers(t_service* tservice, t_funct
  * @param tservice The service to generate a header definition for
  */
 void t_php_generator::generate_service_interface(t_service* tservice) {
-  std::ofstream& f_service_interface = f_service_;
+  ofstream_with_content_based_conditional_update& f_service_interface = f_service_;
   if (!classmap_) {
     string f_service_interface_name = package_dir_ + service_name_ + "If.php";
     f_service_interface.open(f_service_interface_name.c_str());
@@ -1648,7 +1648,7 @@ void t_php_generator::generate_service_interface(t_service* tservice) {
  * Generates a REST interface
  */
 void t_php_generator::generate_service_rest(t_service* tservice) {
-  std::ofstream& f_service_rest = f_service_;
+  ofstream_with_content_based_conditional_update& f_service_rest = f_service_;
   if (!classmap_) {
     string f_service_rest_name = package_dir_ + service_name_ + "Rest.php";
     f_service_rest.open(f_service_rest_name.c_str());
@@ -1729,7 +1729,7 @@ void t_php_generator::generate_service_rest(t_service* tservice) {
  * @param tservice The service to generate a server for.
  */
 void t_php_generator::generate_service_client(t_service* tservice) {
-  std::ofstream& f_service_client = f_service_;
+  ofstream_with_content_based_conditional_update& f_service_client = f_service_;
   if (!classmap_) {
     string f_service_client_name = package_dir_ + service_name_ + "Client.php";
     f_service_client.open(f_service_client_name.c_str());
@@ -1993,7 +1993,7 @@ void t_php_generator::generate_service_client(t_service* tservice) {
 /**
  * Deserializes a field of any type.
  */
-void t_php_generator::generate_deserialize_field(ofstream& out,
+void t_php_generator::generate_deserialize_field(ostream& out,
                                                  t_field* tfield,
                                                  string prefix,
                                                  bool inclass) {
@@ -2125,13 +2125,13 @@ void t_php_generator::generate_deserialize_field(ofstream& out,
  * buffer for deserialization, and that there is a variable protocol which
  * is a reference to a TProtocol serialization object.
  */
-void t_php_generator::generate_deserialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_php_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   out << indent() << "$" << prefix << " = new " << php_namespace(tstruct->get_program())
       << tstruct->get_name() << "();" << endl << indent() << "$xfer += $" << prefix
       << "->read($input);" << endl;
 }
 
-void t_php_generator::generate_deserialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_php_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) {
   string size = tmp("_size");
   string ktype = tmp("_ktype");
   string vtype = tmp("_vtype");
@@ -2208,7 +2208,7 @@ void t_php_generator::generate_deserialize_container(ofstream& out, t_type* ttyp
 /**
  * Generates code to deserialize a map
  */
-void t_php_generator::generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix) {
+void t_php_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix) {
   string key = tmp("key");
   string val = tmp("val");
   t_field fkey(tmap->get_key_type(), key);
@@ -2223,7 +2223,7 @@ void t_php_generator::generate_deserialize_map_element(ofstream& out, t_map* tma
   indent(out) << "$" << prefix << "[$" << key << "] = $" << val << ";" << endl;
 }
 
-void t_php_generator::generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix) {
+void t_php_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) {
   string elem = tmp("elem");
   t_field felem(tset->get_elem_type(), elem);
 
@@ -2239,7 +2239,7 @@ void t_php_generator::generate_deserialize_set_element(ofstream& out, t_set* tse
   }
 }
 
-void t_php_generator::generate_deserialize_list_element(ofstream& out,
+void t_php_generator::generate_deserialize_list_element(ostream& out,
                                                         t_list* tlist,
                                                         string prefix) {
   string elem = tmp("elem");
@@ -2258,7 +2258,7 @@ void t_php_generator::generate_deserialize_list_element(ofstream& out,
  * @param tfield The field to serialize
  * @param prefix Name to prepend to field name
  */
-void t_php_generator::generate_serialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_php_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix) {
   t_type* type = get_true_type(tfield->get_type());
 
   // Do nothing for void types
@@ -2363,7 +2363,7 @@ void t_php_generator::generate_serialize_field(ofstream& out, t_field* tfield, s
  * @param tstruct The struct to serialize
  * @param prefix  String prefix to attach to all fields
  */
-void t_php_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_php_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   (void)tstruct;
   indent(out) << "$xfer += $" << prefix << "->write($output);" << endl;
 }
@@ -2371,7 +2371,7 @@ void t_php_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct
 /**
  * Writes out a container
  */
-void t_php_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_php_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
   if (ttype->is_map()) {
     if (binary_inline_) {
       out << indent() << "$output .= pack('c', " << type_to_enum(((t_map*)ttype)->get_key_type())
@@ -2451,7 +2451,7 @@ void t_php_generator::generate_serialize_container(ofstream& out, t_type* ttype,
  * Serializes the members of a map.
  *
  */
-void t_php_generator::generate_serialize_map_element(ofstream& out,
+void t_php_generator::generate_serialize_map_element(ostream& out,
                                                      t_map* tmap,
                                                      string kiter,
                                                      string viter) {
@@ -2465,7 +2465,7 @@ void t_php_generator::generate_serialize_map_element(ofstream& out,
 /**
  * Serializes the members of a set.
  */
-void t_php_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
+void t_php_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
   t_field efield(tset->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "");
 }
@@ -2473,7 +2473,7 @@ void t_php_generator::generate_serialize_set_element(ofstream& out, t_set* tset,
 /**
  * Serializes the members of a list.
  */
-void t_php_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string iter) {
+void t_php_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter) {
   t_field efield(tlist->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "");
 }
@@ -2481,14 +2481,14 @@ void t_php_generator::generate_serialize_list_element(ofstream& out, t_list* tli
 /**
  * Emits a PHPDoc comment for the given contents
  */
-void t_php_generator::generate_php_docstring_comment(ofstream& out, string contents) {
+void t_php_generator::generate_php_docstring_comment(ostream& out, string contents) {
   generate_docstring_comment(out, "/**\n", " * ", contents, " */\n");
 }
 
 /**
  * Emits a PHPDoc comment if the provided object has a doc in Thrift
  */
-void t_php_generator::generate_php_doc(ofstream& out, t_doc* tdoc) {
+void t_php_generator::generate_php_doc(ostream& out, t_doc* tdoc) {
   if (tdoc->has_doc()) {
     generate_php_docstring_comment(out, tdoc->get_doc());
   }
@@ -2497,7 +2497,7 @@ void t_php_generator::generate_php_doc(ofstream& out, t_doc* tdoc) {
 /**
  * Emits a PHPDoc comment for a field
  */
-void t_php_generator::generate_php_doc(ofstream& out, t_field* field) {
+void t_php_generator::generate_php_doc(ostream& out, t_field* field) {
   stringstream ss;
 
   // prepend free-style doc if available
@@ -2515,7 +2515,7 @@ void t_php_generator::generate_php_doc(ofstream& out, t_field* field) {
 /**
  * Emits a PHPDoc comment for a function
  */
-void t_php_generator::generate_php_doc(ofstream& out, t_function* function) {
+void t_php_generator::generate_php_doc(ostream& out, t_function* function) {
   stringstream ss;
   if (function->has_doc()) {
     ss << function->get_doc() << endl;
diff --git a/compiler/cpp/src/thrift/generate/t_py_generator.cc b/compiler/cpp/src/thrift/generate/t_py_generator.cc
index f8692bbafa..fba9f9daa5 100644
--- a/compiler/cpp/src/thrift/generate/t_py_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_py_generator.cc
@@ -34,7 +34,7 @@
 #include "thrift/generate/t_generator.h"
 
 using std::map;
-using std::ofstream;
+using std::ostream;
 using std::ostringstream;
 using std::string;
 using std::stringstream;
@@ -167,13 +167,13 @@ class t_py_generator : public t_generator {
    */
 
   void generate_py_struct(t_struct* tstruct, bool is_exception);
-  void generate_py_thrift_spec(std::ofstream& out, t_struct* tstruct, bool is_exception);
-  void generate_py_struct_definition(std::ofstream& out,
+  void generate_py_thrift_spec(std::ostream& out, t_struct* tstruct, bool is_exception);
+  void generate_py_struct_definition(std::ostream& out,
                                      t_struct* tstruct,
                                      bool is_xception = false);
-  void generate_py_struct_reader(std::ofstream& out, t_struct* tstruct);
-  void generate_py_struct_writer(std::ofstream& out, t_struct* tstruct);
-  void generate_py_struct_required_validator(std::ofstream& out, t_struct* tstruct);
+  void generate_py_struct_reader(std::ostream& out, t_struct* tstruct);
+  void generate_py_struct_writer(std::ostream& out, t_struct* tstruct);
+  void generate_py_struct_required_validator(std::ostream& out, t_struct* tstruct);
   void generate_py_function_helpers(t_function* tfunction);
 
   /**
@@ -191,47 +191,47 @@ class t_py_generator : public t_generator {
    * Serialization constructs
    */
 
-  void generate_deserialize_field(std::ofstream& out,
+  void generate_deserialize_field(std::ostream& out,
                                   t_field* tfield,
                                   std::string prefix = "");
 
-  void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
+  void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
 
-  void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
+  void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
 
-  void generate_deserialize_list_element(std::ofstream& out,
+  void generate_deserialize_list_element(std::ostream& out,
                                          t_list* tlist,
                                          std::string prefix = "");
 
-  void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
+  void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
 
-  void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
+  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
 
-  void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
+  void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
 
-  void generate_serialize_map_element(std::ofstream& out,
+  void generate_serialize_map_element(std::ostream& out,
                                       t_map* tmap,
                                       std::string kiter,
                                       std::string viter);
 
-  void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
+  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
 
-  void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
+  void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
 
-  void generate_python_docstring(std::ofstream& out, t_struct* tstruct);
+  void generate_python_docstring(std::ostream& out, t_struct* tstruct);
 
-  void generate_python_docstring(std::ofstream& out, t_function* tfunction);
+  void generate_python_docstring(std::ostream& out, t_function* tfunction);
 
-  void generate_python_docstring(std::ofstream& out,
+  void generate_python_docstring(std::ostream& out,
                                  t_doc* tdoc,
                                  t_struct* tstruct,
                                  const char* subheader);
 
-  void generate_python_docstring(std::ofstream& out, t_doc* tdoc);
+  void generate_python_docstring(std::ostream& out, t_doc* tdoc);
 
   /**
    * Helper rendering functions
@@ -328,9 +328,9 @@ class t_py_generator : public t_generator {
    * File streams
    */
 
-  std::ofstream f_types_;
-  std::ofstream f_consts_;
-  std::ofstream f_service_;
+  ofstream_with_content_based_conditional_update f_types_;
+  ofstream_with_content_based_conditional_update f_consts_;
+  ofstream_with_content_based_conditional_update f_service_;
 
   std::string package_dir_;
   std::string module_;
@@ -375,7 +375,7 @@ void t_py_generator::init_generator() {
   f_consts_.open(f_consts_name.c_str());
 
   string f_init_name = package_dir_ + "/__init__.py";
-  ofstream f_init;
+  ofstream_with_content_based_conditional_update f_init;
   f_init.open(f_init_name.c_str());
   f_init << "__all__ = ['ttypes', 'constants'";
   vector<t_service*> services = program_->get_services();
@@ -678,7 +678,7 @@ void t_py_generator::generate_py_struct(t_struct* tstruct, bool is_exception) {
  *       (1, TType.LIST, 'Children', (TType.STRUCT, (Recursive, None), False), None, ),  # 1
  *   )
  */
-void t_py_generator::generate_py_thrift_spec(ofstream& out,
+void t_py_generator::generate_py_thrift_spec(ostream& out,
                                              t_struct* tstruct,
                                              bool /*is_exception*/) {
   const vector<t_field*>& sorted_members = tstruct->get_sorted_members();
@@ -721,7 +721,7 @@ void t_py_generator::generate_py_thrift_spec(ofstream& out,
  *
  * @param tstruct The struct definition
  */
-void t_py_generator::generate_py_struct_definition(ofstream& out,
+void t_py_generator::generate_py_struct_definition(ostream& out,
                                                    t_struct* tstruct,
                                                    bool is_exception) {
   const vector<t_field*>& members = tstruct->get_members();
@@ -920,7 +920,7 @@ void t_py_generator::generate_py_struct_definition(ofstream& out,
 /**
  * Generates the read method for a struct
  */
-void t_py_generator::generate_py_struct_reader(ofstream& out, t_struct* tstruct) {
+void t_py_generator::generate_py_struct_reader(ostream& out, t_struct* tstruct) {
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
@@ -1025,7 +1025,7 @@ void t_py_generator::generate_py_struct_reader(ofstream& out, t_struct* tstruct)
   out << endl;
 }
 
-void t_py_generator::generate_py_struct_writer(ofstream& out, t_struct* tstruct) {
+void t_py_generator::generate_py_struct_writer(ostream& out, t_struct* tstruct) {
   string name = tstruct->get_name();
   const vector<t_field*>& fields = tstruct->get_sorted_members();
   vector<t_field*>::const_iterator f_iter;
@@ -1071,7 +1071,7 @@ void t_py_generator::generate_py_struct_writer(ofstream& out, t_struct* tstruct)
   generate_py_struct_required_validator(out, tstruct);
 }
 
-void t_py_generator::generate_py_struct_required_validator(ofstream& out, t_struct* tstruct) {
+void t_py_generator::generate_py_struct_required_validator(ostream& out, t_struct* tstruct) {
   indent(out) << "def validate(self):" << endl;
   indent_up();
 
@@ -1584,7 +1584,7 @@ void t_py_generator::generate_service_remote(t_service* tservice) {
   vector<t_function*>::iterator f_iter;
 
   string f_remote_name = package_dir_ + "/" + service_name_ + "-remote";
-  ofstream f_remote;
+  ofstream_with_content_based_conditional_update f_remote;
   f_remote.open(f_remote_name.c_str());
 
   f_remote <<
@@ -2157,7 +2157,7 @@ void t_py_generator::generate_process_function(t_service* tservice, t_function*
 /**
  * Deserializes a field of any type.
  */
-void t_py_generator::generate_deserialize_field(ofstream& out,
+void t_py_generator::generate_deserialize_field(ostream& out,
                                                 t_field* tfield,
                                                 string prefix) {
   t_type* type = get_true_type(tfield->get_type());
@@ -2225,7 +2225,7 @@ void t_py_generator::generate_deserialize_field(ofstream& out,
 /**
  * Generates an unserializer for a struct, calling read()
  */
-void t_py_generator::generate_deserialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_py_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   if (is_immutable(tstruct)) {
     out << indent() << prefix << " = " << type_name(tstruct) << ".read(iprot)" << endl;
   } else {
@@ -2238,7 +2238,7 @@ void t_py_generator::generate_deserialize_struct(ofstream& out, t_struct* tstruc
  * Serialize a container by writing out the header followed by
  * data and then a footer.
  */
-void t_py_generator::generate_deserialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_py_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) {
   string size = tmp("_size");
   string ktype = tmp("_ktype");
   string vtype = tmp("_vtype");
@@ -2300,7 +2300,7 @@ void t_py_generator::generate_deserialize_container(ofstream& out, t_type* ttype
 /**
  * Generates code to deserialize a map
  */
-void t_py_generator::generate_deserialize_map_element(ofstream& out, t_map* tmap, string prefix) {
+void t_py_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix) {
   string key = tmp("_key");
   string val = tmp("_val");
   t_field fkey(tmap->get_key_type(), key);
@@ -2315,7 +2315,7 @@ void t_py_generator::generate_deserialize_map_element(ofstream& out, t_map* tmap
 /**
  * Write a set element
  */
-void t_py_generator::generate_deserialize_set_element(ofstream& out, t_set* tset, string prefix) {
+void t_py_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) {
   string elem = tmp("_elem");
   t_field felem(tset->get_elem_type(), elem);
 
@@ -2327,7 +2327,7 @@ void t_py_generator::generate_deserialize_set_element(ofstream& out, t_set* tset
 /**
  * Write a list element
  */
-void t_py_generator::generate_deserialize_list_element(ofstream& out,
+void t_py_generator::generate_deserialize_list_element(ostream& out,
                                                        t_list* tlist,
                                                        string prefix) {
   string elem = tmp("_elem");
@@ -2344,7 +2344,7 @@ void t_py_generator::generate_deserialize_list_element(ofstream& out,
  * @param tfield The field to serialize
  * @param prefix Name to prepend to field name
  */
-void t_py_generator::generate_serialize_field(ofstream& out, t_field* tfield, string prefix) {
+void t_py_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix) {
   t_type* type = get_true_type(tfield->get_type());
 
   // Do nothing for void types
@@ -2416,12 +2416,12 @@ void t_py_generator::generate_serialize_field(ofstream& out, t_field* tfield, st
  * @param tstruct The struct to serialize
  * @param prefix  String prefix to attach to all fields
  */
-void t_py_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) {
+void t_py_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
   (void)tstruct;
   indent(out) << prefix << ".write(oprot)" << endl;
 }
 
-void t_py_generator::generate_serialize_container(ofstream& out, t_type* ttype, string prefix) {
+void t_py_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
   if (ttype->is_map()) {
     indent(out) << "oprot.writeMapBegin(" << type_to_enum(((t_map*)ttype)->get_key_type()) << ", "
                 << type_to_enum(((t_map*)ttype)->get_val_type()) << ", "
@@ -2469,7 +2469,7 @@ void t_py_generator::generate_serialize_container(ofstream& out, t_type* ttype,
  * Serializes the members of a map.
  *
  */
-void t_py_generator::generate_serialize_map_element(ofstream& out,
+void t_py_generator::generate_serialize_map_element(ostream& out,
                                                     t_map* tmap,
                                                     string kiter,
                                                     string viter) {
@@ -2483,7 +2483,7 @@ void t_py_generator::generate_serialize_map_element(ofstream& out,
 /**
  * Serializes the members of a set.
  */
-void t_py_generator::generate_serialize_set_element(ofstream& out, t_set* tset, string iter) {
+void t_py_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
   t_field efield(tset->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "");
 }
@@ -2491,7 +2491,7 @@ void t_py_generator::generate_serialize_set_element(ofstream& out, t_set* tset,
 /**
  * Serializes the members of a list.
  */
-void t_py_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, string iter) {
+void t_py_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter) {
   t_field efield(tlist->get_elem_type(), iter);
   generate_serialize_field(out, &efield, "");
 }
@@ -2499,21 +2499,21 @@ void t_py_generator::generate_serialize_list_element(ofstream& out, t_list* tlis
 /**
  * Generates the docstring for a given struct.
  */
-void t_py_generator::generate_python_docstring(ofstream& out, t_struct* tstruct) {
+void t_py_generator::generate_python_docstring(ostream& out, t_struct* tstruct) {
   generate_python_docstring(out, tstruct, tstruct, "Attributes");
 }
 
 /**
  * Generates the docstring for a given function.
  */
-void t_py_generator::generate_python_docstring(ofstream& out, t_function* tfunction) {
+void t_py_generator::generate_python_docstring(ostream& out, t_function* tfunction) {
   generate_python_docstring(out, tfunction, tfunction->get_arglist(), "Parameters");
 }
 
 /**
  * Generates the docstring for a struct or function.
  */
-void t_py_generator::generate_python_docstring(ofstream& out,
+void t_py_generator::generate_python_docstring(ostream& out,
                                                t_doc* tdoc,
                                                t_struct* tstruct,
                                                const char* subheader) {
@@ -2551,7 +2551,7 @@ void t_py_generator::generate_python_docstring(ofstream& out,
 /**
  * Generates the docstring for a generic object.
  */
-void t_py_generator::generate_python_docstring(ofstream& out, t_doc* tdoc) {
+void t_py_generator::generate_python_docstring(ostream& out, t_doc* tdoc) {
   if (tdoc->has_doc()) {
     generate_docstring_comment(out, "\"\"\"\n", "", tdoc->get_doc(), "\"\"\"\n");
   }
diff --git a/compiler/cpp/src/thrift/generate/t_rs_generator.cc b/compiler/cpp/src/thrift/generate/t_rs_generator.cc
index 6001d8f660..df75d075e0 100644
--- a/compiler/cpp/src/thrift/generate/t_rs_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_rs_generator.cc
@@ -100,7 +100,7 @@ class t_rs_generator : public t_generator {
   string gen_dir_;
 
   // File to which generated code is written.
-  std::ofstream f_gen_;
+  ofstream_with_content_based_conditional_update f_gen_;
 
   // Write the common compiler attributes and module includes to the top of the auto-generated file.
   void render_attributes_and_includes();
diff --git a/compiler/cpp/src/thrift/generate/t_st_generator.cc b/compiler/cpp/src/thrift/generate/t_st_generator.cc
index c45666ad94..595a9497d5 100644
--- a/compiler/cpp/src/thrift/generate/t_st_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_st_generator.cc
@@ -93,8 +93,8 @@ class t_st_generator : public t_oop_generator {
    * Struct generation code
    */
 
-  void generate_st_struct(std::ofstream& out, t_struct* tstruct, bool is_exception);
-  void generate_accessors(std::ofstream& out, t_struct* tstruct);
+  void generate_st_struct(std::ostream& out, t_struct* tstruct, bool is_exception);
+  void generate_accessors(std::ostream& out, t_struct* tstruct);
 
   /**
    * Service-level generation functions
@@ -124,15 +124,15 @@ class t_st_generator : public t_oop_generator {
 
   std::string st_autogen_comment();
 
-  void st_class_def(std::ofstream& out, std::string name);
-  void st_method(std::ofstream& out, std::string cls, std::string name);
-  void st_method(std::ofstream& out, std::string cls, std::string name, std::string category);
-  void st_close_method(std::ofstream& out);
-  void st_class_method(std::ofstream& out, std::string cls, std::string name);
-  void st_class_method(std::ofstream& out, std::string cls, std::string name, std::string category);
-  void st_setter(std::ofstream& out, std::string cls, std::string name, std::string type);
-  void st_getter(std::ofstream& out, std::string cls, std::string name);
-  void st_accessors(std::ofstream& out, std::string cls, std::string name, std::string type);
+  void st_class_def(std::ostream& out, std::string name);
+  void st_method(std::ostream& out, std::string cls, std::string name);
+  void st_method(std::ostream& out, std::string cls, std::string name, std::string category);
+  void st_close_method(std::ostream& out);
+  void st_class_method(std::ostream& out, std::string cls, std::string name);
+  void st_class_method(std::ostream& out, std::string cls, std::string name, std::string category);
+  void st_setter(std::ostream& out, std::string cls, std::string name, std::string type);
+  void st_getter(std::ostream& out, std::string cls, std::string name);
+  void st_accessors(std::ostream& out, std::string cls, std::string name, std::string type);
 
   std::string class_name();
   static bool is_valid_namespace(const std::string& sub_namespace);
@@ -156,7 +156,7 @@ class t_st_generator : public t_oop_generator {
    * File streams
    */
   int temporary_var;
-  std::ofstream f_;
+  ofstream_with_content_based_conditional_update f_;
 };
 
 /**
@@ -250,7 +250,7 @@ void t_st_generator::generate_typedef(t_typedef* ttypedef) {
   (void)ttypedef;
 }
 
-void t_st_generator::st_class_def(std::ofstream& out, string name) {
+void t_st_generator::st_class_def(std::ostream& out, string name) {
   out << "Object subclass: #" << prefix(name) << endl;
   indent_up();
   out << indent() << "instanceVariableNames: ''" << endl << indent() << "classVariableNames: ''"
@@ -258,19 +258,19 @@ void t_st_generator::st_class_def(std::ofstream& out, string name) {
       << generated_category() << "'!" << endl << endl;
 }
 
-void t_st_generator::st_method(std::ofstream& out, string cls, string name) {
+void t_st_generator::st_method(std::ostream& out, string cls, string name) {
   st_method(out, cls, name, "as yet uncategorized");
 }
 
-void t_st_generator::st_class_method(std::ofstream& out, string cls, string name) {
+void t_st_generator::st_class_method(std::ostream& out, string cls, string name) {
   st_method(out, cls + " class", name);
 }
 
-void t_st_generator::st_class_method(std::ofstream& out, string cls, string name, string category) {
+void t_st_generator::st_class_method(std::ostream& out, string cls, string name, string category) {
   st_method(out, cls, name, category);
 }
 
-void t_st_generator::st_method(std::ofstream& out, string cls, string name, string category) {
+void t_st_generator::st_method(std::ostream& out, string cls, string name, string category) {
   char timestr[50];
   time_t rawtime;
   struct tm* tinfo;
@@ -286,12 +286,12 @@ void t_st_generator::st_method(std::ofstream& out, string cls, string name, stri
   out << indent();
 }
 
-void t_st_generator::st_close_method(std::ofstream& out) {
+void t_st_generator::st_close_method(std::ostream& out) {
   out << "! !" << endl << endl;
   indent_down();
 }
 
-void t_st_generator::st_setter(std::ofstream& out,
+void t_st_generator::st_setter(std::ostream& out,
                                string cls,
                                string name,
                                string type = "anObject") {
@@ -300,13 +300,13 @@ void t_st_generator::st_setter(std::ofstream& out,
   st_close_method(out);
 }
 
-void t_st_generator::st_getter(std::ofstream& out, string cls, string name) {
+void t_st_generator::st_getter(std::ostream& out, string cls, string name) {
   st_method(out, cls, name + "");
   out << "^ " << name;
   st_close_method(out);
 }
 
-void t_st_generator::st_accessors(std::ofstream& out,
+void t_st_generator::st_accessors(std::ostream& out,
                                   string cls,
                                   string name,
                                   string type = "anObject") {
@@ -490,7 +490,7 @@ void t_st_generator::generate_xception(t_struct* txception) {
 /**
  * Generates a smalltalk class to represent a struct
  */
-void t_st_generator::generate_st_struct(std::ofstream& out,
+void t_st_generator::generate_st_struct(std::ostream& out,
                                         t_struct* tstruct,
                                         bool is_exception = false) {
   const vector<t_field*>& members = tstruct->get_members();
@@ -542,7 +542,7 @@ string t_st_generator::a_type(t_type* type) {
   return prefix + capitalize(type_name(type));
 }
 
-void t_st_generator::generate_accessors(std::ofstream& out, t_struct* tstruct) {
+void t_st_generator::generate_accessors(std::ostream& out, t_struct* tstruct) {
   const vector<t_field*>& members = tstruct->get_members();
   vector<t_field*>::const_iterator m_iter;
   string type;
diff --git a/compiler/cpp/src/thrift/generate/t_swift_generator.cc b/compiler/cpp/src/thrift/generate/t_swift_generator.cc
index b6bf7e49bd..a1d3211a70 100644
--- a/compiler/cpp/src/thrift/generate/t_swift_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_swift_generator.cc
@@ -31,7 +31,6 @@
 
 using std::map;
 using std::ostream;
-using std::ofstream;
 using std::ostringstream;
 using std::set;
 using std::string;
@@ -115,34 +114,34 @@ class t_swift_generator : public t_oop_generator {
                           t_type* type,
                           t_const_value* value);
 
-  void generate_swift_struct(ofstream& out,
+  void generate_swift_struct(ostream& out,
                              t_struct* tstruct,
                              bool is_private);
 
-  void generate_swift_struct_init(ofstream& out,
+  void generate_swift_struct_init(ostream& out,
                                   t_struct* tstruct,
                                   bool all,
                                   bool is_private);
 
-  void generate_swift_struct_implementation(ofstream& out,
+  void generate_swift_struct_implementation(ostream& out,
                                             t_struct* tstruct,
                                             bool is_result,
                                             bool is_private);
-  void generate_swift_struct_hashable_extension(ofstream& out,
+  void generate_swift_struct_hashable_extension(ostream& out,
                                                 t_struct* tstruct,
                                                 bool is_private);
-  void generate_swift_struct_equatable_extension(ofstream& out,
+  void generate_swift_struct_equatable_extension(ostream& out,
                                                  t_struct* tstruct,
                                                  bool is_private);
-  void generate_swift_struct_thrift_extension(ofstream& out,
+  void generate_swift_struct_thrift_extension(ostream& out,
                                               t_struct* tstruct,
                                               bool is_result,
                                               bool is_private);
-  void generate_swift_struct_reader(ofstream& out, t_struct* tstruct, bool is_private);
+  void generate_swift_struct_reader(ostream& out, t_struct* tstruct, bool is_private);
 
 
-  void generate_swift_struct_printable_extension(ofstream& out, t_struct* tstruct);
-  void generate_swift_union_reader(ofstream& out, t_struct* tstruct);
+  void generate_swift_struct_printable_extension(ostream& out, t_struct* tstruct);
+  void generate_swift_union_reader(ostream& out, t_struct* tstruct);
 
   string function_result_helper_struct_type(t_service *tservice, t_function* tfunction);
   string function_args_helper_struct_type(t_service* tservice, t_function* tfunction);
@@ -152,28 +151,28 @@ class t_swift_generator : public t_oop_generator {
    * Service-level generation functions
    */
 
-  void generate_swift_service_protocol(ofstream& out, t_service* tservice);
-  void generate_swift_service_protocol_async(ofstream& out, t_service* tservice);
+  void generate_swift_service_protocol(ostream& out, t_service* tservice);
+  void generate_swift_service_protocol_async(ostream& out, t_service* tservice);
 
-  void generate_swift_service_client(ofstream& out, t_service* tservice);
-  void generate_swift_service_client_async(ofstream& out, t_service* tservice);
+  void generate_swift_service_client(ostream& out, t_service* tservice);
+  void generate_swift_service_client_async(ostream& out, t_service* tservice);
 
-  void generate_swift_service_client_send_function_implementation(ofstream& out,
+  void generate_swift_service_client_send_function_implementation(ostream& out,
                                                                   t_service* tservice,
                                                                   t_function* tfunction,
                                                                   bool needs_protocol);
-  void generate_swift_service_client_send_function_invocation(ofstream& out, t_function* tfunction);
-  void generate_swift_service_client_send_async_function_invocation(ofstream& out,
+  void generate_swift_service_client_send_function_invocation(ostream& out, t_function* tfunction);
+  void generate_swift_service_client_send_async_function_invocation(ostream& out,
                                                                     t_function* tfunction);
-  void generate_swift_service_client_recv_function_implementation(ofstream& out,
+  void generate_swift_service_client_recv_function_implementation(ostream& out,
                                                                   t_service* tservice,
                                                                   t_function* tfunction,
                                                                   bool needs_protocol);
-  void generate_swift_service_client_implementation(ofstream& out, t_service* tservice);
-  void generate_swift_service_client_async_implementation(ofstream& out, t_service* tservice);
+  void generate_swift_service_client_implementation(ostream& out, t_service* tservice);
+  void generate_swift_service_client_async_implementation(ostream& out, t_service* tservice);
 
-  void generate_swift_service_server(ofstream& out, t_service* tservice);
-  void generate_swift_service_server_implementation(ofstream& out, t_service* tservice);
+  void generate_swift_service_server(ostream& out, t_service* tservice);
+  void generate_swift_service_server_implementation(ostream& out, t_service* tservice);
   void generate_swift_service_helpers(t_service* tservice);
 
   /**
@@ -196,22 +195,22 @@ class t_swift_generator : public t_oop_generator {
   /** Swift 3 specific */
   string enum_case_name(t_enum_value* tenum_case, bool declaration);
   string enum_const_name(string enum_identifier);
-  void function_docstring(ofstream& out, t_function* tfunction);
-  void async_function_docstring(ofstream& out, t_function* tfunction);
-  void generate_docstring(ofstream& out, string& doc);
+  void function_docstring(ostream& out, t_function* tfunction);
+  void async_function_docstring(ostream& out, t_function* tfunction);
+  void generate_docstring(ostream& out, string& doc);
 
   /** Swift 2/Cocoa carryover */
   string promise_function_signature(t_function* tfunction);
   string function_name(t_function* tfunction);
-  void generate_old_swift_struct_writer(ofstream& out,t_struct* tstruct, bool is_private);
-  void generate_old_swift_struct_result_writer(ofstream& out, t_struct* tstruct);
+  void generate_old_swift_struct_writer(ostream& out,t_struct* tstruct, bool is_private);
+  void generate_old_swift_struct_result_writer(ostream& out, t_struct* tstruct);
 
   /** Swift 2/Cocoa backwards compatibility*/
   void generate_old_enum(t_enum* tenum);
-  void generate_old_swift_struct(ofstream& out,
+  void generate_old_swift_struct(ostream& out,
                                  t_struct* tstruct,
                                  bool is_private);
-  void generate_old_swift_service_client_async_implementation(ofstream& out,
+  void generate_old_swift_service_client_async_implementation(ostream& out,
                                                               t_service* tservice);
 
   static std::string get_real_swift_module(const t_program* program) {
@@ -273,8 +272,8 @@ class t_swift_generator : public t_oop_generator {
    * File streams
    */
 
-  ofstream f_decl_;
-  ofstream f_impl_;
+  ofstream_with_content_based_conditional_update f_decl_;
+  ofstream_with_content_based_conditional_update f_impl_;
 
   bool log_unexpected_;
   bool async_clients_;
@@ -621,7 +620,7 @@ void t_swift_generator::generate_xception(t_struct* txception) {
   generate_swift_struct_implementation(f_impl_, txception, false, false);
 }
 
-void t_swift_generator::generate_docstring(ofstream& out, string& doc) {
+void t_swift_generator::generate_docstring(ostream& out, string& doc) {
   if (doc != "") {
     std::vector<std::string> strings;
 
@@ -657,7 +656,7 @@ void t_swift_generator::generate_docstring(ofstream& out, string& doc) {
  * @param is_private
  *                Is the struct public or private
  */
-void t_swift_generator::generate_swift_struct(ofstream& out,
+void t_swift_generator::generate_swift_struct(ostream& out,
                                               t_struct* tstruct,
                                               bool is_private) {
 
@@ -735,7 +734,7 @@ void t_swift_generator::generate_swift_struct(ofstream& out,
  */
 
 
-void t_swift_generator::generate_old_swift_struct(ofstream& out,
+void t_swift_generator::generate_old_swift_struct(ostream& out,
                                                   t_struct* tstruct,
                                                   bool is_private) {
   string visibility = is_private ? "private" : "public";
@@ -787,7 +786,7 @@ void t_swift_generator::generate_old_swift_struct(ofstream& out,
  * @param is_private
  *                Is the initializer public or private
  */
-void t_swift_generator::generate_swift_struct_init(ofstream& out,
+void t_swift_generator::generate_swift_struct_init(ostream& out,
                                                    t_struct* tstruct,
                                                    bool all,
                                                    bool is_private) {
@@ -846,7 +845,7 @@ void t_swift_generator::generate_swift_struct_init(ofstream& out,
  * @param is_private
  *                Is the struct public or private
  */
-void t_swift_generator::generate_swift_struct_hashable_extension(ofstream& out,
+void t_swift_generator::generate_swift_struct_hashable_extension(ostream& out,
                                                                  t_struct* tstruct,
                                                                  bool is_private) {
 
@@ -898,7 +897,7 @@ void t_swift_generator::generate_swift_struct_hashable_extension(ofstream& out,
  * @param is_private
  *                Is the struct public or private
  */
-void t_swift_generator::generate_swift_struct_equatable_extension(ofstream& out,
+void t_swift_generator::generate_swift_struct_equatable_extension(ostream& out,
                                                                   t_struct* tstruct,
                                                                   bool is_private) {
 
@@ -960,7 +959,7 @@ void t_swift_generator::generate_swift_struct_equatable_extension(ofstream& out,
  * @param is_private
  *                Is the struct public or private
  */
-void t_swift_generator::generate_swift_struct_implementation(ofstream& out,
+void t_swift_generator::generate_swift_struct_implementation(ostream& out,
                                                              t_struct* tstruct,
                                                              bool is_result,
                                                              bool is_private) {
@@ -986,7 +985,7 @@ void t_swift_generator::generate_swift_struct_implementation(ofstream& out,
  * @param is_private
  *                Is the struct public or private
  */
-void t_swift_generator::generate_swift_struct_thrift_extension(ofstream& out,
+void t_swift_generator::generate_swift_struct_thrift_extension(ostream& out,
                                                                t_struct* tstruct,
                                                                bool is_result,
                                                                bool is_private) {
@@ -1042,7 +1041,7 @@ void t_swift_generator::generate_swift_struct_thrift_extension(ofstream& out,
   out << endl;
 }
 
-void t_swift_generator::generate_swift_union_reader(ofstream& out, t_struct* tstruct) {
+void t_swift_generator::generate_swift_union_reader(ostream& out, t_struct* tstruct) {
   indent(out) << "public static func read(from proto: TProtocol) throws -> "
               << tstruct->get_name();
   block_open(out);
@@ -1128,7 +1127,7 @@ void t_swift_generator::generate_swift_union_reader(ofstream& out, t_struct* tst
  * @param is_private
  *                Is the struct public or private
  */
-void t_swift_generator::generate_swift_struct_reader(ofstream& out,
+void t_swift_generator::generate_swift_struct_reader(ostream& out,
                                                      t_struct* tstruct,
                                                      bool is_private) {
 
@@ -1335,7 +1334,7 @@ void t_swift_generator::generate_swift_struct_reader(ofstream& out,
  * @param is_private
  *                Is the struct public or private
  */
-void t_swift_generator::generate_old_swift_struct_writer(ofstream& out,
+void t_swift_generator::generate_old_swift_struct_writer(ostream& out,
                                                          t_struct* tstruct,
                                                          bool is_private) {
 
@@ -1391,7 +1390,7 @@ void t_swift_generator::generate_old_swift_struct_writer(ofstream& out,
  *
  * @param tstruct The structure definition
  */
-void t_swift_generator::generate_old_swift_struct_result_writer(ofstream& out, t_struct* tstruct) {
+void t_swift_generator::generate_old_swift_struct_result_writer(ostream& out, t_struct* tstruct) {
 
   indent(out) << "private static func writeValue(__value: " << tstruct->get_name()
               << ", toProtocol __proto: TProtocol) throws";
@@ -1429,7 +1428,7 @@ void t_swift_generator::generate_old_swift_struct_result_writer(ofstream& out, t
  *
  * @param tstruct The struct definition
  */
-void t_swift_generator::generate_swift_struct_printable_extension(ofstream& out, t_struct* tstruct) {
+void t_swift_generator::generate_swift_struct_printable_extension(ostream& out, t_struct* tstruct) {
 
   // Allow use of debugDescription so the app can add description via a cateogory/extension
 
@@ -1595,7 +1594,7 @@ void t_swift_generator::generate_function_helpers(t_service *tservice, t_functio
  *
  * @param tservice The service to generate a protocol definition for
  */
-void t_swift_generator::generate_swift_service_protocol(ofstream& out, t_service* tservice) {
+void t_swift_generator::generate_swift_service_protocol(ostream& out, t_service* tservice) {
   if (!gen_cocoa_) {
     string doc = tservice->get_doc();
     generate_docstring(out, doc);
@@ -1644,7 +1643,7 @@ void t_swift_generator::generate_swift_service_protocol(ofstream& out, t_service
  *
  * @param tservice The service to generate a protocol definition for
  */
-void t_swift_generator::generate_swift_service_protocol_async(ofstream& out, t_service* tservice) {
+void t_swift_generator::generate_swift_service_protocol_async(ostream& out, t_service* tservice) {
   if (!gen_cocoa_) {
     string doc = tservice->get_doc();
     generate_docstring(out, doc);
@@ -1681,7 +1680,7 @@ void t_swift_generator::generate_swift_service_protocol_async(ofstream& out, t_s
  *
  * @param tservice The service to generate a client interface definition for
  */
-void t_swift_generator::generate_swift_service_client(ofstream& out, t_service* tservice) {
+void t_swift_generator::generate_swift_service_client(ostream& out, t_service* tservice) {
   if (!gen_cocoa_) {
     indent(out) << "open class " << tservice->get_name() << "Client";// : "
 
@@ -1724,7 +1723,7 @@ void t_swift_generator::generate_swift_service_client(ofstream& out, t_service*
  *
  * @param tservice The service to generate a client interface definition for
  */
-void t_swift_generator::generate_swift_service_client_async(ofstream& out, t_service* tservice) {
+void t_swift_generator::generate_swift_service_client_async(ostream& out, t_service* tservice) {
   if (!gen_cocoa_) {
     indent(out) << "open class " << tservice->get_name()
                 << "AsyncClient<Protocol: TProtocol, Factory: TAsyncTransportFactory>";// : "
@@ -1762,7 +1761,7 @@ void t_swift_generator::generate_swift_service_client_async(ofstream& out, t_ser
  *
  * @param tservice The service to generate a client interface definition for
  */
-void t_swift_generator::generate_swift_service_server(ofstream& out, t_service* tservice) {
+void t_swift_generator::generate_swift_service_server(ostream& out, t_service* tservice) {
   if (!gen_cocoa_) {
     indent(out) << "open class " << tservice->get_name() << "Processor /* " << tservice->get_name() << " */";
 
@@ -1807,7 +1806,7 @@ void t_swift_generator::generate_swift_service_server(ofstream& out, t_service*
  *                  Wether the first parameter must be a protocol or if
  *                  the protocol is to be assumed
  */
-void t_swift_generator::generate_swift_service_client_send_function_implementation(ofstream& out,
+void t_swift_generator::generate_swift_service_client_send_function_implementation(ostream& out,
                                                                                    t_service *tservice,
                                                                                    t_function* tfunction,
                                                                                    bool needs_protocol) {
@@ -1893,7 +1892,7 @@ void t_swift_generator::generate_swift_service_client_send_function_implementati
  *                  Wether the first parameter must be a protocol or if
  *                  the protocol is to be assumed
  */
-void t_swift_generator::generate_swift_service_client_recv_function_implementation(ofstream& out,
+void t_swift_generator::generate_swift_service_client_recv_function_implementation(ostream& out,
                                                                                    t_service* tservice,
                                                                                    t_function* tfunction,
                                                                                    bool needs_protocol) {
@@ -2018,7 +2017,7 @@ void t_swift_generator::generate_swift_service_client_recv_function_implementati
  *
  * @param tfunction The service to generate an implementation for
  */
-void t_swift_generator::generate_swift_service_client_send_function_invocation(ofstream& out,
+void t_swift_generator::generate_swift_service_client_send_function_invocation(ostream& out,
                                                                                t_function* tfunction) {
 
   indent(out) << "try send_" << tfunction->get_name() << "(";
@@ -2044,7 +2043,7 @@ void t_swift_generator::generate_swift_service_client_send_function_invocation(o
  *
  * @param tfunction The service to generate an implementation for
  */
-void t_swift_generator::generate_swift_service_client_send_async_function_invocation(ofstream& out,
+void t_swift_generator::generate_swift_service_client_send_async_function_invocation(ostream& out,
                                                                                      t_function* tfunction) {
 
   t_struct* arg_struct = tfunction->get_arglist();
@@ -2069,7 +2068,7 @@ void t_swift_generator::generate_swift_service_client_send_async_function_invoca
  *
  * @param tservice The service to generate an implementation for
  */
-void t_swift_generator::generate_swift_service_client_implementation(ofstream& out,
+void t_swift_generator::generate_swift_service_client_implementation(ostream& out,
                                                                      t_service* tservice) {
 
   string name = tservice->get_name() + "Client";
@@ -2121,7 +2120,7 @@ void t_swift_generator::generate_swift_service_client_implementation(ofstream& o
  *
  * @param tservice The service to generate an implementation for
  */
-void t_swift_generator::generate_swift_service_client_async_implementation(ofstream& out, t_service* tservice) {
+void t_swift_generator::generate_swift_service_client_async_implementation(ostream& out, t_service* tservice) {
   if (gen_cocoa_) {
     generate_old_swift_service_client_async_implementation(out, tservice);
     return;
@@ -2203,7 +2202,7 @@ void t_swift_generator::generate_swift_service_client_async_implementation(ofstr
   out << endl;
 }
 
-void t_swift_generator::generate_old_swift_service_client_async_implementation(ofstream& out,
+void t_swift_generator::generate_old_swift_service_client_async_implementation(ostream& out,
                                                                                t_service* tservice) {
 
   string name = tservice->get_name() + "AsyncClient";
@@ -2338,7 +2337,7 @@ void t_swift_generator::generate_old_swift_service_client_async_implementation(o
  *
  * @param tservice The service to generate an implementation for
  */
-void t_swift_generator::generate_swift_service_server_implementation(ofstream& out,
+void t_swift_generator::generate_swift_service_server_implementation(ostream& out,
                                                                      t_service* tservice) {
 
   string name = tservice->get_name() + "Processor";
@@ -2785,7 +2784,7 @@ string t_swift_generator::function_signature(t_function* tfunction) {
  * @param tfunction Function definition
  * @return String of rendered function definition
  */
-void t_swift_generator::function_docstring(ofstream& out, t_function* tfunction) {
+void t_swift_generator::function_docstring(ostream& out, t_function* tfunction) {
 
     // Generate docstring with following format:
     // /// <Description>
@@ -2840,7 +2839,7 @@ void t_swift_generator::function_docstring(ofstream& out, t_function* tfunction)
  * @param tfunction Function definition
  * @return String of rendered function definition
  */
-void t_swift_generator::async_function_docstring(ofstream& out, t_function* tfunction) {
+void t_swift_generator::async_function_docstring(ostream& out, t_function* tfunction) {
     // Generate docstring with following format:
     // /// <Description>
     // /// <empty line>
diff --git a/compiler/cpp/src/thrift/generate/t_xml_generator.cc b/compiler/cpp/src/thrift/generate/t_xml_generator.cc
index a832afd586..35fed14d84 100644
--- a/compiler/cpp/src/thrift/generate/t_xml_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_xml_generator.cc
@@ -101,7 +101,7 @@ class t_xml_generator : public t_generator {
   bool should_use_default_ns_;
   bool should_use_namespaces_;
 
-  std::ofstream f_xml_;
+  ofstream_with_content_based_conditional_update f_xml_;
 
   std::set<string> programs_;
   std::stack<string> elements_;
diff --git a/compiler/cpp/src/thrift/generate/t_xsd_generator.cc b/compiler/cpp/src/thrift/generate/t_xsd_generator.cc
index fa51ba0a87..e487ffca3b 100644
--- a/compiler/cpp/src/thrift/generate/t_xsd_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_xsd_generator.cc
@@ -103,8 +103,8 @@ class t_xsd_generator : public t_generator {
   /**
    * Output xsd/php file
    */
-  std::ofstream f_xsd_;
-  std::ofstream f_php_;
+  ofstream_with_content_based_conditional_update f_xsd_;
+  ofstream_with_content_based_conditional_update f_php_;
 
   /**
    * Output string stream


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


> Avoid updating Thrift compiler generated code if the output has not changed
> ---------------------------------------------------------------------------
>
>                 Key: THRIFT-4532
>                 URL: https://issues.apache.org/jira/browse/THRIFT-4532
>             Project: Thrift
>          Issue Type: Improvement
>          Components: Compiler (General)
>    Affects Versions: 0.11.0
>            Reporter: Buğra Gedik
>            Priority: Minor
>             Fix For: 0.12.0
>
>
> We would like to contribute an improvement to the Thrift compiler that would avoid regenerating target file(s) if they are going to be exactly the same as the ones already present in the same place. This will help when running the Thrift compiler in our build, especially in recursive mode.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)