title: Problems to extract text from PDF for certain pdfs only C#
body: <p>I need to extract some data from a PDF file. 
  I'm using the <strong><code>iTextSharp</code></strong> to do that. </p>
  
  <p>I'm using this code which I founded on the net:</p>
  
  <pre><code>using System;
  using System.IO;
  using iTextSharp.text.pdf;
  
  namespace PdfToText
  {
  /// &lt;summary&gt;
  /// Parses a PDF file and extracts the text from it.
  /// &lt;/summary&gt;
  public class PDFParser
  {
      /// BT = Beginning of a text object operator 
      /// ET = End of a text object operator
      /// Td move to the start of next line
      ///  5 Ts = superscript
      /// -5 Ts = subscript
  
      #region Fields
  
      #region _numberOfCharsToKeep
      /// &lt;summary&gt;
      /// The number of characters to keep, when extracting text.
      /// &lt;/summary&gt;
      private static int _numberOfCharsToKeep = 15;
      #endregion
  
      #endregion
  
      #region ExtractText
      /// &lt;summary&gt;
      /// Extracts a text from a PDF file.
      /// &lt;/summary&gt;
      /// &lt;param name="inFileName"&gt;the full path to the pdf file.&lt;/param&gt;
      /// &lt;param name="outFileName"&gt;the output file name.&lt;/param&gt;
      /// &lt;returns&gt;the extracted text&lt;/returns&gt;
      public bool ExtractText(string inFileName, string outFileName)
      {
          StreamWriter outFile = null;
          try
          {
              outFileName = String.Empty;
  
              outFileName = Path.GetDirectoryName(System.AppDomain.CurrentDomain.BaseDirectory);
              //string currentDirectory = Directory.GetCurrentDirectory();
              //string filePath = System.IO.Path.Combine(currentDirectory, "Data", "myfile.txt");
              // extract the text
              //string test = "";
              outFileName += @"\test.txt";
              // Create a reader for the given PDF file
              PdfReader reader = new PdfReader(inFileName);
              //outFile = File.CreateText(outFileName);
              outFile = new StreamWriter(outFileName, true, System.Text.Encoding.UTF8);
  
              Console.Write("Processing: ");
  
              int totalLen = 68;
              float charUnit = ((float)totalLen) / (float)reader.NumberOfPages;
              int totalWritten = 0;
              float curUnit = 0;
  
              for (int page = 1; page &lt;= reader.NumberOfPages; page++)
              {
                  outFile.Write(ExtractTextFromPDFBytes(reader.GetPageContent(page)) + " ");
  
                  // Write the progress.
                  if (charUnit &gt;= 1.0f)
                  {
                      for (int i = 0; i &lt; (int)charUnit; i++)
                      {
                          Console.Write("#");
                          totalWritten++;
                      }
                  }
                  else
                  {
                      curUnit += charUnit;
                      if (curUnit &gt;= 1.0f)
                      {
                          for (int i = 0; i &lt; (int)curUnit; i++)
                          {
                              Console.Write("#");
                              totalWritten++;
                          }
                          curUnit = 0;
                      }
  
                  }
              }
  
              if (totalWritten &lt; totalLen)
              {
                  for (int i = 0; i &lt; (totalLen - totalWritten); i++)
                  {
                      Console.Write("#");
                  }
              }
              return true;
          }
          catch(Exception ex)
          {
              return false;
          }
          finally
          {
              if (outFile != null) outFile.Close();
          }
      }
      #endregion
  
      #region ExtractTextFromPDFBytes
      /// &lt;summary&gt;
      /// This method processes an uncompressed Adobe (text) object 
      /// and extracts text.
      /// &lt;/summary&gt;
      /// &lt;param name="input"&gt;uncompressed&lt;/param&gt;
      /// &lt;returns&gt;&lt;/returns&gt;
      private string ExtractTextFromPDFBytes(byte[] input)
      {
          if (input == null || input.Length == 0) return "";
  
          try
          {
              string resultString = "";
  
              // Flag showing if we are we currently inside a text object
              bool inTextObject = false;
  
              // Flag showing if the next character is literal 
              // e.g. '\\' to get a '\' character or '\(' to get '('
              bool nextLiteral = false;
  
              // () Bracket nesting level. Text appears inside ()
              int bracketDepth = 0;
  
              // Keep previous chars to get extract numbers etc.:
              char[] previousCharacters = new char[_numberOfCharsToKeep];
              for (int j = 0; j &lt; _numberOfCharsToKeep; j++) previousCharacters[j] = ' ';
  
  
              for (int i = 0; i &lt; input.Length; i++)
              {
                  char c = (char)input[i];
  
                  if (inTextObject)
                  {
                      // Position the text
                      if (bracketDepth == 0)
                      {
                          if (CheckToken(new string[] { "TD", "Td" }, previousCharacters))
                          {
                              resultString += "\n\r";
                          }
                          else
                          {
                              if (CheckToken(new string[] { "'", "T*", "\"" }, previousCharacters))
                              {
                                  resultString += "\n";
                              }
                              else
                              {
                                  if (CheckToken(new string[] { "Tj" }, previousCharacters))
                                  {
                                      resultString += " ";
                                  }
                              }
                          }
                      }
  
                      // End of a text object, also go to a new line.
                      if (bracketDepth == 0 &amp;&amp;
                          CheckToken(new string[] { "ET" }, previousCharacters))
                      {
  
                          inTextObject = false;
                          resultString += " ";
                      }
                      else
                      {
                          // Start outputting text
                          if ((c == '(') &amp;&amp; (bracketDepth == 0) &amp;&amp; (!nextLiteral))
                          {
                              bracketDepth = 1;
                          }
                          else
                          {
                              // Stop outputting text
                              if ((c == ')') &amp;&amp; (bracketDepth == 1) &amp;&amp; (!nextLiteral))
                              {
                                  bracketDepth = 0;
                              }
                              else
                              {
                                  // Just a normal text character:
                                  if (bracketDepth == 1)
                                  {
                                      // Only print out next character no matter what. 
                                      // Do not interpret.
                                      if (c == '\\' &amp;&amp; !nextLiteral)
                                      {
                                          nextLiteral = true;
                                      }
                                      else
                                      {
                                          if (((c &gt;= ' ') &amp;&amp; (c &lt;= '~')) ||
                                              ((c &gt;= 128) &amp;&amp; (c &lt; 255)))
                                          {
                                              resultString += c.ToString();
                                          }
  
                                          nextLiteral = false;
                                      }
                                  }
                              }
                          }
                      }
                  }
  
                  // Store the recent characters for 
                  // when we have to go back for a checking
                  for (int j = 0; j &lt; _numberOfCharsToKeep - 1; j++)
                  {
                      previousCharacters[j] = previousCharacters[j + 1];
                  }
                  previousCharacters[_numberOfCharsToKeep - 1] = c;
  
                  // Start of a text object
                  if (!inTextObject &amp;&amp; CheckToken(new string[] { "BT" }, previousCharacters))
                  {
                      inTextObject = true;
                  }
              }
              return resultString;
          }
          catch
          {
              return "";
          }
      }
      #endregion
  
      #region CheckToken
      /// &lt;summary&gt;
      /// Check if a certain 2 character token just came along (e.g. BT)
      /// &lt;/summary&gt;
      /// &lt;param name="search"&gt;the searched token&lt;/param&gt;
      /// &lt;param name="recent"&gt;the recent character array&lt;/param&gt;
      /// &lt;returns&gt;&lt;/returns&gt;
      private bool CheckToken(string[] tokens, char[] recent)
      {
          foreach (string token in tokens)
          {
              if ((recent[_numberOfCharsToKeep - 3] == token[0]) &amp;&amp;
                  (recent[_numberOfCharsToKeep - 2] == token[1]) &amp;&amp;
                  ((recent[_numberOfCharsToKeep - 1] == ' ') ||
                  (recent[_numberOfCharsToKeep - 1] == 0x0d) ||
                  (recent[_numberOfCharsToKeep - 1] == 0x0a)) &amp;&amp;
                  ((recent[_numberOfCharsToKeep - 4] == ' ') ||
                  (recent[_numberOfCharsToKeep - 4] == 0x0d) ||
                  (recent[_numberOfCharsToKeep - 4] == 0x0a))
                  )
              {
                  return true;
              }
          }
          return false;
      }
      #endregion
  }
  </code></pre>
  
  <p>}</p>
  
  <p>I'm using this way:</p>
  
  <pre><code> PDFParser pdfParser = new PDFParser();
   pdfParser.ExtractText(pdfFile,Path.GetFileNameWithoutExtension(pdfFile) + ".txt");
  </code></pre>
  
  <p>So the pdf content is written in a txt file.
  It works good for certain pdf-s, but for a pdf file that I really need to use, the txt file remains always empty. I didn't get errors, but for some reason it's not writing anything, although as you can see in this screenshot it recognize the pdf,that it has 2 pages...</p>
  
  <p><a href="https://i.stack.imgur.com/5XN0g.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/5XN0g.png" alt="enter image description here"></a></p>
  
  <p>This is the  pdf that I need but the txt always remains empty.(the black lines are added by me, so there are not present when I want to write in the txt)</p>
  
  <p><a href="https://i.stack.imgur.com/bEwfD.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/bEwfD.png" alt="enter image description here"></a></p>
  
  <p>And this is another pdf. For this the program works ok, and it is written is a txt file. It is much bigger than the other pdf, and still for this I can extract the texts and for the other I can't.</p>
  
  <p><a href="https://i.stack.imgur.com/lP1yx.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/lP1yx.png" alt="enter image description here"></a></p>
  
  <p><a href="https://i.stack.imgur.com/HEA4m.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/HEA4m.png" alt="enter image description here"></a></p>
  
  <p>Do you have any idea what can be the problem?</p>