C# Save Blob PDF to disk including embed fonts - c#

Im using StreamWriter to write the blob pdf content which i get from oracle database and save the it to disk as pdf file.
But the fonts are not included in the output file when i look at the properties. Do i have some another step to included all the fonts ?
using (var hasher = System.Security.Cryptography.MD5.Create())
{
using (var reader = comando.ExecuteReader(CommandBehavior.SequentialAccess))
{
while (reader.Read())
{
var filename = Convert.ToBase64String(hasher.ComputeHash(Blob)).Replace("=", string.Empty);
var filepath = Path.ChangeExtension(Path.Combine("C:/ttttt/", filename), ".pdf");
using (var fs = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write))
{
//reset the index to the beginning of the file
CurrentIndex = 0;
BytesReturned = reader.GetBytes(0, CurrentIndex, Blob, 0, BufferSize);
while (BytesReturned == BufferSize)
{
fs.Write(Blob, 0, Blob.Length);
CurrentIndex += BufferSize;
BytesReturned = reader.GetBytes(0, CurrentIndex, Blob, 0, BufferSize);
}
fs.Write(Blob, 0, (int)BytesReturned);
}
}
}
]

Related

C# BinaryWriter, Write with 8 bit

Im Using Binarywriter to save blob data (PDF) from oracle to disk.
The result is ugly when i open the generated file. I think its the problem of that 1 character is write with one byte.
How can i increase to write to 8. (/BitsPerComponent 8)
Any Ideas ?
long CurrentIndex = 0;
int BufferSize = 10000;
long BytesReturned;
byte[] Blob = new byte[BufferSize];
OracleDataReader reader = comando.ExecuteReader(CommandBehavior.SequentialAccess);
string filepath = "C:\\ttttt.pdf";
while (reader.Read())
{
FileStream fs = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write);
BinaryWriter writer = new BinaryWriter(fs);
//reset the index to the beginning of the file
CurrentIndex = 0;
BytesReturned = reader.GetBytes(0, CurrentIndex, Blob, 0, BufferSize);
while (BytesReturned == BufferSize)
{
writer.Write(Blob);
writer.Flush();
CurrentIndex += BufferSize;
BytesReturned = reader.GetBytes(0, CurrentIndex, Blob, 0, BufferSize);
}
writer.Write(Blob, 0, (int)BytesReturned);
writer.Flush();
writer.Close();
fs.Close();
}
You don't need a BinaryWriter for this. Just write to the stream directly. BinaryWriter's intended use case is writing primitive data types to a stream for serialization purposes.
Update: Automatically generate a filename from Base64(MD5(Blob)).
long CurrentIndex = 0;
int BufferSize = 10000;
long BytesReturned;
byte[] Blob = new byte[BufferSize];
using (var hasher = MD5.Create())
{
using (var reader = comando.ExecuteReader(CommandBehavior.SequentialAccess))
{
while (reader.Read())
{
var filename = Convert.ToBase64String(hasher.ComputeHash(Blob)).Replace("=", string.Empty);
var filepath = Path.ChangeExtension(Path.Combine("C:\\", filename), ".pdf");
using (var fs = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write))
{
//reset the index to the beginning of the file
CurrentIndex = 0;
BytesReturned = reader.GetBytes(0, CurrentIndex, Blob, 0, BufferSize);
while (BytesReturned == BufferSize)
{
fs.Write(Blob, 0, Blob.Length);
CurrentIndex += BufferSize;
BytesReturned = reader.GetBytes(0, CurrentIndex, Blob, 0, BufferSize);
}
fs.Write(Blob, 0, (int)BytesReturned);
}
}
}
}

Replicate Wave file using Naudio - Copy/Append Latest Available bytes

