oracle没有ftp包,Oracle 自带包中有没有类似于ftp的函数?

How to perform FTP operations from within PL/SQL (part I)

Introduction

There are times where it would be useful to be able to move files across systems from within a PL/SQL program. The usual tool for doing this is the ftp command. There are at least 4 ways to realize this.

The first one is to interface the O/S ftp command to the database so it can be used from within PL/SQL. An implementation of this alternative will likely use an external procedure to spawn the program. Actually, such a solution already exists, see Note:111780.1. Another implementation will be found in a future article.

The second one is to grab a library offering an ftp client API callable from C. A quick search on the Web brought back several hits, among which FCE4C "a library of functions providing direct and simple control of the FTP protocol". This is a shareware available from http://www.marshallsoft.com/fce4c.htm.

The third way is to use the functions in PL/SQL packages utl_tcp and utl_http, either to realize ad hoc file retrieve/put functionality or to (re-)implement the ftp protocol. This can be a fun project but requires some insight of its innards as described in the RFC 959 document, far too more than an application programmer cares to know about.

The fourth one is to publish the java class FtpClient from the package sun.net.ftp, contained in the JDK�s rt.jar library. This solution is similar to the second one but for java. While the first is more universal because it is based on the external procedure mechanism existing since Oracle v8, the fourth one is cleaner because it relies on the built-in JVM that exists since Oracle v8i, and is therefore an internal solution. There is one catch though: as it uses the Sun's package sun.net.ftp, which is not part of the JDK and is not supported by Sun, there is no warranty nor official documentation. However, it is easy to use and seems to work fine so far � minus one small glitch, see below � and there are free alternative implementations of it in source form on the Internet. See http://www.enterprisedt.com/downloads/ftp.html for a FTPClient implementation, and http://www.enterprisedt.com/downloads/ftp/doc/index.html for its documentation.

In this 3-part article, I have chosen the fourth alternative. I am presenting its implementation here and will provide the code listing in Note.159061.1 and Note.159062.1.

Interfacing to FtpClient

This java class belongs to the Sun�s package sun.net.ftp. It conveniently exports the following main methods: openServer() and closeServer(), login() (log in onto a given host), get() (retrieve a list of remote files), put() (store a list of files to the remote host), list() (get the current directory�s list of entries), binary() (set file transfer to binary), and ascii() (set file transfer to ASCII), and cd() (change to directory). As no mget() is exported by the class, this function is not available, though it could relatively easily be implemented using list() and get().

As usual with java in the database, the FtpClient class will be invoked through static public methods published as stored procedures (JSP). Because of this, a stateless java interface has to be written, which one can take profit of to make it more synthetic and comfortable. Here are the retained public methods:

static public String FTPGet(String ServerName,

String UserName,

String Password,

String SourceFileList,

String FileTypeIsBinaryList,

String DestFileList,

String ListSeparator);

static public String FTPGet(String ServerName,

String UserName,

String Password,

String[] SourceFiles,

boolean[] FileTypeIsBinary,

String[] DestFiles);

static public String FTPPut(String ServerName,

String UserName,

String Password,

String SourceFileList,

String FileTypeIsBinaryList,

String DestFileList,

String ListSeparator);

static public String FTPPut(String ServerName,

String UserName,

String Password,

String[] SourceFiles,

boolean[] FileTypeIsBinary,

String[] DestFiles);

static public String FTPDir(String ServerName,

String UserName,

String Password,

String RemoteDir);

The functions return a string which is the eventual error message, or an empty string if no error occurred.

FTPGet() and FTPPut() functions are overloaded because PL/SQL index-by tables cannot currently be passed to java (an error "PLS-00999: implementation restriction (may be temporary) INDEX TABLE parameters are disallowed" is issued). Therefore, lists of files to put or get are passed as strings containing file names separated by a given separator string. On the java side however, it is more natural to resort to array of file names as collection, so a higher-level profile is also given.

The function�s profile is quite intuitive and does not need any explanation except parameter FileTypeIsBinaryList. This is a string of ListSeparator-separated "T" or "F" characters which respectively stand for TRUE and FALSE. This is needed because PL/SQL BOOLEAN type is not mappable to java boolean.

