Add getFileSize() and writeLinesToPath() to ProjectFilesystem.

Test Plan: Sandcastle builds.
diff --git a/src/com/facebook/buck/util/ProjectFilesystem.java b/src/com/facebook/buck/util/ProjectFilesystem.java
index 7197341..58f4344 100644
--- a/src/com/facebook/buck/util/ProjectFilesystem.java
+++ b/src/com/facebook/buck/util/ProjectFilesystem.java
@@ -28,9 +28,12 @@
 import com.google.common.io.ByteStreams;
 import com.google.common.io.Files;
 
+import java.io.BufferedWriter;
 import java.io.File;
+import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.Writer;
 import java.nio.file.FileVisitor;
 import java.nio.file.LinkOption;
 import java.nio.file.Path;
@@ -132,6 +135,15 @@
     return getFileForRelativePath(pathRelativeToProjectRoot).exists();
   }
 
+  public long getFileSize(Path pathRelativeToProjectRoot) throws IOException {
+    File file = getFileForRelativePath(pathRelativeToProjectRoot);
+    // TODO(mbolin): Decide if/how symlinks should be supported and add unit test.
+    if (!file.isFile()) {
+      throw new IOException("Cannot get size of " + file + " because it is not an ordinary file.");
+    }
+    return file.length();
+  }
+
   /**
    * Deletes a file specified by its path relative to the project root.
    * @param pathRelativeToProjectRoot path to the file
@@ -204,6 +216,23 @@
     mkdirs(file.getParentFile().toPath());
   }
 
+  /**
+   * Writes each line in {@code lines} with a trailing newline to a file at the specified path.
+   * <p>
+   * The parent path of {@code pathRelativeToProjectRoot} must exist.
+   */
+  public void writeLinesToPath(Iterable<String> lines, Path pathRelativeToProjectRoot)
+      throws IOException {
+    try (Writer writer = new BufferedWriter(
+        new FileWriter(
+            getFileForRelativePath(pathRelativeToProjectRoot)))) {
+      for (String line : lines) {
+        writer.write(line);
+        writer.write('\n');
+      }
+    }
+  }
+
   public void writeContentsToPath(String contents, Path pathRelativeToProjectRoot)
       throws IOException {
     Files.write(contents, getFileForRelativePath(pathRelativeToProjectRoot), Charsets.UTF_8);
diff --git a/test/com/facebook/buck/util/ProjectFilesystemTest.java b/test/com/facebook/buck/util/ProjectFilesystemTest.java
index 9bc5add..db11483 100644
--- a/test/com/facebook/buck/util/ProjectFilesystemTest.java
+++ b/test/com/facebook/buck/util/ProjectFilesystemTest.java
@@ -22,6 +22,7 @@
 
 import com.google.common.base.Charsets;
 import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
 import com.google.common.io.Files;
 
 import org.junit.Before;
@@ -32,6 +33,7 @@
 import java.io.File;
 import java.io.IOException;
 import java.nio.file.Path;
+import java.nio.file.Paths;
 
 /** Unit test for {@link ProjectFilesystem}. */
 public class ProjectFilesystemTest {
@@ -90,4 +92,27 @@
     Files.write("foo\nbar\nbaz\n", multiLineFile, Charsets.UTF_8);
     assertEquals(Optional.of("foo"), filesystem.readFirstLine("foo.txt"));
   }
+
+  @Test
+  public void testGetFileSize() throws IOException {
+    File wordsFile = tmp.newFile("words.txt");
+    String content = "Here\nare\nsome\nwords.\n";
+    Files.write(content, wordsFile, Charsets.UTF_8);
+
+    assertEquals(content.length(), filesystem.getFileSize(Paths.get("words.txt")));
+  }
+
+  @Test(expected = IOException.class)
+  public void testGetFileSizeThrowsForNonExistentFile() throws IOException {
+    filesystem.getFileSize(Paths.get("words.txt"));
+  }
+
+  @Test
+  public void testWriteLinesToPath() throws IOException {
+    Iterable<String> lines = ImmutableList.of("foo", "bar", "baz");
+    filesystem.writeLinesToPath(lines, Paths.get("lines.txt"));
+
+    String contents = Files.toString(new File(tmp.getRoot(), "lines.txt"), Charsets.UTF_8);
+    assertEquals("foo\nbar\nbaz\n", contents);
+  }
 }