-2

Have a slight issue that I need a second pair of eyes because I am at the point where the code is just being hacked apart instead of taking time needed to break it down.

The end goal of the program is to read in X number of files depending on users choices, take those files put them into memory all together, and then append them all to one Word file.

It is only writing out the first file. If I change to a WriteFile method it only writes out the last file. I would like it to write out all files

Any tips in the right direction would be appreciated.

private void cmdSubmit_Click(object sender, EventArgs e)
{
    SaveFileDialog saveFile = new SaveFileDialog();
    saveFile.Filter = "Word Files (*.doc)|*.doc";
    saveFile.FilterIndex = 1;
    saveFile.RestoreDirectory = true;

    string dirPath = "";
    FileStream destStream = (dynamic)null;
    MemoryStream outStream = new MemoryStream();

    if (saveFile.ShowDialog() == DialogResult.OK)
    {
        dirPath = saveFile.FileName;
        destStream = new FileStream(dirPath, FileMode.Create, FileAccess.Write);
        destStream.Close();
    }

    DirectoryInfo di = new DirectoryInfo(@"FilePath");
    FileInfo[] args = di.GetFiles("*.doc");

    foreach (object itemChecked in chkLB.CheckedItems)
    {

        //loop through checked items and add to file

        string fileStream = di.ToString() + itemChecked.ToString() + ".doc";//READ IN FILES

        FileStream inFile = File.OpenRead(fileStream); //Read the files one by one
        outStream.SetLength(inFile.Length);
        inFile.Read(outStream.GetBuffer(), 0, (int)inFile.Length);

        outStream.Flush();
        inFile.Close();

        fileSave(outStream, dirPath);

        //MessageBox.Show("Item with title: \"" + itemChecked.ToString()); Nice trick to add "" around a value

    }

    //Open File
    //Microsoft.Office.Interop.Word.Application word = new Microsoft.Office.Interop.Word.Application();
    //Document openDoc = word.Documents.Open(dirPath);
    MessageBox.Show("DONE");

}

public static void fileSave(MemoryStream memStream, string saveFile)
{

    //FileStream fileOut = File.Open(saveFile, FileMode.Append);

    if (!File.Exists(saveFile))
    {


        FileStream fileOut = new FileStream(saveFile, FileMode.OpenOrCreate, FileAccess.Write);
        //stream writter?
        memStream.WriteTo(fileOut);
        fileOut.Flush();
        fileOut.Close();
    }
    else
    {
        FileStream fileOut = new FileStream(saveFile, FileMode.Append, FileAccess.Write);

        memStream.WriteTo(fileOut);

        fileOut.Flush();
        fileOut.Close();
    }
}
Bill W
  • 1
  • 1
  • 2
  • Can you elaborate on the problem? – Ron Beyer May 15 '15 at 19:46
  • What is the issue? Any of us would be glad to help you if you could tell us what was **not working properly.** – Der Kommissar May 15 '15 at 19:47
  • Sorry, yes it is only writing out the first file. If I change to a WriteFile Method it only writes out the last file. I would like it to write out all files. – Bill W May 15 '15 at 19:48
  • You do realize, that if you get your code to work the way that you say you would like to, the result will not be a word document that can actually be opened in Word. – Alex May 15 '15 at 19:53
  • If it is easier to put it through using the word interop that is fine I was trying to limit resources for a simple task. – Bill W May 15 '15 at 19:54

3 Answers3

1

Use open XMl to merge two word files into one. AltChunk is the answer for your question. http://msdn.microsoft.com/en-us/library/documentformat.openxml.wordprocessing.altchunk.aspx

Dreamweaver
  • 1,328
  • 11
  • 21
1

There is two answer for this question.

Answer 1. If all you're doing is reading files and marge them together to a new file, you might not need to write code. You can use command:

C:\> copy x.doc+y.doc+z.doc output.doc

Now call this via Process.Start when you want.

Answer 2:

string[] files = { @"E:\x.txt", @"E:\y.txt", @"E:\z.txt" };

FileStream outputFile = new FileStream(@"E:\output.txt", FileMode.Create);

using (BinaryWriter ws = new BinaryWriter(outputFile))
{
    foreach (string file in files)
    {
        ws.Write(System.IO.File.ReadAllBytes(file));
    }
}
Nazmul
  • 575
  • 3
  • 18
0

Well...the simple way wouldn't be much more difficult than this:

public static void Concatenate( IEnumerable<FileInfo> files , FileInfo destination , bool overWriteDestination = true )
{
  FileMode mode = overWriteDestination ? FileMode.Create : FileMode.Append ;

  using ( FileStream tgt = destination.Open( mode , FileAccess.Write , FileShare.Read ) )
  {
    foreach( FileInfo file in files )
    {
      using ( FileStream src = file.Open( FileMode.Open , FileAccess.Read , FileShare.Read ) )
      {
        const int bufferSize = 64*1024; // 64k buffer OK?
        src.CopyTo( tgt , bufferSize ) ;
      }
    }
    tgt.Flush() ;
  }

  return;
}

...

DirectoryInfo dir = new DirectoryInfo( @"C:\foo") ;
FileInfo target = new FileInfo( @"C:\foo.glob") ;
Concatenate( dir.EnumerateFiles( "*.*" ) , target , true ) ;

Which will do what you ask (concatenate the files). But at the end of the day, all you've got is all the various octets concatenated together. If you're expecting a single MS Word document to result that is the functional concatenation of the pages in each file, it's not going to happen.

Easily.

That's a rather more complicated process. These might be of use:

All of these techniques make the assumption that you're working with *.docx files (which are XML) rather than the binary *.doc files. If you've got to deal with *.doc files, Good luck. You're probably better off converting them to RTF and parsing that, or converting them to *.docx.

Community
  • 1
  • 1
Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135