|
yes, a typical mistake. A read operation not always returns the amount of data requested. Your first file length isn't necessarily a multiple of 1024, so the last read is bound to return less, yet you write an entire array of 1024 data bytes. The solution is simple: capture the return value of Read() and use it as a parameter to Write() .
BTW: all streams have a Dispose method which you should call to clean up; AFAIK such Dispose() automatically calls Flush() and Close() when necessary. A simple way to get Dispose() called automatically is through the using statement, like so:
using (NetworkStream nStream = new NetworkStream(getSocket(numsock).getSocket(),true)) {
using (FileStream fs = new FileStream("C:\\Users\\Mauri\\Desktop\\" + item.Name, FileMode.Append, FileAccess.Write)) {
using (BinaryWriter writer = new BinaryWriter(fs)) {
for(;;) {
int len=nStream.Read(myReadBuffer, 0, myReadBuffer.Length);
if (len==0) break;
writer.Write(myReadBuffer, 0, len);
}
}
}
}
which avoids a number of potential mistakes and yields the most readable code IMO.
Of course, you might want to reorganize if you need to keep the NetworkStream alive after a file has been transmitted. Then either rearrange the code so it handles a number of files inside the outer using, or drop the using and call nStream.Dispose() explicitly when done.
Luc Pattyn [My Articles] Nil Volentibus Arduum
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Please use <PRE> tags for code snippets, they improve readability. CP Vanity has been updated to V2.4
|
|
|
|
|
Ok catched that, but the problem is that my socket, never returns "0" so len == 0 gives timeout exception:
Unable to write data to the transport connection: An error occurred during connection attempt because the connected part did not properly respond after a period of time, or failed to established connection and connected host has failed to respond.
in
int len = nStream.Read(myReadBuffer, 0, myReadBuffer.Length); line.
Thanks
PD: If you can explain me, or give me some documentation about the "using", that you put in the code, would be great.
|
|
|
|
|
Actually, there is more to it than what I said earlier. If the NetworkStream remains open and you send another file, it will look like more bytes coming through the cable, and the receiver will not know where the first file ends and the second one begins. You do need something extra to carry that information.
If the length is known in advance, as when sending a file from disk, then you could put a writer.Write(fs.Length); in front of the data copying loop. Your receiver should then read than length and loop until it has read that many bytes. At that point either the transmission is over or another file is coming.
Luc Pattyn [My Articles] Nil Volentibus Arduum
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Please use <PRE> tags for code snippets, they improve readability. CP Vanity has been updated to V2.4
|
|
|
|
|
In addition to what Luc said in the first post, you are closing the connection after data is no longer available (read=0) so you can't use this socket to read another. If you want to keep the connection open for multiple files you will need to specify a protocol that sends the length first and then the contents; for example have a look at the message handling code in my socket library[^], though that's slightly obfuscated by the encryption support.
|
|
|
|
|
Hi Guys. I want to dev an app which will read ASCII files but using their COBOL copy-books as format reference and then mapping them into a new COBOL copy-book. Is there a plugin that would let me specify a cobol copy book and then reference the input file against it and read it?
I coul probably write the layouts as classes and do it that way bbut this will take ages as I have many copy-books to do.
My aim is to read in a file, refer to the copy book for the format and then convert it to a different copy-book by "cross mapping".
Anybody done anything like this before? I'm just looking for suggestions or references to articles or some web links. All I can find is some IBM stuff, WEBSPHERE etc but not what I am looking for though.
Thanks
Excellence is doing ordinary things extraordinarily well.
|
|
|
|
|
I have no idea what a COBOL copy-book is. Maybe post a snippet of one? Plus a sample of what the input and output would be?
|
|
|
|
|
I think I got one as a present in the thread below. Consider it yours if you want it.
Luc Pattyn [My Articles] Nil Volentibus Arduum
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Please use <PRE> tags for code snippets, they improve readability. CP Vanity has been updated to V2.4
|
|
|
|
|
|
The one right below this one, titled "PrintPreviewControl and HTML", holding a "contribution" by the same author.
And yes, if you haven't already.
Luc Pattyn [My Articles] Nil Volentibus Arduum
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Please use <PRE> tags for code snippets, they improve readability. CP Vanity has been updated to V2.4
|
|
|
|
|
|
|
I want to creat a .net app reading "messages" or shall I say files defined by a cobol-copy book format/layout. Do this I want to reference the copy-book and pass the message to it for unmarshalling and then writing it out to another message in yet another cobol copy-book format. Like creating a middleware app. If I have to transform the copy book and write it out to as a file format, it could take ages as they are huge layouts and would be easier just to reference the copy-book. Hope this explains!
Excellence is doing ordinary things extraordinarily well.
|
|
|
|
|
|
Hi all,
I have some html files (Custom Reports) and I want to show the print preview of them to the user.I don't want to use IE print preview or web browser because they are not embedded in my application and I can not control them the way I want. I was wondering if there is a way to preview a html file in PrintPreviewControl (or any other components like that)?
Please help me.
thank you.
Every new thing you learn,Gives you a new personality.
|
|
|
|
|
Assuming your app is a WinForms app, I see three possibilities:
1.
Use a WebBrowser control and have it navigate to your HTML document.
2.
Use any external app you choose (MS Word if you must), and make it show its main form inside your app, by calling SetParent (using P/Invoke).
3.
create your own UserControl, that parses and interprets HTML; it is quite a job, probably not worth the effort it would take.
Luc Pattyn [My Articles] Nil Volentibus Arduum
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Please use <PRE> tags for code snippets, they improve readability. CP Vanity has been updated to V2.4
|
|
|
|
|
I tend to agree. I have numerous copy-books and some of them are pretty big. Take this one for instance:
<br />
01 X30002-FUNCTION-SEG. <br />
05 X30002-MSG-LL PIC S9(04) COMP. Message length is variable depending on number of items in the set<br />
05 X30002-FUNC-TAG PIC X(08). ZPE0805F<br />
05 X30002-VERSION PIC 9(02). Version Number. Must be set to 00<br />
05 X30002-FUNCTION-INPUT. <br />
10 X30002-HEADER. <br />
15 X30002-BATCH-TYPE PIC X(03). P = Payment batch<br />
T = Transfer batch within a customers own profile<br />
PS = Purchase of Services batch<br />
RTI = Real-time Clearing inward batch<br />
RTO = Real-time Clearing outward batch<br />
15 X30002-SET-TYPE PIC X(01). C = Consolidated batch. 1 Debit upto 50 credits <br />
I = Itemised batch. Upto 25 Dr/CR items<br />
15 X30002-CUSTOMER-ID PIC X(20). A valid customer identifier from the channel. Not Validated<br />
15 X30002-BATCH-ID PIC X(20). A unique batch identifier. Not Validated<br />
15 X30002-SET-NUMBER PIC 9(05). The number of the set contained within the batch. Start at 1 and increment for each set within the batch<br />
15 X30002-NOMINATED-POST-IND PIC X(01). R = Real-time post<br />
= defaults to Real-Time<br />
15 X30002-HOMING-POST-IND PIC X(01). F = Force post<br />
R = Real-time post<br />
= defaults to Real-Time where applicable<br />
15 X30002-CHECK-AVAIL-BAL-IND PIC X(01). Set to Y if available balance must be checked prior to posting <br />
15 X30002-TRAN-CODE-IND PIC X(01). C = Channel<br />
D = Default <br />
= Defaults to Channel <br />
15 X30002-NO-OF-TXNS PIC 9(03). The number of transactions contained in the homing table<br />
15 FILLER PIC 9(08). <br />
10 X30002-REVERSAL-DETAILS. <br />
15 X30002-NOM-REV-PROD-CODE PIC X(03). Reversal Product Code eg DDA / TCS<br />
15 X30002-NOM-REV-ACCOUNT PIC X(23). Reversal Account Number. Right justified, zero filled<br />
15 X30002-REVERSAL-TRAN-CODE PIC X(05). Reversal Tran Code, can be supplied or resolved by PE<br />
15 X30002-MATCH-REVERSAL-IND PIC X(01). Y if matched reversals are required. If set the transaction does not appear on the statement<br />
10 X30002-NOMINATED-DETAILS. Details of the FNB account to be debited <br />
15 X30002-NOM-CO-ID PIC 9(05). FNB company identifier<br />
15 X30002-NOM-PROD-CODE PIC X(03). Nominated Product code eg DDA / TCS / MLS / GLB<br />
15 X30002-NOM-ACCOUNT-NO PIC X(23). Account Number to be debited. Right justified, zero filled<br />
15 X30002-NOM-ACCOUNT-NAME PIC X(30). Account Name. Not Validated<br />
15 X30002-NOM-REF PIC X(20). Mandatory when batch is Consolidated <br />
15 X30002-NOM-DESCR PIC X(47). Used when batch is Consolidated If not supplied the default description for the transaction code will be applied <br />
15 X30002-NOM-AMOUNT PIC 9(15)V99. Mandatory when batch is Consolidated Right justified, zero filled, 2 decimal places<br />
15 X30002-NOM-TRAN-CODE PIC X(05). If not supplied the transaction code will be resolved by the PE <br />
15 X30002-NOM-SERIAL-NO PIC 9(10). Only applicable to IDS, optional cheque serial number <br />
10 FILLER PIC X(26). <br />
10 X30002-GL-DETAILS. Mandatory when CONSOLIDATED and SET-NUMBER is > 1 <br />
15 X30002-GL-AMOUNT PIC 9(15)V99. Right justified, zero filled, 2 decimal places <br />
15 X30002-GL-SIGN PIC X(01). D or C <br />
10 FILLER PIC X(01). <br />
10 X30002-AMOUNT-CURRENCY PIC X(03). e.g. ZAR; ZMK; NAD; LSL; SZL; BWP <br />
10 FILLER PIC X(50). <br />
10 X30002-HOMING-DETAILS OCCURS 50. <br />
15 X30002-HOM-CO-ID PIC 9(05). A Valid FNB company identifier.<br />
15 X30002-HOM-PROD-CODE PIC X(03). Valid values <br />
TPT – must supply account type and branch when using this option. The product code is then derived <br />
DDA<br />
TOA <br />
TCS; or Valid Card Product eg ZFN<br />
ILP; MLS; PLS;<br />
NPS<br />
REC<br />
OBP<br />
WES<br />
EWA<br />
GLB<br />
15 X30002-HOM-ACCT-TYPE PIC 9(01). 1 = Current Acc <br />
2 = Savings Acc <br />
3 = Transmission Acc <br />
4 = Bond Acc <br />
6 = Subscription Share<br />
15 X30002-HOM-BRANCH PIC 9(06). Sort Code<br />
15 X30002-HOM-ACCOUNT-NO PIC X(23). Right justified, zero filled<br />
15 X30002-HOM-BUDGET-NO PIC 9(05). Only used for Cardes products <br />
15 X30002-HOM-ACCOUNT-NAME PIC X(30). Account Name. Not validated<br />
15 X30002-HOM-AMOUNT PIC 9(15)V99. Right justified, zero filled, 2 decimal places<br />
15 X30002-HOM-REF PIC X(20). Reference<br />
15 X30002-HOM-DESCR PIC X(47). If not supplied the default description for the transaction code will be applied <br />
15 X30002-HOM-TRAN-CODE PIC X(05). If not supplied the transaction code will be resolved by the PE <br />
15 X30002-HOM-REVERSAL-DESCR PIC X(47). Supply if a different description is required other than the homing description <br />
15 X30002-NOM-REFERENCE PIC X(20). Mandatory when batch is Itemised <br />
15 X30002-NOM-DESCRIPTION PIC X(47). Used when batch is Itemised. If not supplied the default description for the transaction code will be applied <br />
This is huge and writing my own class to parse the message to is probably a waist of time. I'll see if I can come up with a better solution or find something and post back.
Thanks Luc
Excellence is doing ordinary things extraordinarily well.
|
|
|
|
|
I'll wait.thanks
Every new thing you learn,Gives you a new personality.
|
|
|
|
|
Can you explain more about the second one?(Maybe an article or something?)
Every new thing you learn,Gives you a new personality.
|
|
|
|
|
something along these lines would show your HTML editor inside your panel "myPanel":
Process p=Process.Start("myHtmlEditor", "someFile.html");
p.WaitForInputIdle();
IntPtr hWndChild=p.MainWindowHandle();
IntPtr hWndParent=myPanel.Handle;
SetParent(hWndChild, hWndParent);
Adapt where necessary!
And the prototype for the native Win32 function would be:
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
Luc Pattyn [My Articles] Nil Volentibus Arduum
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Please use <PRE> tags for code snippets, they improve readability. CP Vanity has been updated to V2.4
|
|
|
|
|
You have significantly less control over starting another app than you do over a web browser OCX, which the OP says isn't enough, so I doubt this solution will fulfil his needs. The best third party app for rendering HTML – a browser – is already available as a control in .Net.
|
|
|
|
|
I'm working on a WPF app using MVVM with Telerik controls. I have a Telerik RadTreeView loaded with clients and projects:
<telerik:RadTreeView Width="200"
HorizontalAlignment="Left"
ItemsSource="{Binding Path=Clients}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"/>
Here are the 2 data models:
http://www.maroisconsulting.com/stuff/models.png[^]
When a node is clicked, the SelectedItem's Get calls nodeSelected. Here's where the fun begins.
The nodeSelected methods is responsible for
1) Extracting the DataModel (either the ClientModel or ProjectModel) from the selected node
2) Creating the view (ClientView or ProjectView)
3) Creating the viewmodel (ClientViewModel or ProjectViewModel)
4) Adding a tab to a RadTabControl and assigning the view to it.
While this all works fine, the code doesn't feel right. In the code below, you'll see that both the Client and Project sections have alot in common. I'd like to get some suggestions on refactoring it (Sorry it's a bit long):
private void nodeSelected()
{
if (SelectedItem == null)
return;
string selectedObjectName = SelectedItem.GetType().Name.Trim().ToLower();
switch (selectedObjectName)
{
#region Client
case "clientmodel":
ClientModel clientModel = SelectedItem as ClientModel;
TabInfo clientTabInfo = getTabInfo(AppViews.Client, clientModel.ClientId);
if (clientTabInfo == null)
{
string clientName = "Client - " + clientModel.ClientName;
string clientImage = "/Falcon;component/Media/Graphics/customer_48x48.png";
string clientIcon = "/Falcon;component/Media/Graphics/customer_16x16.png";
ClientViewModel clientViewModel = new ClientViewModel(clientModel)
{
HeaderTitle = clientName,
HeaderImage = clientImage
};
ClientView clientView = new ClientView
{
DataContext = clientViewModel };
TabInfo info = new TabInfo
{
ItemId = clientModel.ClientId,
ViewType = AppViews.Client
};
RadTabItem tab = addTab(clientName, clientIcon);
tab.Content = clientView;
tab.Tag = info;
Tabs.Add(tab);
SelectedTab = tab;
}
else
{
activateTab(AppViews.Client, clientModel.ClientId);
}
break;
#endregion
#region Project
case "projectmodel":
ProjectModel ProjectModel = SelectedItem as ProjectModel;
TabInfo projectTabInfo = getTabInfo(AppViews.Project, ProjectModel.ProjectId);
if (projectTabInfo == null)
{
string projectName = "Project - " + ProjectModel.Caption;
string projectImage = "/Falcon;component/Media/Graphics/project_48x48.png";
string projectIcon = "/Falcon;component/Media/Graphics/project_16x16.png";
ProjectViewModel ProjectViewModel = new ProjectViewModel(ProjectModel)
{
HeaderTitle = projectName,
HeaderImage = projectImage
};
ProjectView ProjectView = new ProjectView();
ProjectView.DataContext = ProjectViewModel;
TabInfo info = new TabInfo
{
ItemId = ProjectModel.ProjectId,
ViewType = AppViews.Project
};
RadTabItem tab = addTab(projectName, projectIcon);
tab.Content = ProjectView;
tab.Tag = info;
Tabs.Add(tab);
SelectedTab = tab;
}
else
{
activateTab(AppViews.Project, ProjectModel.ProjectId);
}
break;
#endregion
}
}
Everything makes sense in someone's mind
|
|
|
|
|
That's not too bad. It looks similar but actually most of it is not identical and therefore isn't an immediate candidate for refactoring. The only thing that is is creating or activating a tab, which is about 10 lines, which isn't critical.
However, the type switching by name is ugly. You should have ClientModel and ProjectModel both implement an interface (let's call it IModelInfoProvider) that exposes what you need to determine tab identity (an AppViews enum, ModelType, and an ID). You could argue that they should go in the view model, so if you have two way linkage you could put them there and expose a base view model through the interface, or make the UI control have ViewModels not Models as its item list. Then you can do:
IModelInfoProvider item = (IModelInfoProvider)SelectedItem;
TabInfo tabInfo = getTabInfo(item.ViewType, item.ID);
if(tabInfo == null){
TabInfo info = new TabInfo
{
ItemId = item.ID,
ViewType = item.ViewType
};
IView view = ...;
RadTabItem tab = addTab(view.DisplayName, view.IconPath);
tab.Content = view;
tab.Tag = info;
SelectedTab = tab;
} else activateTab(tabInfo.Tab);
Now, what goes in ... is essentially 'make your MV and View'. Depending on how strict on layering you're feeling you can either expose that as an interface method as well, or create a factory to which you can pass a model and it will construct views of the appropriate type. In the latter case you will still have to type switch, inside the factory code – please use is if you have to type switch, not string type names!
|
|
|
|
|
I have a C# 2010 Windows Forms project that accesses (primarily) two tables in a SQL Server 2008 database. Each table is accessed in two modes: active accounts and cancelled accounts, and both have to be visible and editable at the same time (user requirement). The way I have it set up now is to have one DataSet, one TableAdapterManager, two TableAdapters (one for each table) and four BindingSources (two for each table adapter; one for active, one for cancelled). I have FillBy/GetDataBy methods setup for each TableAdapter that fill my BindingSources correctly. This is the code I’m using for filling them:
htcActiveBindingSource.DataSource = this.htcTableAdapter.ActiveGetDataBy(gpn);
htcCancelledBindingSource.DataSource = this.htcTableAdapter.CancelledGetDataBy(gpn);
vetActiveBindingSource.DataSource = this.vetTableAdapter.ActiveGetDataBy(gpn);
vetCancelledBindingSource.DataSource = this.vetTableAdapter.CancelledGetDataBy(gpn);
Everything works exactly as I was hoping, except for saving. The code I was using for saving is this:
this.Validate();
this.htcActiveBindingSource.EndEdit();
this.htcCancelledBindingSource.EndEdit();
this.vetActiveBindingSource.EndEdit();
this.vetCancelledBindingSource.EndEdit();
this.tableAdapterManager.UpdateAll(this.cramdDataSet);
When I step through in debug mode, the current row in the BindingSource knows that it has been modified after the EndEdits run. However, when it executes the UpdateAll, nothing happens in the database. Playing around with it, I figured out that if I fill the TableAdapter directly, like this:
this.htcTableAdapter.ActiveFillBy(this.cramdDataSet.htc, gpn);
then it works, but only for just active or just cancelled, not both at the same time (it sets both binding sources to the same data). Is there some way to get the data from the independent BindingSources back into the TableAdapter? Or am I going to be forced to create a second table adapter for the cancelled versions of each table? Am I going about this in a completely retarded way? If so, please enlighten me! (As much as I’d like to make my code work, I’m not opposed to rewriting big chunks to do it the “right” way.) I’m also going to need to insert new records created from the form, but I haven’t gotten to that point yet since my basic save is not even working.
Thanks in advance!
|
|
|
|
|
Can you show ActiveFillBy and ActiveGetDataBy? I suspect that you are returning a binding source on an in-memory copy of the data and the link back to the database is being lost.
|
|
|
|
|
I'm not sure what you mean by "show ActiveFillBy and ActiveGetDataBy". They are queries attached to the htcTableAdapter in the dataset designer. However, I stumbled upon a way to make it work, but I'm not sure exactly why it works. If I alter the code like this before the UpdateAll, then it works:
this.htcActiveBindingSource.EndEdit();
this.htcTableAdapter.Update((cramdDataSet.htcRow)((DataRowView)this.htcActiveBindingSource.Current).Row);
I get what the update is doing: taking the current row from the BindingSource and applying it back to the TableAdapter. What I don't get is the parameter value (starting w/ the first double parentheses). I found that online somewhere a while ago, but I don't understand what it is doing. Is there a better way to pass the current row into the update? More importantly, is there a way to pass the entire set of rows from the binding source? The vetActiveBindingSource and vetCancelledBindingSource can have multiple records in them that can all be edited. Since one overload of the BindingSource.Update method can take a collection of rows, I'd rather do it like that, rather than looping thru all the records and passing them in one at a time. I looked thru the BindingSource properties and methods but didn't see anything that looked promising.
|
|
|
|
|