I have an Active wave recording wave-file.wav happening to the Source folder.
I need to replicate this file to Destination folder with a new name wave-file-copy.wav.
The recording and replication should happen in parallel.
I have implemented a scheduled job, which will run in every 10 minutes and copy the source file to destination.
private static void CopyWaveFile(string destinationFile, string sourceFile){
using (var fs = File.Open(sourceFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)){
using (var reader = new WaveFileReader(fs)){
using (var writer = new WaveFileWriter(destinationFile, reader.WaveFormat)){
reader.Position = 0;
var endPos = (int)reader.Length;
var buffer = new byte[1024];
while (reader.Position < endPos){
var bytesRequired = (int)(endPos - reader.Position);
if (bytesRequired <= 0) continue;
var bytesToRead = Math.Min(bytesRequired, buffer.Length);
var bytesRead = reader.Read(buffer, 0, bytesToRead);
if (bytesRead > 0){
writer.Write(buffer, 0, bytesRead);
}
}
}
}
}
}
The copy operation is working fine, even though the source file is being updated continuously.
Time taken for the copy operation is increasing in linear time, because i am copying the entire file every time.
I am trying to implement a new function ConcatenateWavFiles(), which should update the content of destination file, with the latest available bytes of source recording.
I have tried few sample codes - the approach i am using is :
Read destination file meta info, and get the length.
Set the length of destination file as reader.Position of source file waveReader
Read the source file till end, starting from position.
public static void ConcatenateWavFiles(string destinationFile, string sourceFile){
WaveFileWriter waveFileWriter = null;
var sourceReadOffset = GetWaveFileSize(destinationFile);
try{
using (var fs = File.Open(sourceFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (var reader = new WaveFileReader(fs))
{
waveFileWriter = new WaveFileWriter(destinationFile, reader.WaveFormat);
if (!reader.WaveFormat.Equals(waveFileWriter.WaveFormat)){
throw new InvalidOperationException(
"Can't append WAV Files that don't share the same format");
}
var startPos = sourceReadOffset - sourceReadOffset % reader.WaveFormat.BlockAlign;
var endPos = (int) reader.Length;
reader.Position = startPos;
var bytesRequired = (int)(endPos - reader.Position);
var buffer = new byte[bytesRequired];
if (bytesRequired > 0)
{
var bytesToRead = Math.Min(bytesRequired, buffer.Length);
var bytesRead = reader.Read(buffer, 0, bytesToRead);
if (bytesRead > 0)
{
waveFileWriter.Write(buffer, startPos, bytesRead);
}
}
}
}
}
finally{
if (waveFileWriter != null){
waveFileWriter.Dispose();
}
}
}
I was able to get the new content.
Is it possible to append the latest content to existing destination file?
If possible what am I doing wrong in the code?
My code throws the following exception - Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.
I couldn't find a solution to wave audio file replication with NAudio Library.
But I have implemented a solution using C# MemoryStreams and FileStreams.
Copy the Source file to destination, if destination file doesn't exist.
Append all the latest bytes (recorded after the last operation) to the destination file.
Modify the Wave File Header to to reflect the last appended bytes. (Else the duration of the file will not be updated, only the file size will increase.
Repeat this append operation in regular intervals.
public void ReplicateFile(string destinationFile, string sourceFile){
if (!Directory.Exists(GetRoutePathFromFile(sourceFile)))
return;
if (!File.Exists(sourceFile))
return;
if (Directory.Exists(GetRoutePathFromFile(destinationFile))){
if (File.Exists(destinationFile)){
UpdateLatestWaveFileContent(destinationFile, sourceFile);
}else{
CopyWaveFile(destinationFile, sourceFile);
}
}else{
Directory.CreateDirectory(GetRoutePathFromFile(destinationFile));
CopyWaveFile(destinationFile, sourceFile);
}
}
private static string GetRoutePathFromFile(string file){
var rootPath = Directory.GetParent(file);
return rootPath.FullName;
}
private static void CopyWaveFile(string destination, string source){
var sourceMemoryStream = new MemoryStream();
using (var fs = File.Open(source, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)){
fs.CopyTo(sourceMemoryStream);
}
using (var fs = new FileStream(destination, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite)){
sourceMemoryStream.WriteTo(fs);
}
}
private static void UpdateLatestWaveFileContent(string destinationFile, string sourceFile){
var sourceMemoryStream = new MemoryStream();
long offset = 0;
using (var fs = File.Open(destinationFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)){
offset = fs.Length;
}
using (var fs = File.Open(sourceFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)){
fs.CopyTo(sourceMemoryStream);
}
var length = sourceMemoryStream.Length - offset;
var buffer = sourceMemoryStream.GetBuffer();
using (var fs = new FileStream(destinationFile, FileMode.Append, FileAccess.Write, FileShare.ReadWrite)){
fs.Write(buffer, (int)offset, (int)length);
}
var bytes = new byte[45];
for (var i = 0; i < 45; i++){
bytes[i] = buffer[i];
}
ModifyHeaderDataLength(destinationFile, 0, bytes);
}
private static void ModifyHeaderDataLength(string filename, int position, byte[] data){
using (Stream stream = File.Open(filename, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite))
{
stream.Position = position;
stream.Write(data, 0, data.Length);
}
}
Try Reading the Source File one or two Wav blocks prior to the actual end of the source file.
The case could be that the code is judging the end of the source file too close for comfort.

How to compress a Excel file to zip or cap file extention using C#

I want to compress a Excel file to .zip or .cap extension. The code Used to do that it is compressing the file but that zip file can't be unzip. while unzip that i am getting the error file file corrupted or can't be unzip.
The code I am using:
static public bool CompressFile(string file, string outputFile)
{
try
{
using (var inFile = File.OpenRead(file))
{
using (var outFile = File.Create(outputFile))
{
using (var compress = new GZipStream(outFile, CompressionMode.Compress, false))
{
byte[] buffer = new byte[inFile.Length];
int read = inFile.Read(buffer, 0, buffer.Length);
while (read > 0)
{
compress.Write(buffer, 0, read);
read = inFile.Read(buffer, 0, buffer.Length);
}
}
}
}
return true;
}
catch (IOException ex)
{
MessageBox.Show(string.Format("Error compressing file: {0}", ex.Message));
return false;
}
}
Even i go some link to get the proper solution. But nothing is workout.I need some suggestion to get the proper solution. Any answer please.
This code uses the SharpZipLib library and will compress files that can be uncompressed no problems
private void Zip()
{
string output = #"C:\TEMP\test.zip";
string input = #"C:\TEMP\test.xlsx";
using (var zipStream = new ZipOutputStream(System.IO.File.Create(output)))
{
zipStream.SetLevel(9);
var buffer = new byte[4096];
var entry = new ZipEntry(Path.GetFileName(input));
zipStream.PutNextEntry(entry);
using (FileStream fs = System.IO.File.OpenRead(input))
{
int sourceBytes;
do
{
sourceBytes = fs.Read(buffer, 0, buffer.Length);
zipStream.Write(buffer, 0, sourceBytes);
} while (sourceBytes > 0);
}
zipStream.Finish();
zipStream.Close();
}
}

overwrite file in Zipping

I try to Zip some .pdf files in C#. My code works fine but when the size of one of the pdfs is big, it is going to overwrite that pdf on the rest of pdfs. I am not sure what is happening. I tried to increase the size of buffer or zip file but still same issue. Do you have any suggestion?
This is my code:
public void ProcessZipRequest(string strQueueID, string strBatchID, string strFtpPath)
{
int intReportCnt = 0;
string strZipFileName = "Order-" + strBatchID + "-" + strQueueID + "-" + DateTime.Now.ToString("MM-dd-yyyy-HH-mm") + ".zip";
strZipFileName = SafeFileName(strZipFileName);
//MemoryStream ms = new MemoryStream();
FileStream ms = new FileStream(#"c:\surf\nikoo.zip", FileMode.Create);
ZipOutputStream oZipStream = new ZipOutputStream(ms); // create zip stream
oZipStream.SetLevel(9); // maximum compression
intReportCnt += 1;
string strRptFilename=string.Empty;
MemoryStream outputStream = new MemoryStream();
if (strQueueID != null)
{
String[] filenames = Directory.GetFiles(#"C:\uploaded");
// setting Report name to path given for Report name
foreach (String filename in filenames)
{
strRptFilename = filename.Substring(filename.LastIndexOf("\\") + 1);
FileStream fs = File.OpenRead(#"C:\uploaded\" + strRptFilename);
int bufferSize = 2048;
int readCount;
byte[] buffer = new byte[bufferSize];
readCount = fs.Read(buffer, 0, bufferSize);
while (readCount>0)
{
outputStream.Write(buffer, 0, readCount);
readCount = fs.Read(buffer, 0, bufferSize);
}
fs.Close();
outputStream.Position = 0;
ZipFile(ref outputStream, strRptFilename, ref oZipStream);
}
}
outputStream.Close();
oZipStream.Finish();
oZipStream.Flush();
oZipStream.IsStreamOwner = false; // False stops the Close also Closing the underlying stream.
oZipStream.Close(); // Must finish the ZipOutputStream before using outputMemStream.
ms.Close();
}
And this is Zipfile Method:
public void ZipFile(ref MemoryStream msFile, string strFilename, ref ZipOutputStream oZipStream)
{
ZipEntry oZipEntry = new ZipEntry(strFilename);
oZipEntry.DateTime = DateTime.Now;
oZipEntry.Size = msFile.Length;
oZipStream.PutNextEntry(oZipEntry);
StreamUtils.Copy(msFile, oZipStream, new byte[4096]);
oZipStream.CloseEntry();
}
I found the issue. I have to create a new MemoyStream in for loop and close it at the end of the loop.
foreach (String filename in filenames)
{
strRptFilename = filename.Substring(filename.LastIndexOf("\\") + 1);
outputStream = new MemoryStream();
FileStream fs = File.OpenRead(#"C:\uploaded\" + strRptFilename);
int bufferSize = 2048;
int readCount;
byte[] buffer = new byte[bufferSize];
readCount = fs.Read(buffer, 0, bufferSize);
while (readCount>0)
{
outputStream.Write(buffer, 0, readCount);
readCount = fs.Read(buffer, 0, bufferSize);
}
fs.Close();
outputStream.Position = 0;
ZipFile(ref outputStream, strRptFilename, ref oZipStream);
fs.Close();
outputStream.Close();
}

Can we merge two memory mapped files?

Can we merge two memory mapped files? if so the how? if not then why not?
So here are my first experiences with MemoryMappedFiles, give it a try:
String f1Path = #"C:\Temp\Test1.txt";
String f2Path = #"C:\Temp\Test2.txt";
byte[] buffer;
int offset;
int length;
using (FileStream f1ReadStream = new FileStream(f1Path, FileMode.Open, FileAccess.Read))
{
offset = (int)f1ReadStream.Length;
}
using (FileStream f2ReadStream = new FileStream(f2Path, FileMode.Open, FileAccess.Read))
{
length = (int)f2ReadStream.Length;
}
// read file2 and append all to file1
using (var mappedFile2 = MemoryMappedFile.CreateFromFile(f2Path, FileMode.Open, null, length))
{
using (var reader = mappedFile2.CreateViewStream(0, length, MemoryMappedFileAccess.Read))
{
// Read from MMF
buffer = new byte[length];
reader.Read(buffer, 0, length);
}
}
using (var mappedFile1 = MemoryMappedFile.CreateFromFile(f1Path,FileMode.Open, null, offset + length))
{
// Create writer to MMF
using (var writer = mappedFile1.CreateViewAccessor(offset, length, MemoryMappedFileAccess.Write))
{
// Write to MMF
writer.WriteArray<byte>(0, buffer, 0, length);
}
}

Categories

Resources