To be used as JSP, the above static methods need to be interfaced to PL/SQL through PL/SQL functions, which do not need to be public. Here is the profile of the publicly accessible functions:

FUNCTION FTPGet(ServerName STRING,

UserName STRING,

Password STRING,

SourceFiles STRING_TABLE,

FileTypeIsBinary BOOLEAN_TABLE,

DestFiles STRING_TABLE) RETURN STRING;

FUNCTION FTPPut(ServerName STRING,

UserName STRING,

Password STRING,

SourceFiles STRING_TABLE,

FileTypeIsBinary BOOLEAN_TABLE,

DestFiles STRING_TABLE) RETURN STRING;

FUNCTION FTPDir(ServerName IN STRING,

UserName IN STRING,

Password IN STRING,

RemoteDir IN STRING,

DirList OUT STRING_TABLE) RETURN STRING;

FUNCTION FTPDir(ServerName IN STRING,

UserName IN STRING,

Password IN STRING,

RemoteDir IN STRING) RETURN STRING;

The profiles are closely related to their java counterparts.

Function FTPGet() connects to the remote machine whose host name is in ServerName using user account UserName/Password. If successful, it attempts to get the files whose names are in the PL/SQL index-by table of strings SourceFiles, and whose type (binary or ASCII) is contained in the PL/SQL index-by table of booleans FileTypeIsBinary (entry at index i is TRUE iff SourceFiles(i) is binary). The retrieved files are stored in the PL/SQL index-by table of strings DestFiles.

Index-by tables were chosen as collections here because they support the PL/SQL BOOLEAN data type and despite they don�t have constructors (each item in the table must be individually assigned, this cannot be done globally in one shot). Alternatively, higher-level nested tables of user-defined types could be used here but such types must be declared and defined in the database outside of PL/SQL packages, and they do not support the BOOLEAN data type. They have a constructor though which makes it nicer to initializes nested table literals. The reader is free to choose the interface s?he bests sees fit.

FTPPut() works similarly, excepted that it copies the files passed in SourceFiles onto the remote host as files whose names are in DestFiles.

SourceFiles and DestFiles must obey the file name syntax of their respective host platforms. E.g. when getting files from a Unix host into a PC host running NT, SourceFiles must be a �/� delimited list of sub-path names whereas DestFiles must be a �\� delimited list of sub-path names with an optional starting drive letter�:� sequence.

As PL/SQL index-by tables can be sparse, there is no guarantee that their first element is at index 0 or even 1. Therefore, instead of coercing the user to some arbitrary starting index or to dense tables only, I leave up to (him)|(her) this choice. Internally, functions Table.FIRST, Table.LAST, Table.EXISTS(index) are used to accommodate that freedom, which only slightly complicates the code.

FTPDir() exists in 2 flavors. The first version gets a directory listing of the files in the directory RemoteDir and returns it in raw format, i.e. the same as the one returned by the ftp "dir" command. Each line contains a file name preceded by its permissions, owner name, group name, size, and last access date. All the linefeed-separated lines are concatenated together into one string. The caller is responsible for parsing it and extracting the information of interest. The second flavor partially parses the raw output and returns it into a PL/SQL index-by table, one file entry per table element.

The functions return an error message if an error occurs, or an empty string if all the files could be processed correctly. If an error occurs, the current file plus the rest of the files are discarded and the functions return immediately. Programmatically, this was the easiest thing to do and justifies itself by the fact that a transfer error usually means a permission issue, a disk full or a network problem, which jeopardizes all subsequent file transfer as well so that an abort is the most sensible thing to do here.

Permission considerations

As resources such as TCP/IP sockets and files are being accessed by java functions, special permissions are required. Firstly, if the remote host is accessed through its hostname, a DNS must be queried to get the host�s IP address. This requires the resolve permission. Secondly, sockets operations such as accept(), listen(), and connect() also demand adequate permissions. Thirdly, files accessed remotely to be copied locally require the write permission and files accessed locally to be copied remotely require the read permission. All those permissions must be granted to the calling user through the function dbms_java.grant_permission().

