Show / Hide Table of Contents

MSDN.WhiteKnight - Stack Overflow answers

Ответ на "Как изменить поле /Producer в pdf документе без сторонних библиотек"

Answer 1039794

Link

И хотелось бы получить полный ответ почему я немгу pdf считать в байты, затем перевести в строку

На это ответ очень прост: PDF - бинарный формат, а не текстовый. Любой код, который вызывает Encoding.GetString на содержимом PDF-файла (в целом) можно смело выбрасывать. Конечно, преобразовывать в строку отдельные его поля, которые гарантированно являются текстом, можно.

Если вам нужно просто грубо заменить вхождение /Producer (Foo) на /Producer (Bar), не учитывая структуру файла (т.е., если такая последовательность случайно встретится в содержимом файла, он будет поврежден), то можно сделать так:

using System;
using System.IO;
using System.Text;

class Program
{
    public static bool SequenceEquals(byte[] array, int position, byte[] match)
    {
        if (match.Length > (array.Length - position)) return false;

        for (int i = 0; i < match.Length; i++)
        {
            if (array[position + i] != match[i])  return false;
        }

        return true;
    }

    public static int FindSequence(byte[] arr, byte[] match, int startindex=0)
    {
        for (int i = startindex; i < arr.Length; i++)
        {
            if (SequenceEquals(arr, i, match)) return i;
        }
        return -1;
    }

    public static void Main()
    {        
        string path1 = @"C:\Test\file1.pdf";
        string path2 = @"C:\Test\file2.pdf";

        //считаем данные
        byte[] data = File.ReadAllBytes(path1);

        //подготовим последовательности для поиска
        byte[] match_start = Encoding.ASCII.GetBytes("/Producer");
        byte[] match_end = Encoding.ASCII.GetBytes(")");

        //найдем последовательность в массиве
        int index_start = FindSequence(data, match_start);           
        int index_end = FindSequence(data, match_end, index_start + 1) + 1;
        byte[] bytes_old = new byte[index_end - index_start];
        Array.Copy(data, index_start, bytes_old, 0, bytes_old.Length);
        string s_old = Encoding.ASCII.GetString(bytes_old);

        //подготовим новые данные
        string s_new = "/Producer (MyMy)";
        byte[] bytes_new = Encoding.ASCII.GetBytes(s_new);
        byte[] newdata = new byte[data.Length - bytes_old.Length + bytes_new.Length];

        //запишем результат
        Array.Copy(data, newdata, index_start);
        Array.Copy(bytes_new, 0, newdata, index_start, bytes_new.Length);
        Array.Copy(data, index_end, newdata, index_start+ bytes_new.Length, data.Length - index_end);
        File.WriteAllBytes(path2, newdata);

        Console.ReadKey();
    }
}

Корректная замена должна учитывать структуру файла в соответствии с документацией Adobe.


Content is retrieved from StackExchange API.

Auto-generated by ruso-archive tools.

Back to top Stack Overflow answers (published from sources in GitHub repository). Copyright (c) 2020, MSDN.WhiteKnight. Content licensed under BSD 3-Clause License.
Generated by DocFX