How can I generate only a single PDF - c#

Below is my Code I am generating Password Protected pdf from ItextSharp.
Actually two pdf are getting generating and saving.
But i want only file to be saved.
If I use same for input and output i am getting error.
Truly appreciate your help.
Letter1 mydoc = new Letter1();
mydoc.GenerateLetter();
string WorkingFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
string InputFile = Path.Combine(WorkingFolder, "Testing1.pdf");
FileStream f = new FileStream(InputFile, FileMode.Create);
f.Write(mydoc.DocumentBytes, 0, mydoc.DocumentBytes.Length);
f.Close();
string OutputFile = Path.Combine(WorkingFolder, "TestingOut1.pdf");
using (Stream input = new FileStream(InputFile, FileMode.OpenOrCreate, FileAccess.Read, FileShare.Read))
{
using (Stream output = new FileStream(OutputFile, FileMode.Create, FileAccess.Write, FileShare.None))
{
PdfReader reader = new PdfReader(input);
PdfEncryptor.Encrypt(reader, output, true, "abc123", "secret", PdfWriter.ALLOW_SCREENREADERS);
}
}

Consider using a MemoryStream
Untested code (written in browser:)
using (MemoryStream m = new MemoryStream())
{
m.Write(mydoc.DocumentBytes, 0, mydoc.DocumentBytes.Length);
m.Seek(0, SeekOrigin.Origin);
string OutputFile = Path.Combine(WorkingFolder, "TestingOut1.pdf");
using (Stream output = new FileStream(OutputFile, FileMode.Create, FileAccess.Write, FileShare.None))
{
PdfReader reader = new PdfReader(m);
PdfEncryptor.Encrypt(reader, output, true, "abc123", "secret", PdfWriter.ALLOW_SCREENREADERS);
}
}

No need to instantiate a separate stream to read the PDF you want to encrypt. Use the PdfReader overloaded constructor that accepts a file path. Something like this:
PdfReader reader = new PdfReader(InputFile);
using (Stream output = new FileStream(
OutputFile, FileMode.Create, FileAccess.Write, FileShare.None
))
{
PdfEncryptor.Encrypt(
reader, output, true, "abc123", "secret", PdfWriter.ALLOW_SCREENREADERS
);
}

Related

Read and overwrite at the same FileStream

I'm using a FileStream to lock the File to be not writeable for other processes and also read and write to it, I'm using following method for it:
public static void ChangeOrAddLine(string newLine, string oldLine = "")
{
string filePath = "C:\\test.txt";
FileMode fm = FileMode.Create;
//FileMode fm = FileMode.OpenOrCreate;
using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read))
using (StreamReader sr = new StreamReader(fs))
using (StreamWriter sw = new StreamWriter(fs))
{
List<string> lines = sr.ReadToEnd().Split(new string[] { "\r\n" }, StringSplitOptions.None).ToList();
bool lineFound = false;
if (oldLine != "")
for (int i = 0; i < lines.Count; i++)
if (lines[i] == oldLine)
{
lines[i] = newLine;
lineFound = true;
break;
}
if (!lineFound)
lines.Add(newLine);
sw.Write(string.Join("\r\n", lines));
}
}
I want to overwrite it with the new content but i don't find the right FileMode, using FileMode.OpenOrCreate just appends the new content to the old and FileMode.Create deletes the file-content at the time, the FileStream fm has been initialized, so the file is empty.
I need to just clear the old content at the moment, when i write the new content to it without losing the write-lock on it during the method is running.
OpenOrCreate just appends ...
Because you don't reposition after the reading.
That also shows the main problem with your approach: The FileStream only has one Position, and the Reader and the Writer heavily use caching.
However, as long as you want to replace everything and really need that locking scheme:
using (FileStream fs = new FileStream(filePath,
FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read))
{
using (StreamReader sr = new StreamReader(fs))
{
... // all the reading
}
fs.Position = 0;
using (StreamWriter sw = new StreamWriter(fs))
{
sw.Write(string.Join("\r\n", lines));
}
fs.SetLength(fs.Position); // untested, something along this line
}
and maybe you have to convince the sw and sr to leave their stream open.
But I have to note that the FileShare.Read flag doesn't make too much sense in this scenario. A reader could see al sorts of inconsistent data, including torn lines and broken UTF8 characters.

Read file that's already used by another process

