欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android socket如何实现文件列表动态访问

程序员文章站 2022-03-07 13:58:07
目录idea服务端更新为了防止代码量上升可能带来的结构杂乱,我们对服务端架构进行优化,server包负责socket服务基础实现,data包负责处理各种安卓端的命令。将readsocketmsg,wr...

Android socket如何实现文件列表动态访问

idea服务端更新

Android socket如何实现文件列表动态访问

为了防止代码量上升可能带来的结构杂乱,我们对服务端架构进行优化,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如何实现文件列表动态访问的详细内容,更多关于android socket实现列表动态访问的资料请关注其它相关文章!