从服务器下载文件

问题描述:

这里我试图从服务器上下载一个文件到SD卡上。代码如下图所示:从服务器下载文件

try{ 
    FileConnection fconn = (FileConnection)Connector.open("file:///SDCard/BlackBerry/documents/Report.xml"); 
    if (fconn.exists()) { 
     fconn.delete(); 
    } 

    fconn.create(); 
    add(new RichTextField("Deleted and created", Field.NON_FOCUSABLE)); 

    HttpConnection connection = (HttpConnection)   
    Connector.open("http://127.0.0.1/xml/home.xml"); 
    add(new RichTextField("Connection success", Field.NON_FOCUSABLE)); 
    InputStream ds = connection.openInputStream(); 
    byte[] data = new byte[ds.available()]; 
    ds.read(data); 
    add(new RichTextField("Data read", Field.NON_FOCUSABLE)); 
    OutputStream outStream = fconn.openOutputStream(); 
    outStream.write(data); 
    outStream.close(); 
    add(new RichTextField("Data written succesfully", Field.NON_FOCUSABLE)); 
    fconn.close(); 

    } 
    catch (Exception e) { 
    // TODO: handle exception 
} 

的问题是,在emulatora我看到的第一个两个消息,即

  • 删除并创建
  • 连接成功

但经过,没有给出数据被写入的消息。 XML文件的大小是1KB。 可以帮我解决这个问题吗?我的代码中是否有任何问题或者是否存在其他问题?

首先,这条线:

add(new RichTextField("Deleted and created", Field.NON_FOCUSABLE)); 

让我觉得你是直接在事件线程,这是不好的做法,就这样做。如果连接超时或需要很长时间,那么您将冻结当时的GUI。你通常会产生一个工作线程来完成这样的长时间任务。

也就是说,你的代码可以工作,但它不是很健壮。很多事情可能会变坏。例如,以下行:

HttpConnection connection = (HttpConnection) Connector.open("http://127.0.0.1/xml/home.xml"); 

返回的连接可以为空,因此您必须检查它。您最好使用ConnectionFactory,因为它会为每种连接(WiFi,BES,TCP,...)附加正确的后缀。在模拟器中,我不确定您可以使用本地主机URL,因为它是本地工作站,但模拟BB设备必须通过MDS模拟器。

With FileConnection您还必须检查它是否为空,并且fconn.canRead也会返回true。考虑到并非每个设备都有一个SD卡插槽(最新的插槽)。您可以检查该卡是否可用,如this article中所述,或者让catch处理该例外情况。如果你在模拟器上测试,你将不得不“挂载”虚拟SD卡。

而且这一呼吁:

ds.read(data); 

将阻塞,直到服务器实际发送你的东西。这可能是正在发生的事情。

您必须检查您是否拥有正确的权限。对于文件的连接,你需要:

ApplicationPermissions.PERMISSION_FILE_API 

以及网络连接,这取决于你在哪里连接,你需要之一:

ApplicationPermissions.PERMISSION_INTERNET 
ApplicationPermissions.PERMISSION_SERVER_NETWORK 

最后提示:添加try-catch的finally子句,并关闭finally中的所有流和连接(如果它们不为null)。

+0

感谢4早期回复。我已经测试了所有的NULL值,我的连接也是成功的,但问题出在Input Stream对象创建。所以请给我一个输入流的解决方案,以及如何使用上面提到的所有权限。 – AMUL 2012-03-22 12:08:31

+0

inputstream行是实际建立HTTP连接的第一行。也许你正在超时。您应该让它至少运行3分钟,并记录异常。然后请张贴它。 – 2012-03-22 17:37:34

+0

关于权限,我认为它们在模拟器中是不需要的。在真实设备中,用户在安装时设置权限(或稍后通过选项菜单)。 – 2012-03-22 17:39:02

仅尝试在InputStream ds = connection.openInputStream();这行中发生HTTP连接失败,因此在此之后您看不到任何消息。失败的原因可能是因为模拟器无法访问指定的URL。

上线Connector.open("http://127.0.0.1/xml/home.xml");尝试将URL更改为http://127.0.0.1/xml/home.xml?interface=wifi

这将强制模拟器使用仿真的WLAN连接,它实际上是您的PC的网络接口。确保模拟器连接到Default WLAN connection。另外,为了查看代码中发生了什么,您最好添加调试消息(例如System.out.println("Got connection"))并使用调试器 - 只需在eclipse中按F11即可。而不是添加UI字段到屏幕上。

+0

谢谢donturner的回复,是的,我会尝试Wifi部分... – AMUL 2012-03-26 12:05:10