D365 FO操作FTP
D365 FO与.NET的交互比起AX2012 提高不止一个层次,AX2012与.NET交互只能算半成品,有些时候需要各种稀奇古怪的转换才能用。
D365 FO直接就编译成CIL了,使用.NET的类库也更加简洁。
通过FTP与其他系统做交互,可以直接通过.NET的System.NET类库,简单封装一下就可以用了。
1 using System.Net; 2 using System.IO; 3 using System.Text; 4 5 public class Ftp 6 { 7 FtpWebRequest request; 8 FtpWebResponse response; 9 10 FTPAddress address; 11 FTPUserName userName; 12 FTPPassword password; 13 14 const str FtpListFiles = 'NLST'; 15 const str FtpDownloadFile = 'RETR'; 16 const str FtpDeleteFile = 'DELE'; 17 const str FtpUploadFile = 'STOR'; 18 19 public static Ftp construct( 20 FTPAddress _address, 21 FTPUserName _userName, 22 FTPPassword _password) 23 { 24 return new Ftp( 25 _address, 26 _userName, 27 _password); 28 } 29 30 /// <summary> 31 /// 32 /// </summary> 33 /// <param name = "_address">FTP的IP地址或域名,不带前缀FTP://</param> 34 /// <param name = "_userName">访问FTP的用户名</param> 35 /// <param name = "_password">访问FTP的密码</param> 36 public void new( 37 FTPAddress _address, 38 FTPUserName _userName, 39 FTPPassword _password) 40 { 41 address = "FTP://" + _address; 42 userName = _userName; 43 password = _password; 44 } 45 46 public List getFiles() 47 { 48 List files = new List(Types::String); 49 50 this.initRequest(FtpListFiles); 51 response = request.GetResponse(); 52 StreamReader sr = new StreamReader(response.GetResponseStream()); 53 54 while (!sr.EndOfStream) 55 { 56 files.addEnd(sr.ReadLine()); 57 } 58 return files; 59 } 60 61 public void uploadFile( 62 MemoryStream _ms, 63 Encoding _encoding, 64 Filename _fileName) 65 { 66 System.Byte[] bytes = _encoding.GetBytes(new StreamReader(_ms).ReadToEnd()); 67 68 this.initRequest(FtpUploadFile, _fileName); 69 70 using(Stream stream = request.GetRequestStream()) 71 { 72 stream.Write(bytes, 0, bytes.get_Length()); 73 stream.Close(); 74 response = request.GetResponse(); 75 76 if (response.StatusCode != FtpStatusCode::ClosingData) 77 { 78 throw error(response.StatusDescription); 79 } 80 response.Close(); 81 } 82 } 83 84 public void deleteFile(Filename _fileName) 85 { 86 this.initRequest(FtpDeleteFile, _fileName); 87 response = request.GetResponse(); 88 } 89 90 public MemoryStream downloadFile(Filename _fileName) 91 { 92 MemoryStream ms = new MemoryStream(); 93 94 this.initRequest(FtpDownloadFile, _fileName); 95 96 response = request.GetResponse(); 97 98 using (Stream stream = response.GetResponseStream()) 99 { 100 int bufferSize = 2048; 101 System.Byte[] buffer = new System.Byte[bufferSize](); 102 int readCount = stream.Read(buffer, 0, bufferSize); 103 while (readCount) 104 { 105 ms.Write(buffer, 0, readCount); 106 readCount = stream.read(buffer, 0, bufferSize); 107 } 108 } 109 response.Close(); 110 return ms; 111 } 112 113 private void initRequest( 114 str _method, 115 Filename _fileName = '') 116 { 117 request = WebRequest::Create(new System.Uri(_fileName ? address + "/" + _fileName : address)); 118 119 NetworkCredential credential = new NetworkCredential(userName, password); 120 request.Credentials = credential; 121 request.Method = _method; 122 } 123 124 }
上传文件
首先将数据写入到System.IO.MemoryStream类是实例中,然后调用FTP类的UploadFile方法就可以了。
ms.Position = 0; new FTP( exportGroupTable.FTPAddress, exportGroupTable.FTPUserName, exportGroupTable.FTPPassword).uploadFile( ms, encoding, fileName);
下载文件
跟上传类似,调用FTP的方法downloadFile
MemoryStream ms = ftp.downloadFile(_fileName);
如果要报文件存入到数据库里,只要用Binary类将得到ms转换成container类型,然后赋值给container类型的表字段就可以了。
Binary::constructFromMemoryStream(ms).getContainer();
Binary这个类用来做MemoeryStream和Container之间的转换很好用,如果把存到container类型字段的文件读取出来,可以用下面的方法。
ms = Binary::constructFromContainer(someTable.FileContent).getMemoryStream();
接下来就就可以用.NET的StreamReader之类的类库进行遍历分析了。