Examples of use

In this example, all the permission granting stuff is done automatically since the running user name is grabbed from the session�s environment and the file names to be granted permission on are obviously known at run-time.

As error messages and the directory listing must be printed by the SQL*PLUS environment (see below why), host string variables are used.

CONNECT scott/tiger

SET SERVEROUTPUT ON

exec dbms_java.set_output(5000);

VAR DirFiles VARCHAR2(4000);

VAR ErrorMessage VARCHAR2(4000);

DECLARE

S FTP.STRING_TABLE;

B FTP.BOOLEAN_TABLE;

D FTP.STRING_TABLE;

DirList FTP.STRING_TABLE;

DummyKey NUMBER;

I NUMBER;

BEGIN

-- grant required socket permissions;

dbms_java.grant_permission(USER,

'java.net.SocketPermission',

'*:*',

'accept,listen,connect,resolve',

DummyKey);

-- get list of files;

:ErrorMessage := FTP.FTPDir(ServerName => 'chaos7a.ch.oracle.com',

UserName => 'osupport',

Password => 'password',

RemoteDir => '/usr/users/osupport',

DirList =>

266faa3e2451dd0bb0047cc3ca69ae30.gifirFiles);

:ErrorMessage := FTP.FTPDir(ServerName  => 'chaos7a.ch.oracle.com',

UserName    => 'osupport',

Password => 'password',

RemoteDir   => '/usr/users/osupport/ccervini',

DirList     => DirList);

FOR I IN 1 .. DirList.COUNT LOOP

dbms_output.put_line(DirList(I));

END LOOP;

-- get files;

S(1) := '/export/home/osupport/ccervini/1-65.pdf';

B(1) := true;

D(1) := '/u02/home/usupport/ccervini/1.pdf';

S(2) := '/export/home/osupport/ccervini/KO11.xls';

B(2) := true;

D(2) := '/u02/home/usupport/ccervini/3.xls';

S(3) := '/export/home/osupport/ccervini/Anatomy_of_an_Asp.pdf';

B(3) := true;

D(3) := '/u02/home/usupport/ccervini/2.pdf';

-- test sparse table here;

S(10) := '/export/home/osupport/ccervini/ODCI/JSSIndex.java';

B(10) := false;

D(10) := '/u02/home/usupport/ccervini/4.java';

FOR I IN D.FIRST .. D.LAST LOOP

IF D.EXISTS(I) THEN

dbms_java.grant_permission(USER,

'java.io.FilePermission size=+1>                                    D(I),

'write');

END IF;

END LOOP;

:ErrorMessage := FTP.FTPGet(ServerName => 'chsuncl1.ch.oracle.com',

UserName => 'osupport',

Password => 'password',

SourceFiles => S,

FileTypeIsBinary => B,

DestFiles => D);

-- put files;

S(1) := '/u02/home/usupport/ccervini/RegularExpressions.c';

B(1) := false;

D(1) := '/usr/users/osupport/100.c';

S(2) := '/u02/home/usupport/ccervini/analyze.sql';

B(2) := false;

D(2) := '/usr/users/osupport/101.sql';

S(-10) := '/u02/home/usupport/core';

B(-10) := true;

D(-10) := '/usr/users/osupport/ccervini/102';

FOR I IN S.FIRST .. S.LAST LOOP

IF S.EXISTS(I) THEN

dbms_java.grant_permission('SCOTT',

'java.io.FilePermission size=+1>                                    S(I),

'read');

END IF;

END LOOP;

:ErrorMessage := FTP.FTPPut(ServerName => 'chaos7a.ch.oracle.com',

UserName => 'osupport',

Password => 'password',

SourceFiles => S,

FileTypeIsBinary => B,

DestFiles => D);

END;

/

print DirFiles

print ErrorMessage

