Adding a file to a node programatically I am working on a module that is transferring files from my old site (hosted on the same server) to a new drupal based site.  The files will be associated with a single content type (the content type has multipel file fields associated with it). I've written code to read a directory and then loop through the files, associating the files with the appropriate file file.  So far the files are getting transferred correctly, but they aren't being associated with the new node.  What am I missing

$result = new stdClass;
$result-&gt;type = "results";
node_object_prepare($result);

//add values to text fields here
...

//open the source directory
$d = dir($seasonDir);
while(false !== ($entry = $d-&gt;read())) {
      if($entry != "." &amp;&amp; $entry != "..") {
        //set the file location
        $fileLocation = $seasonDir . "/" . $entry;
        //get the file contents
        $fileContents = file_get_contents($fileLocation);
        //save the file
        $file = file_save_data($fileContents,'public://results/'.$entry,FILE_EXISTS_RENAME);
        //store the file for copying to a subdirectory later
        $result_files[] = $file;
        //create an array to assign to the various file fields
        $file_details = array(LANGUAGE_NONE =&gt; array('0' =&gt; (array)$file));
        switch($entry) {
          case "results.inc.html":
            $result-&gt;field_results_html = $file_details;
            break;
          case"clubs.inc.html":
            $result-&gt;field_clubs_html = $file_details;
            break;
          case "events.inc.html":
            $result-&gt;field_events_html = $file_details;
            break;
          case "index.xml":
            $result-&gt;field_results_index = $file_details;
            break;
          case "events.xml":
            $result-&gt;field_results_events = $file_details;
            break;
          case "clubs.xml":
            $result-&gt;field_results_clubs = $file_details;
            break;
          case "results.xml":
            $result-&gt;field_results = $file_details;
            break;
          default:
            //because the resuls_files field allows multiple files, this
            //field has to use a different method of assigning the file
            $result-&gt;results_files[LANGUAGE_NONE][] = (array)$file;
            break;
        }
       }
    }
    $d-&gt;close();

    node_save($result);
    //now move the files to the folder using the node ID as the subfolder
    $newdir = 'public://results/' . $result-&gt;nid;
    if(file_prepare_directory($newdir, FILE_CREATE_DIRECTORY)) {
      //move the files into this directory
      foreach($result_files as $file) {
        file_move($file, $newdir . '/' . $file-&gt;filename, FILE_EXISTS_REPLACE);
      }
    }
    else {
      drupal_set_message("could not create $newdir");
    }


At the end, all the nodes have been created, the files have been moved to the correct sub directory, but the node doesn't show any attached files.  What am I missing?
I think from what I understand; you are trying to add each file(s) to its node folder public://results/[nid]/filename.ext

As solution to your issue, first you need to save the node before you attach the file(s) to it. Then move/save file(s) to its desired location. Then attach the moved file(s) to the selected node again.

Change your code to look like the following:

$result = new stdClass;
$result-&gt;type = "results";
node_object_prepare($result);

//add values to text fields here

// save node
node_save($result);


//open the source directory

$d = dir($seasonDir);

while(false !== ($entry = $d-&gt;read())) {
  if($entry != "." &amp;&amp; $entry != "..") {

    $dir = 'public://results/' . $result-&gt;nid;  
    // create folder str 
    if(file_prepare_directory($dir, FILE_CREATE_DIRECTORY)) {

      //set the file location
      $fileLocation = $seasonDir . "/" . $entry;

      //get the file contents
      $fileContents = file_get_contents($fileLocation);

      //save the file - added nid as sub folder
      $file = file_save_data($fileContents, $dir . '/' . $entry, FILE_EXISTS_RENAME);

      // important if you are importing none image files
      $file-&gt;display = 1; 

      // you don't need to copy files to an array anymore

      // create entity object to store file(s) to the node 

      $entity = new stdClass();
      $entity-&gt;nid = $result-&gt;nid;
      $entity-&gt;vid = $result-&gt;vid;
      $entity-&gt;type  = $result-&gt;type;

      //create an array to assign to the various file fields
      $file_details = array(LANGUAGE_NONE =&gt; array('0' =&gt; (array)$file));

      switch($entry) {
        case "results.inc.html":
          $entity-&gt;field_results_html = $file_details;
          break;
        case"clubs.inc.html":
          $entity-&gt;field_clubs_html = $file_details;
          break;
        case "events.inc.html":
          $entity-&gt;field_events_html = $file_details;
          break;
        case "index.xml":
          $entity-&gt;field_results_index = $file_details;
          break;
        case "events.xml":
          $entity-&gt;field_results_events = $file_details;
          break;
        case "clubs.xml":
          $entity-&gt;field_results_clubs = $file_details;
          break;
        case "results.xml":
          $entity-&gt;field_results = $file_details;
          break;
        default:
          //because the resuls_files field allows multiple files, this
          //field has to use a different method of assigning the file
          $entity-&gt;results_files[LANGUAGE_NONE][] = (array)$file;
          break;
      }

      // save entity 
      field_attach_presave('node', $entity);
      field_attach_update('node', $entity);
    }
  }
}
$d-&gt;close();