Как преобразовать файл JDF в PDF (удаление текста из многокодированного документа) - PullRequest
0 голосов
/ 26 апреля 2019

Я пытаюсь преобразовать файл JDF в файл PDF, используя C #.

После просмотра формата JDF ... я вижу, что файл представляет собой просто XML, помещенный в начало документа PDF.

Я пытался использовать функциональность StreamWriter / StreamReader в C #, но из-за документа PDF, также содержащего двоичные данные и переменные переводы строк (\ r \ t и \ t), созданный файл не может быть открыт как некоторые из двоичных данных искажается на PDF. Вот часть кода, который я пытался использовать без успеха.

using (StreamReader reader = new StreamReader(_jdf.FullName, Encoding.Default))
{
    using (StreamWriter writer = new StreamWriter(_pdf.FullName, false, Encoding.Default))
    {

        writer.NewLine = "\n"; //Tried without this and with \r\n

        bool IsStartOfPDF = false;
        while (!reader.EndOfStream)
        {
            var line = reader.ReadLine();

            if (line.IndexOf("%PDF-") != -1)
            {
                IsStartOfPDF = true;
            }

            if (!IsStartOfPDF)
            {
                continue;
            }

            writer.WriteLine(line);
        }
    }
}

1 Ответ

0 голосов
/ 26 апреля 2019

Я сам отвечаю на этот вопрос, так как это может быть довольно распространенной проблемой, и решение может быть информативным для других.

Поскольку документ содержит как двоичный файл, так и текст, мы не можем просто использовать StreamWriter, чтобы записать двоичный файл обратно в другой файл. Даже если вы используете StreamWriter для чтения файла, а затем запишите все содержимое в другой файл, вы поймете разницу между документами.

Вы можете использовать BinaryWriter для поиска документа, состоящего из нескольких частей, и записи каждого байта в точности так, как вы нашли его в другом документе.

//Using a Binary Reader/Writer as the PDF is multitype
using (var reader = new BinaryReader(File.Open(_file.FullName, FileMode.Open)))
{
    using (var writer = new BinaryWriter(File.Open(tempFileName.FullName, FileMode.CreateNew)))
    {

        //We are searching for the start of the PDF 
        bool searchingForstartOfPDF = true;
        var startOfPDF = "%PDF-".ToCharArray();

        //While we haven't reached the end of the stream
        while (reader.BaseStream.Position != reader.BaseStream.Length)
        {
            //If we are still searching for the start of the PDF
            if (searchingForstartOfPDF)
            {
                //Read the current Char
                var str = reader.ReadChar();

                //If it matches the start of the PDF signiture
                if (str.Equals(startOfPDF[0]))
                {
                    //Check the next few characters to see if they match
                    //keeping an eye on our current position in the stream incase something goes wrong
                    var currBasePos = reader.BaseStream.Position;
                    for (var i = 1; i < startOfPDF.Length; i++)
                    {
                        //If we found a char that isn't in the PDF signiture, then resume the while loop
                        //to start searching again from the next position
                        if (!reader.ReadChar().Equals(startOfPDF[i]))
                        {
                            reader.BaseStream.Position = currBasePos;
                            break;
                        }
                        //If we've reached the end of the PDF signiture then we've found a match
                        if (i == startOfPDF.Length - 1)
                        {
                            //Success
                            //Set the Position to the start of the PDF signiture 
                            searchingForstartOfPDF = false;
                            reader.BaseStream.Position -= startOfPDF.Length;
                            //We are no longer searching for the PDF Signiture so 
                            //the remaining bytes in the file will be directly wrote
                            //using the stream writer
                        }
                    }
                }
            }
            else
            {
                //We are writing the binary now
                writer.Write(reader.ReadByte());
            }
        }

    }
}

В этом примере кода BinaryReader используется для считывания каждого символа 1 на 1, и если он находит совпадение строки %PDF- (Начальная подпись PDF), он перемещает позицию считывателя обратно на %, а затем написать оставшийся документ, используя writer.Write(reader.ReadByte()).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...