In the above demonstration block, the error message is returned into a SQL*PLUS host variable. This is because it was not always possible to use the dbms_output.put_line() function as the string often was too large (larger than 255 characters). Thus, this output task is left to the SQL*PLUS client. There is a java implementation of put_line() that works around those limits. Please see Note:136486.1.

The reader is invited to play with different combinations of host O/S, account and file status (existing/non existing, binary/ASCII, existing/non existing user, correct/wrong password) to see which error messages are returned.

A small glitch in Sun's class FtpClient

As is, method FtpClient.get() does not handle well multiple file cases, and fails with a java.lang.NullPointerException error after the first file was successfully retrieved.

The bug is on the last line of FtpClient.get(), i.e. instead of

return new FtpInputStream(this,

socket.getInputStream(),

binaryMode);

it should read:

return new TelnetInputStream(socket.getInputStream(),

binaryMode);

Once this change is made and the whole class recompiled and reloaded, the method works as expected.

The original code can be gotten from the following URL:

http://www.sourcebot.com/sourceb ... t/ftp/FtpClient.cla size=+1>References

For the full code of the java and PL/SQL interfaces, please check Note.159061.1 and Note.159062.1.

For an alternative implementation of FTPClient, see source code and documentation here:

http://www.enterprisedt.com/downloads/ftp.html

