2013-06-26 39 views
0

我已经继承了可用于将信息直接发送到打印机的打印机辅助类。它可以处理文件,字符串或原始字节。对于文件和字符串,它首先将它们转换为字节,然后使用bytes方法进行发送。未能将FileStream长度转换为int

我的问题是文件方法无法为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的某些特性,或者这里的代码有问题?

编辑:为了澄清什么,我完全了解一个longint之间的差异。使用的文件不会对此造成问题。我可以在有和没有暂停的情况下通过十几次运行相同的文件,并且在没有暂停的情况下它总是会失败。

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

回答

1

不是依靠FILESTREAM的长度,也许你可以依靠返回的字节数组的长度:

// 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;