0

我继承了一个打印机助手类,可用于将信息直接发送到打印机。它可以处理文件、字符串或原始字节。对于文件和字符串,它首先将它们转换为字节,然后使用 bytes 方法进行发送。

我的问题是文件方法未能设置字节方法成功所需的所有变量。看下面的方法:

// Open the file.
FileStream fs = new FileStream(szFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

// Create a BinaryReader on the file.
BinaryReader br = new BinaryReader(fs);

// Dim an array of bytes big enough to hold the file's contents.
Byte[] bytes = new Byte[fs.Length];
bool bSuccess = false;

// Your unmanaged pointer.
IntPtr pUnmanagedBytes = new IntPtr(0);
int nLength;
nLength = Convert.ToInt32(fs.Length);

// Read the contents of the file into the array.
bytes = br.ReadBytes(nLength);

// Allocate some unmanaged memory for those bytes.
pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength);

// Copy the managed byte array into the unmanaged array.
Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength);

// Send the unmanaged bytes to the printer.
bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength);

// Free the unmanaged memory that you allocated earlier.
Marshal.FreeCoTaskMem(pUnmanagedBytes);
return bSuccess;

即使流本身具有所有正确的数据,故障点似乎也nLength = Convert.ToInt32(fs.length);出现了。0如果我在那一点上放一个断点,那么它将永远有效。SendBytesToPrinter如果我在通话时将其放在下方,nLength它将是0.

我现在的解决方法是Thread.Sleep(1000);在转换之前使用,但这对我来说太老套了。

FileStream 的某些特征是否导致此问题,或者这里的代码有问题?

编辑:为了澄清一些事情,我完全了解 alongint. 使用的文件不会导致此问题。我可以在有和没有暂停的情况下运行同一个文件十几次,它总是会在没有暂停的情况下失败。

编辑#2:布兰登的回答并没有直接解决问题,但处理文件的新方法首先揭示了用于获取文件的下载方法存在问题。我将他的回答标记为已接受,因为它不仅将我引向了真正的问题,而且它是一种处理该方法的更清洁的方法。

4

1 回答 1

1

而不是依赖文件流的长度,也许你可以依赖返回的字节数组的长度:

// Read bytes in from file, capture length of returned array
var bytes = File.ReadAllBytes(szFileName);
var nLength = bytes.Length;

// Your unmanaged pointer.
IntPtr pUnmanagedBytes = new IntPtr(0);

// Allocate some unmanaged memory for those bytes.
pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength);

// Copy the managed byte array into the unmanaged array.
Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength);

// Send the unmanaged bytes to the printer.
var bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength);

// Free the unmanaged memory that you allocated earlier.
Marshal.FreeCoTaskMem(pUnmanagedBytes);

return bSuccess;
于 2013-06-26T19:20:01.907 回答