http://www.enterprisedt.com/downloads/ftp/doc/index.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring4GWT GWT Spring 使得在 Spring 框架下构造 GWT 应用变得很简单,提供一个易于理解的依赖注入和RPC机制。 Java扫雷游戏 JVMine JVMine用Applets开发的扫雷游戏,可在线玩。 public class JVMine extends java.applet.Applet 简单实现!~ 网页表格组件 GWT Advanced Table GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以直接在你的网页里面显示搜查的结果。 github-java-api github-java-api 是 Github 网站 API 的 Java 语言版本。 java缓存工具 SimpleCache SimpleCache 是一个简单易用的java缓存工具,用来简化缓存代码的编写,让你摆脱单调乏味的重复工作!1. 完全透明的缓存支持,对业务代码零侵入 2. 支持使用Redis和Memcached作为后端缓存。3. 支持缓存数据分区规则的定义 4. 使用redis作缓存时,支持list类型的高级数据结构,更适合论坛帖子列表这种类型的数据 5. 支持混合使用redis缓存和memcached缓存。可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 Java对象的SQL接口 JoSQL JoSQL(SQLforJavaObjects)为Java开发者提供运用SQL语句来操作Java对象集的能力.利用JoSQL可以像操作数据库中的数据一样对任何Java对象集进行查询,排序,分组。 搜索自动提示 Autotips AutoTips是为解决应用系统对于【自动提示】的需要(如:Google搜索), 而开发的架构无关的公共控件, 以满足该类需求可以通过快速配置来开发。AutoTips基于搜索引擎Apache Lucene实现。AutoTips提供统一UI。 WAP浏览器 j2wap j2wap 是一个基于Java的WAP浏览器,目前处于BETA测试阶段。它支持WAP 1.2规范,除了WTLS 和WBMP。 Java注册表操作类 jared jared是一个用来操作Windows注册表的 Java 类库,你可以用来对注册表信息进行读写。 GIF动画制作工具 GiftedMotion GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用程序)。 重复文件检查工具 FindDup.tar FindDup 是一个简单易用的工具,用来检查计算机上重复的文件。 OpenID的Java客户端 JOpenID JOpenID是一个轻量级的OpenID 2.0 Java客户端,仅50KB+(含源代码),允许任何Web网站通过OpenID支持用户直接登录而无需注册,例如Google Account或Yahoo Account。 JActor的文件持久化组件 JFile JFile 是 JActor 的文件持久化组件,以及一个高吞吐量的可靠事务日志组件。 Google地图JSP标签库 利用Google:maps JSP标签库就能够在你的Web站点上实现GoogleMaps的所有功能而且不需要javascript或AJAX编程。它还能够与JSTL相结合生成数据库驱动的动态Maps。 OAuth 实现框架 Agorava Agorava 是一个实现了 OAuth 1.0a 和 OAuth 2.0 的框架,提供了简单的方式通过社交媒体进行身份认证的功能。 Eclipse的JavaScript插件 JSEditor JSEditor 是 Eclipse 下编辑 JavaScript 源码的插件,提供语法高亮以及一些通用的面向对象方法。 Java数据库连接池 BoneCP BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接池的性能,根据某些测试数据发现,BoneCP是最快的连接池。BoneCP很小,只有四十几K
Oracle P/L SQL实现FTP上传、下载功能,以下是此过程的头部,体经常打处理plb,感兴趣用户可以下载下来。 --Oracle上的FTP功能 Create or Replace Package UTL_FTP AUTHID CURRENT_USER as Type Connection is Record( Connection UTL_TCP.Connection, AccountInfo VarChar2(1000), TransferMethod Char(1), --A: ASCII, E: EBCDIC, I: IMAGE TransferOption Char(1), LocalDirectory VarChar2(30), LastReply VarChar2(32767 ) ); Type File_List is Table of VarChar2(32767) Index by Binary_Integer; is_FTPStatus VarChar2(800) := 'disconnect'; is_FTPPort Constant Integer := 21; is_TransferMethod Constant VarChar2(10) := 'ASCII'; ii_OutputLog Constant Integer := 1; ii_RollBufferLog Constant Integer := 2; ii_ClientInfoLog Constant Integer := 4; -- Per RFC 959, if account info ( ACCT ) is requested Then a 332 code -- should be Returned from the PASS command instead of a Positive Completion ii_FTPRequestAcct Constant Integer := 332; gb_Verbose Boolean := False; --是否记录冗长、累赘的日志 gi_LogOptions Integer := ii_OutputLog; gs_LogText VarChar2(32767) := Null; Procedure p_SetVerbose( ab_Verbose in Boolean ); Procedure p_SetLogOptions( ai_LogOptions in Integer ); Procedure p_ClearLog; --登录到远程FTP服务器 Function f_Login( as_RemoteHost in VarChar2, as_Username in VarChar2, as_Password in VarChar2, as_LocalDirectory in VarChar2 Default Null, as_RemoteDir in VarChar2 Default Null, as_TransferMethod in VarChar2 Default is_TransferMethod, ai_Timeout in Integer Default Null, ai_FTPPort in Integer Default is_FTPPort, as_AccountInfo in VarChar2 Default Null )Return Connection; Procedure p_Logout( ac_Connection in out Nocopy Connection ); Procedure p_SendFTPCmd( ac_Connection in out Nocopy Connection, as_Command in VarChar2, as_Argument in VarChar2 Default Null, as_AccountInfo in VarChar2 Default Null ); Procedure p_ReadReply( ac_Connection in out Nocopy Connection ); Procedure p_Rename( ac_Connection in out Nocopy Connection, as_OldFilename in VarChar2, as_NewFilename in VarChar2 ); Procedure p_DeleteFile( ac_Connection in out Nocopy Connection, as_Filename in VarChar2 ); Function f_isDirectory( ac_Connection in out Nocopy Connection, as_Directory in VarChar2, ab_CDToo in Boolean Default True )Return Boolean; Procedure p_CreateDirectory( ac_Connection in out Nocopy Connection, as_Directory in VarChar2 ); Procedure p_DeleteDirectory( ac_Connection in out Nocopy Connection, as_Directory in VarChar2 ); Procedure p_SetTransferMethod( ac_Connection in out Nocopy Connection, as_TransferMethod in VarChar2, as_Option in VarChar2 Default Null ); Procedure p_RemoteCD( ac_Connection in out Nocopy Connection, as_Directory in VarChar2, ab_CreateDir in Boolean Default True ); Procedure p_RemoteCDup( ac_Connection in out Nocopy Connection ); Function f_RemotePWD( ac_Connection in out Nocopy Connection )Return VarChar2; Procedure p_PutClob( ac_Connection in out Nocopy Connection, ac_LocalClob in Clob, as_RemoteFilename in VarChar2, as_TransferMethod in VarChar2 Default Null ); Function f_PutClob( ac_Connection in out Nocopy Connection, ac_LocalClob in Clob, as_RemoteFilename in VarChar2, as_TransferMethod in VarChar2 Default Null )Return VarChar2; Procedure p_PutBlob( ac_Connection in out Nocopy Connection, ab_LocalBlob in BLOB, as_RemoteFilename in VarChar2, ab_ForceBinary in Boolean Default True --强制为二进制 ); Procedure p_GetClob( ac_Connection in out Nocopy Connection, as_RemoteFilename in VarChar2, ac_LocalClob in out Nocopy Clob, as_TransferMethod in VarChar2 Default Null ); Function f_GetClob( ac_Connection in out Nocopy Connection, as_RemoteFilename in VarChar2, as_TransferMethod in VarChar2 Default Null )Return Clob; Procedure p_GetBlob( ac_Connection in out Nocopy Connection, as_RemoteFilename in VarChar2, ab_LocalBlob in out Nocopy BLOB, ab_ForceBinary in Boolean Default True ); Function f_GetBlob( ac_Connection in out Nocopy Connection, as_RemoteFilename in VarChar2, ab_ForceBinary in Boolean Default True )Return BLOB; Procedure p_PutFile( ac_Connection in out Nocopy Connection, ai_LocalFilename in UTL_File.File_Type, as_RemoteFilename in VarChar2, as_TransferMethod in VarChar2 Default Null ); Procedure p_PutFile( ac_Connection in out Nocopy Connection, as_LocalDirectory in VarChar2, as_LocalFilename in VarChar2, as_RemoteFilename in VarChar2, as_TransferMethod in VarChar2 Default Null ); Function f_PutFile( ac_Connection in out Nocopy Connection, as_LocalDirectory in VarChar2, as_LocalFilename in VarChar2, as_RemoteFilename in VarChar2, as_TransferMethod in VarChar2 Default Null )Return VarChar2; Procedure p_PutFile( ac_Connection in out Nocopy Connection, as_LocalDirectory in VarChar2, as_LocalFilename in VarChar2 ); Procedure p_GetFile( ac_Connection in out Nocopy Connection, as_RemoteFilename in VarChar2, as_LocalDirectory in VarChar2, as_LocalFilename in VarChar2, as_TransferMethod in VarChar2 Default Null ); Procedure p_GetFile( ac_Connection in out Nocopy Connection, as_RemoteFilename in VarChar2, as_TransferMethod in VarChar2 Default Null ); Procedure p_GetFile( ac_Connection in out Nocopy Connection, as_RemoteFilename in VarChar2, ai_LocalFilename in out Nocopy UTL_File.File_Type, as_TransferMethod in VarChar2 Default Null ); Procedure p_GetFileList( ac_Connection in out Nocopy Connection, afl_List out File_List, as_RemotePath in VarChar2 Default Null, ab_FilenameOnly in Boolean Default True, as_FilenamePrefix in VarChar2 Default Null, as_FilenameExt in VarChar2 Default Null, as_TransferMethod in VarChar2 Default is_TransferMethod ); Function f_GetFileList( ac_Connection in out Nocopy Connection, as_RemotePath in VarChar2 Default Null, ab_FilenameOnly in Boolean Default True, as_FilenamePrefix in VarChar2 Default Null, as_FilenameExt in VarChar2 Default Null, as_TransferMethod in VarChar2 Default is_TransferMethod )Return File_List; --根据FTP参数或系统事先设定好的IP登录到FTP服务器 --Select UTL_FTP.f_ConnectFTP() From dual; Function f_ConnectFTP( as_RemoteSubDir in VarChar2 Default Null, --Remote Subdirectory as_RemoteFileWildcard in VarChar2 Default Null, --Remote File Wildcard --删除之前生成的文件 如I02-UB*.xls as_FTPServer in VarChar2, --FTP Server as_FTPUserID in VarChar2, --FTP User ID as_FTPPasswd in VarChar2 --FTP Password )Return UTL_FTP.Connection; END UTL_FTP; /
提供的源码资源涵盖了Java应用等多个领域,每个领域都含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值