I have a C# app that tries to read a log file which is being written to by another app. When I try to read the file, I get IOException
"The process cannot access the file ... because it is being used by
another process."
What I tried using so far are the following, but none of them fix the problem
var log = File.ReadAllText(logPath);
var stream = new FileStream(logPath, FileMode.Open);
using (var stream = File.Open(logPath, FileMode.Open))
{
}
try this:
FileStream logFileStream = new FileStream("c:\test.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
StreamReader logFileReader = new StreamReader(logFileStream);
while (!logFileReader.EndOfStream)
{
string line = logFileReader.ReadLine();
// Your code here
}
// Clean up
logFileReader.Close();
logFileStream.Close();
edited with MethodMan's suggestions
using(FileStream logFileStream = new FileStream(#"c:\test.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using(StreamReader logFileReader = new StreamReader(logFileStream))
{
string text = logFileReader.ReadToEnd();
// Your code..
}
}
You can do nothing, if the "another app" does not use Share.Read while creating/opening the file.

Save image in Existing PDF using iTextSharp. Not Working

I am using the below mentioned code. Due to some reasons I am not able to save the image in output PDF. is there anything I am missing ?
string imageFileName = Path.Combine(Application.StartupPath, "a.jpg");
var inputpdf = Path.Combine(Application.StartupPath, "b.pdf");
var outputpdf = Path.Combine(Application.StartupPath, "output.pdf");
using (Stream inputPdfStream = new FileStream(inputpdf, FileMode.Open, FileAccess.Read,
FileShare.Read))
{
using (Stream inputImageStream = new FileStream(imageFileName, FileMode.Open,
FileAccess.Read, FileShare.Read))
{
var reader = new PdfReader(inputPdfStream);
var stamper = new PdfStamper(reader, new FileStream(outputpdf, FileMode.Create),
'\0', true);
var pdfContentByte = stamper.GetOverContent(1);
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(inputImageStream);
image.SetAbsolutePosition(10, 10);
pdfContentByte.AddImage(image);
stamper.Close();
}
}

How to output results to console instead .txt - X12 Parser?

I am testing this EDI standard: X12 Parser (link), now example in link have as result.txt. The code that does this is:
using OopFactory.X12.Parsing;
using OopFactory.X12.Parsing.Model;
namespace MyX12.Edi835Parser
{
class Program
{
static void Main(string[] args)
{
Stream transformStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("MyX12.Edi835Parser.X12-835-To-CSV.xslt");
Stream inputStream = new FileStream(args[0], FileMode.Open, FileAccess.Read);
Stream outputFile = new FileStream(args[1], FileMode.Create, FileAccess.Write);
X12Parser parser = new X12Parser();
Interchange interchange = parser.Parse(inputStream);
string xml = interchange.Serialize();
var transform = new XslCompiledTransform();
transform.Load(XmlReader.Create(transformStream));
transform.Transform(XmlReader.Create(new StringReader(xml)), new XsltArgumentList(), outputFile);
}
}
}
As you can see, the code has: Stream outputFile = new FileStream(args1 ... where args1 is in project properties / Debug set as Sample-Output.txt, which is the name of file that would be created.
Now, I want to have the result instead as Sample-Output.txt, in my console, something like this:
Stream outputFile = Console.Write();
Really thanks for help.
Console.OpenStandardOutput() acquires the standard output stream.
Try replacing
Stream outputFile = new FileStream(args[1], FileMode.Create, FileAccess.Write);
with
Stream outputFile = Console.OpenStandardOutput();

How to set copyright metadata of an existing PDF using iTextSharp for C#

How can the copyright metadata of an existing (i.e. a pdf loaded from file or memory stream) pdf file be set using iTextSharp for C#?
Thanks a lot
The native XMP structures don't have copyright implemented (or at least they don't in a way that Adobe Reader recognizes.) To do that you can reverse engineer what Adobe kicks out and write it manually:
String inputPDF = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Services.pdf");
String outputPDF = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Services_Out.pdf");
PdfReader reader = new PdfReader(inputPDF);
using (FileStream fs = new FileStream(outputPDF, FileMode.Create, FileAccess.Write, FileShare.Read))
{
using (PdfStamper stamper = new PdfStamper(reader, fs))
{
using (MemoryStream ms = new MemoryStream())
{
string CopyrightName = "YOUR NAME HERE";
string CopyrightUrl = "http://www.example.com/";
XmpWriter xmp = new XmpWriter(ms);
xmp.AddRdfDescription("xmlns:dc=\"http://purl.org/dc/elements/1.1/\"", String.Format("<dc:rights><rdf:Alt><rdf:li xml:lang=\"x-default\">{0}</rdf:li></rdf:Alt></dc:rights>", CopyrightName));
xmp.AddRdfDescription("xmlns:xmpRights=\"http://ns.adobe.com/xap/1.0/rights/\"", string.Format("<xmpRights:Marked>True</xmpRights:Marked><xmpRights:WebStatement>{0}</xmpRights:WebStatement>", CopyrightUrl));
xmp.Close();
stamper.XmpMetadata = ms.ToArray();
stamper.Close();
}
}
}

Categories