发送和读取数据

转自:《Actionscript3.0 CookBook》

19.0.发送和读取数据

简介
很多情况下我们需要发送数据到flash或从flash中读取数值,比如:
1.发送表单数据到服务端脚本以便存储到数据库;
2.发送电子邮件数据给服务端发送电子邮件;
3.从文本文件中读取数据;
4.从服务器端读取数据,这些数据可能来自于数据库;

5.发送数据给服务端处理并返回结果,比如说用户登陆界面

当从一个URL中读取数据时,Flash播放器会把数据转换成以下三种形式之一:文本形式,原始二进制数据,或URL编码变量,
URL-编码遵循以下规则:
1.每个变量名用=号与其值相关联,=号两边没有空格
2.变量值被Flash读取后都被转换为字符串,如artist=Picasso.
3.当有多个名称/值对时,每一对都用&符号分开,如artist=Picasso&type=painting.
4.空格被替换成+符号,不是%20,比如title=The+Old+Guitarist. (空格和%20 也可以用,但是用+ 兼容性更好
5.除了数字和字母,如空格都被转换成十六进制的转义序列,例如,"L'Atelier" 被转换成L%27Atelier (%27 就是单引号),看下面的转义序列表

看下面的一个URL-编码格式的变量:
artist=Picasso&type=painting&title=Guernica&room=L%27Atelier

在ActionScript 3.0里发送和读取的数据都会被改变。LoadVars类已经被flash.net的URLLoader所代
替。URLLoader 支持新的字符集映射,他们是URLRequest, URLVariables, 和URLStream 。这些类提供了比以前更强大更灵活的处理能力。
有一些是没有改变的,比如读取的数据依然遵循Flash 播放器标准安全沙漏体系,也就是说读取的数据文件或脚本必须和flash 在同一个域内。

19.1.从文本文件中读取数据

问题
我想读取外部的文本文件的内容到flash上。
解决办法
使用URLLoader.load( )方法和DataFormat.VARIABLES 读取URL-编码数据
讨论
读取URL-编码数据时应该使用URLLoader.load( )方法。

load( )方法需要一个URLRequest实例作为参数,该参数指向文本文件的URL,这个URL即可以是相对路径也可以是绝对路径。另外URLLoader 需要进行配置把文本数据解释成URL-编码变量。设置URLLoader的dataFormat属性为DataFormat.VARIABLES常量:

import flash.net.*;
// 首先创建URLLoader对象
var example:URLLoader = new URLLoader( );
// 进行设置
example.dataFormat = DataFormat.VARIABLES;
// 读取绝对路径的URL
example.load( new URLRequest( "http://www.darronschall.com/example.txt" ) );
// 读取相对路径的URL,文本文件和swf文件在同一个目录下
example.load( new URLRequest( "example.txt" ) );
假设文本文件的内容如下:
someText=testing&someNumber=123
一旦调用了load( )方法,Flash播放器就会试图读取URL的数据填充URLLoader的data属性。读取完成后,Flash会试图解码这些内容并发出complete事件,指示数据已经读取完毕。这时候你可以添加处理函数来处理了。如果读取失败,根据失败的原因URLLoader会发出不同类型的异常事件,因此除了监听完成事件,还要监听那些异常事件。
load( )调用引发的异常有:
httpStatus     当试图读取数据,Flash播放器检测出错误的HTTP请求时发出
ioError            当遇到致命错误导致下载终止时发出
securityError 当试图读取安全沙漏允许以外的域数据时发出

下面的例子演示监听各种事件:

package {
	import flash.events.*;
	import flash.net.*;
	import flash.util.trace;
	public class Example {
		public function Example( ) {
			// Create the URLLoader instance to be able to load data
			var loader:URLLoader = new URLLoader( );
			// Define the event handlers to listen for success and failure
			loader.addEventListener( IOErrorEvent.IO_ERROR, handleIOError );
			loader.addEventListener( HTTPStatusEvent.HTTP_STATUS, handleHttpStatus );
			loader.addEventListener( SecurityErrorEvent.SECURITY_ERROR,handleSecurityError );
			loader.addEventListener( Event.COMPLETE, handleComplete );
			// Configure the loader to load URL-encoded variables
			loader.dataFormat = DataFormat.VARIABLES;
			// Attempt to load some data
			loader.load( new URLRequest( "example.txt" ) );
		}
		function handleIOError( event:IOErrorEvent ):void {
			trace( "Load failed: IO error: " + event.text );
		}
		function handleHttpStatus( event:HTTPStatusEvent ):void {
			trace( "Load failed: HTTP Status = " + event.status );
		}
		function handleSecurityError( event:SecurityErrorEvent ):void {
			trace( "Load failed: Security Error: " + event.text );
		}
		function handleComplete( event:Event ):Void {
			trace( "The data has successfully loaded" );
		}
	}

如果读取成功,Flash播放器把数据存在URLLoader实例的data属性上并发出complete事件。下面的例子演示处理complete事件:

			function handleComplete( event:Event ):void {
				// 把event target 转换为URLLoader
				var loader:URLLoader = URLLoader( event.target );
				// 输出获得的数据
				trace( "someText = " + data.someText );
				trace( "someNumber = " + data.someNumber );
			}
假设文本文件的内容如下:
someText=ActionScript+3.0+Cookbook&someNumber=3
通过for...in
语句遍历所有读取的变量:

			function handleComplete( event:Event ):void {
				var loader:URLLoader = URLLoader( event.target );
				// Use a for . . . in loop to loop over all of the variables that
				// were loaded
				for ( var property
					:String in loader.data ) {
					// property 就是data里的变量名
					trace( property + " = " + loader.data[property] );
				}
			}

19.2.从服务端脚本中读取变量

问题
我想从服务端脚本(ColdFusion, Perl, PHP, etc.)中读取变量.
解决办法
使用URLLoader.load( )方法和DataFormat.VARIABLES 读取由服务端脚本产生的URL-编码数据
讨论
ActionScript读取服务端脚本数据和读取文本文件的操作是一样的,当这些数据是从服务端数据库或其他资源中产生时,脚本必须输出为URL-编码的数据才行,如果你采用perl脚本,输出为URL-编码,就不需要其他任何调整了,看下面的例子:

#!/usr/bin/perl
# In a more practical example this value would be retrieved
# from a database or other server-side resource.
$someText = "test";
# 定义Content-Type 头.
print "Content-Type: text/plain\n\n";
# Output the name-value pair.
print "someText=$someText";
ColdFusion:
<cfsetting enablecfoutputonly="yes">
<cfprocessingdirective suppresswhitespace="yes">
<cfset someText = "test">
<cfoutput>someText=#someText#</cfoutput>
</cfprocessingdirective>
PHP:
<?php
$someText = "test";
echo "someText=$someText";
?>
上面的每个脚本例子中都返回一个变量:someText,用下面的ActionScript代码读取这个变量:
			package {
				import flash.events.*;
				import flash.net.*;
				import flash.util.trace;
				public class Example( ) {
					public function Example( ) {
						// 创建URLLoader实例
						var loader:URLLoader = new URLLoader( );
						// 定义事件处理函数
						loader.addEventListener( Event.COMPLETE, handleComplete );
						// 设置读取的是URL-编码变量
						loader.dataFormat = DataFormat.VARIABLES;
						// 尝试读取数据
						loader.load( new URLRequest( "getSomeText.cfm" ) );
					}
					private function handleComplete( event:Event ):void {
						var loader:URLLoader = URLLoader( event.target );
						trace( "someText = " + loader.data.someText );
					}
				}
			}
如果你事先不知道变量名,可以使用for...in语句遍历data。

19.3.读取文本块(包括HTML和XML)

问题
我想读取文本块,如HTML或XML.
解决办法
使用URLLoader.load( )和DataFormat.TEXT
讨论
ActionScript 3.0 处理数据的方式已经和ActionScript 1.0 和2.0完全不同了,在以前的版本中,LoadVars 实例有两个不同的回调函数用于处理通过URL读取的数据。当处理读取的数据时触发onLoad( )回调函数,当数据读取完成时触发onData( )回调函数。flash.net.URLLoader类和LoadVars类则不同,它只有一个complete事件和dataFormat属性用于决定如何解释这些下载的数据。dataFormat属性如果为DataFormat.TEXT,则会把数据解释为普通的文本内容,如果为DataFormat.VARIABLES则解释为URL-编码的变量,默认情况下,URLLoader把数据解释为文本。假设从外部读取一个名为example.html的HTML数据,内容大致如下:

<b>Title:</b> ActionScript 3.0 Cookbook<br />
<b>Authors:</b> Joey Lott, Darron Schall, Keith Peters<br />
<b>Publisher URL:</b> <a href="http://www.oreilly.com">www.oreilly.com</a>
下面的例子将读取并显示这些内容:

			package {
				import flash.display.*;
				import flash.text.*;
				import flash.events.*
					import flash.net.*;
				public class HTMLLoadingExample extends Sprite {
					private var _output:TextField;
					public function HTMLLoadingExample( ) {
						initializeOutput( );
						loadData( );
					}
					private function initializeOutput( ):void {
						_output = new TextField( );
						_output.width = stage.stageWidth;
						_output.height = stage.stageHeight;
						_output.html = true; // Enable HTML for the text field
						addChild( _output );
					}
					private function loadData( ):void {
						var loader:URLLoader = new URLLoader( );
						// Instruct the loader to read the file as plain text - This line is not
						// necessary because the dataFormat is DataFormat.TEXT by default.
						loader.dataFormat = DataFormat.TEXT;
						// Register an event handler for when the data is finished downloading
						loader.addEventListener( Event.COMPLETE, handleComplete );
						// Load the HTML text from the example.html file
						loader.load( new URLRequest( "example.html" ) );
					}
					private function handleComplete( event:Event ):void {
						var loader:URLLoader = URLLoader( event.target );
						// Assign the htmlText of the text field to the HTML text that was contained
						// in example.html. The data property of the URLLoader is the file contents.
						_output.htmlText = loader.data;
					}
				}
			}
data 属性的数据类型是根据dataFormat 属性的设置而决定的,如果设置为DataFormat.TEXT,则data 属性的值为String 类型,如果设置DataFormat.VARIABLES,则是Object 类型,如果设置为DataFormat.BINARY,则data 的数据类型为flash.util.ByteArray。

19.4.检测读取进度

问题
我想知道数据读取的进度
解决办法
监听URLLoader的progress事件
讨论
URLLoader类有个progress事件,当正在下载数据时该事件就会触发。Flash播放器传递一个flash.events.ProgressEvent实例给事件处理函数,以便检查该事件bytesLoaded和bytesTotal属性。bytesLoaded属性是指已经读取的数据量,bytesTotal属性是指总共要读取的数据量。
下面的代码演示如何监听progress事件:

			package {
				import flash.display.*;
				import flash.text.*;
				import flash.events.*
					import flash.net.*;
				public class CheckProgressExample extends Sprite {
					private var _output:TextField;
					public function CheckProgressExample( ) {
						initializeOutput( );
						loadData( );
					}
					private function initializeOutput( ):void {
						_output = new TextField( );
						_output.width = stage.stageWidth;
						_output.height = stage.stageHeight;
						addChild( _output );
					}
					private function loadData( ):void {
						var loader:URLLoader = new URLLoader();
						// Listen for the progress event to check download progress
						loader.addEventListener( ProgressEvent.PROGRESS, handleProgress );
						loader.load( new URLRequest( "example.txt" ) );
					}
					private function handleProgress( event:ProgressEvent ):void {
						// Calculate the percentage by multiplying the loaded-to-total
						// ratio by 100
						var percent:Number = Math.round( event.bytesLoaded / event.bytesTotal * 100 );
						_output.text = " Loaded: " + event.bytesLoaded + "\n"
							+ " Total: " + event.bytesTotal + "\n"
							+ "Percent: " + percent;
					}
				}
			}
需要注意的是URLLoader 不能边下载边处理数据,如果想这样可以用URLStream,这将在下一节讨论。

19.5.边下载边访问数据

问题
我想边下载边访问数据
解决办法
使用flash.net.URLStream 实例可在下在过程中立即读取二进制数据
讨论
第19.4章讨论了如何检测数据下载进度,但是由于URLLoader类本身的限制,只能等数据全部下载完才能读取数据,要想边下载边读取可使用URLStream类代替之。URLStream 可以边下载边以二进制形式读取数据, URLLoader 的dataFormat 属性为DataFormat.BINARY时和URLStream非常类似,它们有相同的事件,关键的区别是处理progress事件的方式不同而已。
在URLLoader 中,progress 事件在检测多少已下载的数据或显示下载进度方面有用,而URLStream 中的progress 事件允许使用bytesAvailable 属性和下列方法如readInt( ), readByte( ),readBoolean( )检查下载的数据。当使用URLLoader 不是很有效时或访问的数据都是二进制时最好使用URLStream。
下面的例子代码使用URLStream 读取一个.txt 文件,访问文件中的字节数据:

			package {
				import flash.display.*;
				import flash.events.*
					import flash.net.*;
				public class CheckProgressExample extends Sprite {
					public function CheckProgressExample( ) {
						var streamer:URLStream = new URLStream( );
						// Listen for the progress event to act on data
						// as it is received
						streamer.addEventListener( ProgressEvent.PROGRESS, handleProgress );
						streamer.load( new URLRequest( "example.txt" ) );
					}
					private function handleProgress( event:ProgressEvent ):void {
						// Cast the target of the vent as a URLStream
						var streamer:URLStream = URLStream( event.target );
						// 遍历所有已读取得字节数据
						while ( streamer.bytesAvailable > 0 ) {
							// Read a byte value and output it to the console window
							trace( "Read byte: " + streamer.readByte( ) );
						}
					}
				}
			}
从上面的代码中可以看到,在进行读之前最好检测下bytesAvailable 属性,如果读取的字节超出缓冲的结果则会抛出EOFError 异常。

19.6.发送数据给服务端脚本

问题
我想发送数据给服务端脚本
解决办法
创建一个包含数据的URLRequest实例,并用flash.net.sendToURL( )方法传递给服务端脚本,如果想在新的浏览器窗口中打开可使用flash.net.navigateToURL( )方法,如果想知道执行结果,可使用URLLoader.load( )方法。
讨论
如果不用处理结果,最好是用flash.net.sendToUrl( )方法发送数据,例如发送一个web表单数据,而服务端脚本处理后不用返回结果显示出来。但是sendToURL( )方法也就不会返回数据是否收到的确认消息了,因此在实际应用中并不很实用。如果只是想显示一个信息如"Thank you for submitting the form,"确认信息,表示服务端已成功收到,可使用URLLoader.load( )方法,3.12节和19.7节.都讨论过这个方法。
通过sendToUrl传递给服务端的URLRequest实例包含传递的数据以及传输方式,如果data属性设置为URLVariables实例,则发送名称/值对到服务器,也可以是flash.util.ByteArray,通过HTTPPOST 方式传递二进制数据到服务器, 或者是String 类型的数据作为XML-RPC ( 看http://www.xmlrpc.com)请求发送到服务器。

下面的代码演示:

			function sendData( ):void {
				// Create a request that sends data to the process.cfm page
				var request:URLRequest = new URLRequest( "process.cfm" );
				// Create some variables to send, someText and someNumber.
				var variables:URLVariables = new URLVariables( );
				variables.someText = "Some text to send";
				variables.someNumber = 26.2;
				// Set the data to be sent to the variables, created earlier
				request.data = variables;
				// Send the data to the script for processing
				sendToURL( request );
			}
传递给URLRequest的URL既可以是绝对地址也可以是相对地址,这可以通过Flash播放器安全沙漏进行管理,有关安全方面看第3.12节。
// 设置url属性为绝对地址
request.url = "http://www.darronschall.com/cgi-bin/submitVars.cgi";
// 设置为相对于swf 文件的地址
request.url = "cgi-bin/submitVars.cgi";
通过sendToURL( )方法发送的数据被服务器处理后,服务器返回的信息会被Flash播放器忽略掉,要想发送数据且打开指定的浏览器可使用navigateToURL( )方法,这个方法也sendToURL( )方法几乎一样,只是多了个参数,如果设为_blank即会在新的窗口显示响应结果,还可设置为_self 或_parent 。
// 在新的窗口中发送数据
navigateToURL( request, "_blank" );

如果想接收服务器返回的结果,可使用URLLoader.load( )方法(看3.12节和19.7节).默认情况下,使用sendToURL( ) 或navigateToURL( )方法,数据都是通过HTTP POST方法传输的,URLRequest的method属性指定数据传输的方式,如URLRequestMethod.GET指HTTP GET 和URLRequestMethod.POST指HTTP POST。

var request:URLRequest = new URLRequest( "cgi-bin/submit.cgi" );
// 创建发送的变量
var variables:URLVariables = new URLVariables( );
variables.someText = "Post me!";
request.data = variables;
// 设置传输方式HTTP POST
request.method = URLRequestMethod.POST;
// Send the request and open the response in a new window
navigateToURL( request, "_blank" );

19.7.发送变量并处理返回结果

问题
我想发送变量到服务器脚本,并处理返回的结果
解决办法
使用URLLoader.load( )方法且设置URLRequest实例的data属性
讨论
当需要处理服务器返回的结果时,应该使用URLLoader.load( )方法。比如一个flash的商店程序,它的商品分类都存在服务器数据库里,当用户点击一个分类,flash发送这个分类id给服务器脚本并返回这个分类的商品数据。URLLoader.load( ) 发送数据给服务器脚本的方式和sendToURL( ) ,navigateToURL( ) 是一样的,下面的完整例子发送数据到服务器脚本并返回URL-编码的值:

			package {
				import flash.display.*;
				import flash.text.*;
				import flash.events.*
					import flash.net.*;
				public class SendAndLoadExample extends Sprite {
					private var _output:TextField;
					public function SendAndLoadExample( ) {
						initializeOutput( );
						sendData( );
					}
					private function initializeOutput( ):void {
						_output = new TextField();
						_output.width = stage.stageWidth;
						_output.height = stage.stageHeight;
						addChild( output );
					}
					private function sendData( ):Void {
						// Create a URLRequest to contain the data to send
						// to process.cfm
						var request:URLRequest = new URLRequest( "process.cfm" );
						// Create name-value pairs to send to the server
						var variables:URLVariables = new URLVariables( );
						variables.method = "getProductDetail"
						variables.productId = 2;
						request.data = variables;
						// Create a URLLoader to send the data and receive a
						// response
						var loader:URLLoader = new URLLoader( );
						// Expect the script to return URL-encoded variables
						loader.dataFormat = DataFormat.VARIABLES;
						// Listen for the complete event to read the server response
						loader.addEventListener( Event.COMPLETE, handleComplete );
						// Send the data in the URLRequest off to the script
						loader.load( request );
					}
					private function handleComplete( event:Event ):void {
						var loader:URLLoader = URLLoader( event.target );
						// Expect the script to return name and description variables.
						// Display these values in a text field on the screen.
						_output.text = "Name: " + loader.data.name + "\n"
							+ "Description: " + loader.data.description;
					}
				}
			}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在安卓中,你可以使用串口库来实现串口的发送读取数据操作。你可以通过引用中提供的android-serialport-api地址来获取这个库。在这个库中,你可以使用相应的方法来进行串口数据的读取和写入。 要发送数据,你可以使用写入(发送)数据的方法。而要读取数据,你可以使用读取(接收)数据的方法。你可以参考引用中提供的示例代码来了解如何使用这些方法进行串口数据的发送和读取操作。 另外,需要注意的是,当退出串口通讯后,下位机可能会在此发送信息到端口,下次重新进入时,会有上次残留的数据。为了解决这个问题,你可以参考引用中提到的方法,修改SerialPort.c文件中的打开串口参数,满足设置停止位、奇偶校验等要求。 总结起来,安卓串口发送数据和读取数据的操作主要是通过使用串口库提供的方法来实现的,你可以参考引用中的库地址和示例代码来了解具体的操作步骤。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [android 使用服务读取串口数据实例](https://blog.csdn.net/weixin_30344519/article/details/117632840)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [Android串口通讯RS485发送和接收数据](https://blog.csdn.net/discode/article/details/115262165)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [android开发串口,修改串口为非阻塞模式](https://download.csdn.net/download/zfgzeng/10618362)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值