2013-06-26 37 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;