Android socket如何实现文件列表动态访问
程序员文章站
2022-03-07 13:58:07
目录idea服务端更新为了防止代码量上升可能带来的结构杂乱,我们对服务端架构进行优化,server包负责socket服务基础实现,data包负责处理各种安卓端的命令。将readsocketmsg,wr...
idea服务端更新
为了防止代码量上升可能带来的结构杂乱,我们对服务端架构进行优化,server包负责socket服务基础实现,data包负责处理各种安卓端的命令。
将readsocketmsg,writebackmsg方法单独拿出,创建一个socketmsg方法类,专门负责数据流的读取与写入。
socketmsg.java
package lrz.server; import java.io.*; import java.net.socket; import java.util.arraylist; public class socketmsg { public static arraylist<string> readsocketmsg(socket socket) throws ioexception { arraylist<string> msglist=new arraylist<string>(); inputstream inputstream = socket.getinputstream(); inputstreamreader reader = new inputstreamreader(inputstream, "utf-8"); bufferedreader bufferedreader=new bufferedreader(reader); string linenumstr = bufferedreader.readline(); int linenum=integer.parseint(linenumstr); for(int i=0;i<linenum;i++){ string str = bufferedreader.readline(); msglist.add(str); } //读取结束后,输入流不能关闭,此时关闭,会将socket关闭,从而导致后续对socket写操作无法实现 return msglist; } public static void writebackmsg(socket socket, arraylist<string> msgbacklist) throws ioexception { bufferedoutputstream os = new bufferedoutputstream(socket.getoutputstream()); outputstreamwriter writer=new outputstreamwriter(os,"utf-8"); writer.write(""+msgbacklist.size()+"\n"); //未真正写入的输出流,仅仅在内存中 writer.flush(); //写入输出流,真正将数据传输出去 for(int i=0;i<msgbacklist.size();i++){ writer.write(msgbacklist.get(i)+"\n"); writer.flush(); } } }
创建netfiledata.java作为文件夹访问的方法类,将exedir()方法放入其中。
netfiledata.java
package lrz.data; import java.io.file; import java.text.simpledateformat; import java.util.arraylist; import java.util.date; public class netfiledata { public static arraylist<string> exedir(string cmdbody) throws exception { // todo auto-generated method stub arraylist<string> backlist=new arraylist<string>(); file file = new file(cmdbody); file[] listfiles = file.listfiles(); for(file mfile:listfiles){ string filename = mfile.getname(); long lastmodified = mfile.lastmodified();//获取文件修改时间 simpledateformat dateformat = new simpledateformat("yyyy-mm-dd hh:mm:ss");//给时间格式,例如:2018-03-16 09:50:23 string filedate = dateformat.format(new date(lastmodified));//取得文件最后修改时间,并按格式转为字符串 string filesize="0"; string isdir="1"; if(!mfile.isdirectory()){//判断是否为目录 isdir="0"; filesize=""+mfile.length(); } backlist.add(filename+">"+filedate+">"+filesize+">"+isdir+">"); } return backlist; } }
serversocket01.java主函数则将以上方法移除,改为调用
package lrz.server; import lrz.data.netfiledata; import java.io.*; import java.net.inetaddress; import java.net.networkinterface; import java.net.serversocket; import java.net.socket; import java.util.arraylist; import java.util.enumeration; public class serversocket01 { int port = 8019;// 自定义一个端口,端口号尽可能挑选一些不被其他服务占用的端口,祥见http://blog.csdn.net/hsj521li/article/details/7678880 static int connect_count = 0;// 连接次数统计 arraylist<string> msgbacklist; public serversocket01() { // todo auto-generated constructor stub } public serversocket01(int port) { super(); this.port = port; } private void printlocalip(serversocket serversocket) {// 枚举打印服务端的ip try { system.out.println("服务端命令端口prot=" + serversocket.getlocalport()); enumeration<networkinterface> interfaces = null; interfaces = networkinterface.getnetworkinterfaces(); while (interfaces.hasmoreelements()) { networkinterface ni = interfaces.nextelement(); enumeration<inetaddress> addresss = ni.getinetaddresses(); while (addresss.hasmoreelements()) { inetaddress nextelement = addresss.nextelement(); string hostaddress = nextelement.gethostaddress(); system.out.println("本机ip地址为:" + hostaddress); } } } catch (exception e) { e.printstacktrace(); } } public void work() throws ioexception { // 注意:由于socket的工作是阻塞式,android端socket的工作必须在新的线程中实现,若在ui主线程中工作会报错 serversocket serversocket = new serversocket(port); printlocalip(serversocket); while (true) {// 无限循环,使之能结束当前socket服务后,准备下一次socket服务 system.out.println("waiting client to connect....."); socket socket = serversocket.accept();// 阻塞式,直到有客户端连接进来,才会继续往下执行,否则一直停留在此代码 system.out.println("client connected from: " + socket.getremotesocketaddress().tostring()); arraylist<string> cmdlist= socketmsg.readsocketmsg(socket); cmdlist.foreach(s -> system.out.println(s)); string cmdbody=cmdlist.get(0); try { msgbacklist= netfiledata.exedir(cmdbody); } catch (exception e) { e.printstacktrace(); } msgbacklist.foreach(s -> system.out.println(s)); socketmsg.writebackmsg(socket,msgbacklist); socket.close(); system.out.println("当前socket服务结束"); } } /** * @param args */ public static void main(string[] args) { // todo auto-generated method stub try { new serversocket01().work(); } catch (ioexception e) { // todo auto-generated catch block e.printstacktrace(); } } }
安卓端更新
使用listview显示文件夹内容,并且实现动态访问。
mainactivity.java更新了简单的listview显示,设立互动事件,在点击某个列表部分时向服务端发动指定命令,返回结果后更新列表,实现互动效果。
package com.example.android_app; import androidx.appcompat.app.appcompatactivity; import android.os.bundle; import androidx.annotation.nonnull; import android.os.build; import android.os.handler; import android.os.message; import android.view.view; import android.widget.adapterview; import android.widget.arrayadapter; import android.widget.button; import android.widget.edittext; import android.widget.listview; import android.widget.textview; import android.widget.toast; import java.util.arraylist; public class mainactivity extends appcompatactivity { public static final string key_server_ack_msg = "key_server_ack_msg"; private handler handler = null; edittext url,way,dir; listview lv; button submit; socketclient socketclient=null; string here; arraylist<string> data; int port; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); url=findviewbyid(r.id.url); way=findviewbyid(r.id.way); dir=findviewbyid(r.id.dir); lv=findviewbyid(r.id.listview); submit=findviewbyid(r.id.submit); handler=new handler(new handler.callback() { @override public boolean handlemessage(@nonnull message msg) { bundle data_bundle = msg.getdata(); data=data_bundle.getstringarraylist(key_server_ack_msg); data=datamaker(); printadapter(data); return false; } }); submit.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { port=integer.parseint(way.gettext().tostring()); here=dir.gettext().tostring(); getdata(); } }); lv.setonitemclicklistener(new adapterview.onitemclicklistener() { @override public void onitemclick(adapterview<?> parent, view view, int position, long id) { here=here+"/"+data.get(position); getdata(); } }); } private void getdata() { socketclient=new socketclient(url.gettext().tostring(),port,handler); socketclient.work(here); } private arraylist<string> datamaker() { arraylist<string> dataresult=new arraylist<>(); int i=data.size(); for (int j = 0; j <i ; j++) { string str=data.get(j); str=str.substring(0,str.indexof(">")); dataresult.add(str); } return dataresult; } private void printadapter(arraylist<string> data) { arrayadapter<string> arrayadapter=new arrayadapter<>(this,android.r.layout.simple_list_item_1,data); lv.setadapter(arrayadapter); } }
socketclient.java无变动
activity_main.xml布局添加listview,代替原先的textview
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <linearlayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <edittext android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="3" android:id="@+id/url" android:text="服务端ip"/> <edittext android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="3" android:id="@+id/way" android:text="8019"/> </linearlayout> <edittext android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/dir" android:text="d://"/> <button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="submit" android:id="@+id/submit"/> <listview android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/listview"/> </linearlayout>
补充一点:
安卓端访问的ip在服务端中查看,ip为服务端网络ip,我是红色圈中的,可以都试一下,一般都是倒数第二个长得像ip的这个,port在服务端主函数中设置,可以是任何数,8019为常用端
以上就是android socket如何实现文件列表动态访问的详细内容,更多关于android socket实现列表动态访问的资料请关注其它相关文章!