Java对文件的操作及UDP,TCP

1.文本文件复制

/*
将C盘下的一个文本文件复制到D盘下。
其实就是将C盘下的文件数据存储到D盘下的一个文件中

步骤:
1.在D盘中创建一个文件,用于存储C盘文件中的数据。
2.定义读取流和C盘文件关联
3.通过不断的读写完成数据存储。
4.关闭资源。
*/
//方法一
import java.io.*;
class CopyText {
    public static void main(String[] args) throws IOException{
        copy();
    }
    public static void copy(){
        FileReader fr = null;
        FileWriter fw = null;
        try{
            fr = new FileReader("c:\\demo.txt");
            fw = new FileWriter("d:\\demoD.txt",true);

            char[] buf = new char[1024];
            int len = 0;
            while((len=fr.read(buf))!=-1){
                fw.write(buf,0,len);
            }
        }catch (IOException e){
            throw new RuntimeException("读写失败");
        }finally{
            if(fr!=null)
            try{
                fr.close();
            }catch (IOException e){
                System.out.println(e.toString());
            }

            if(fw!=null)
            try{
                fw.close();
            }catch (IOException e){
                System.out.println(e.toString());
            }
        }
    }
}

//方法二
/*
通过缓冲区复制一个文本文件。
*/
import java.io.*;
class CopyTextByBuf{
    public static void main(String[] args){
        BufferedWriter bufw = null;
        BufferedReader bufr = null;
        try
        {
            bufw = new BufferedWriter(new FileWriter("e:\\bufD.txt",true)); 
            bufr = new BufferedReader(new FileReader("c:\\buf.txt")); 
            
            String line = null;//相当于中转站。
            while((line=bufr.readLine())!=null)
            {
                bufw.write(line);
                bufw.newLine();
                bufw.flush();
            }

        }
        catch (IOException e)
        {
            throw new RuntimeException("读写失败");
        }
        finally
        {
            if(bufw!=null)
            try
            {
                bufw.close();
            }
            catch (IOException e)
            {
                throw new RuntimeException("写入关闭失败");
            }

            if(bufr!=null)
            try
            {
                bufr.close();
            }
            catch (IOException e)
            {
                throw new RuntimeException("读取关闭失败");
            }
        }
    }
}

2.二进制文件(图片,视频等)复制

/*
复制一个图片(不要拿字符流处理媒体文件,字符流只处理文字数据)

思路:
1.用字节读取流对象和图片关联
2.用字节写入流对象创建一个图片文件,用于存储获取到的图片数据。
3.通过循环读写,完成数据的存储
4.关闭资源。
*/

import java.io.*;
class  CopyPic
{
    public static void main(String[] args)
    {
        FileOutputStream fos = null;
        FileInputStream fis = null;
        try
        {
            fos = new FileOutputStream("CopyofSrc.png");
            fis = new FileInputStream("src.jpg");

            byte[] buf = new byte[fis.available()];//定义一个刚刚好的缓冲区,不用再循环了。
            int len = 0;
            while((len = fis.read(buf))!=-1)
            {
                fos.write(buf);
            }
        }
        catch (IOException e)
        {
            throw new RuntimeException("读写失败");
        }
        finally
        {
            try
            {
                if(fos!=null)
                    fos.close();
            }
            catch (IOException e)
            {
                throw new RuntimeException("写入失败");
            }
            try
            {
                if(fis!=null)
                    fis.close();
            }
            catch (IOException e)
            {
                throw new RuntimeException("读取失败");
            }
        }   
    }
}

3.标准键盘读取/标准控制台输出

//读取键盘输入的最常见写法。
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
//写入控制台的最常用写法。
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));

4.UDP

/*
编写一个聊天程序
有收数据的部分和发数据的部分
这两部分需要同时执行,那就需要用到多线程技术,
一个线程控制接收,一个线程控制发送。

因为收和发动作是不一致的,所以要定义两个run方法,
而且这两个方法要封装到不同的类中。

*/

import java.io.*;
import java.net.*;
class Send implements Runnable
{
    private DatagramSocket ds ;
    public Send(DatagramSocket ds)
    {
        this.ds = ds;
    }
    public void run()
    {
        try
        {
            BufferedReader bufr = 
                new BufferedReader(new InputStreamReader(System.in));
            String line = null;
            while((line = bufr.readLine())!= null)
            {
                if("886".equals(line))
                    break;
                byte[] buf = line.getBytes();
                DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("localhost"),10003);
                
                ds.send(dp);
            }
        }
        catch (Exception e)
        {
            throw new RuntimeException("发送端失败");
        }
    }
}

class Rece implements Runnable
{
    private DatagramSocket ds ;
    public Rece(DatagramSocket ds)
    {
        this.ds = ds;
    }
    public void run()
    {
        try
        {
            while(true)
            {
                byte[] buf = new byte[1024*64];
                DatagramPacket dp = new DatagramPacket(buf,buf.length);

                ds.receive(dp);

                String ip = dp.getAddress().getHostAddress();
                String data = new String(dp.getData(),0,dp.getLength());

                System.out.println(ip+":"+data);
            }
        }
        catch (Exception e)
        {
            throw new RuntimeException("接收端失败");
        }   
    }   
}

class ChatDemo //必须掌握 
{
    public static void main(String[] args) throws Exception
    {
        DatagramSocket sendSocket = new DatagramSocket();
        DatagramSocket receSocket = new DatagramSocket(10003);

        new Thread(new Send(sendSocket)).start();
        new Thread(new Rece(receSocket)).start();
    }
}

5.TCP

/*
需求:客户端并发上传图片

*/
/*
客户端
1.服务端点
2.读取客户端已有的图片数据
3.通过socket输出流将数据发给服务端
4.读取服务端反馈信息
5.关闭
*/
import java.io.*;
import java.net.*;
class  UploadPicClient
{
    public static void main(String[] args) throws IOException
    {
        //主函数传参数  java UploadPicClient c:\1.png
        if(args.length!=1)
        {
            System.out.println("请选择一个jpg格式的图片文件");
            return;
        }

        File file = new File(args[0]);
        if(!(file.exists()&&file.isFile()))
        {
            System.out.println("上传的文件不存在或者不是文件");
            return ;
        }
        if(!(file.getName().endsWith(".png")))
        {
            System.out.println("上传的文件格式不正确,请重新选择!");
            return;
        }
        if(file.length()>1024*1024*5)
        {
            System.out.println("文件过大,不安好心,重新选择 !");
            return;
        }


        Socket s = new Socket("localhost",50005);
        
        FileInputStream in = new FileInputStream(file);

        OutputStream out = s.getOutputStream();

        byte[] buf = new byte[1024];
        int len = 0 ;
        while((len = in.read(buf))!=-1)
        {
            out.write(buf,0,len);
        }
        //告诉服务器数据写完了。
        s.shutdownOutput();

        InputStream is = s.getInputStream();

        byte[] bufIn = new byte[1024];
        int num = is.read(bufIn);
        
        System.out.println(new String(bufIn,0,num));

        s.close();
        in.close();
    }
}


/*
服务端
这个服务端有个局限性,当A客户端连接上以后,被服务端获取到,服务端执行具体流程。
这时B客户端连接,只有等待
因为服务端还没有处理完A客户端的请求,还要循环回来执行下次accept方法,所以
暂时获取不到B客户端对象。

那么为了可以让多个客户端同时并发访问服务端,
那么服务端最好就是将每个客户端封装到一个单独的线程中,这样,就可以
同时处理多个客户端请求。

如何定义线程呢?
只要明确了每一个客户端要在服务端执行的代码即可,将该代码存入run方法中。

*/

class PicThread implements Runnable
{
    private Socket s ;
    PicThread(Socket s )
    {
        this.s = s;
    }
    public void run()
    {
        String ip = s.getInetAddress().getHostAddress();
        int num = 1;//只能定义在函数内,在外的话是共享数据,不行的。
        try
        {
            System.out.println(ip+".....connected");

            InputStream in = s.getInputStream();

            File file = new File("d:\\server.png");
            while(file.exists())
                file = new File("d:\\server("+(num++)+").png");

            FileOutputStream out = new FileOutputStream(file);

            byte[] buf = new byte[1024];
            int len = 0 ;
            while((len = in.read(buf))!=-1)
            {
                out.write(buf,0,len);
            }

            OutputStream os = s.getOutputStream();
            os.write("上传图片成功!!".getBytes());


            out.close();
            s.close();  
        }
        catch (Exception e)
        {
            throw new RuntimeException(ip+"上传失败^_^");
        }
    }
}

class  UploadPicServer
{
    public static void main(String[] args) throws IOException
    {
        ServerSocket ss = new ServerSocket(50005);
        while(true)
        {
            Socket s = ss.accept();
            new Thread(new PicThread(s)).start();//服务器多线程玩法,几乎所有服务器都这么玩。
        }
    }
}

6.多线程实现方式

//方法一:
/*
创建两个线程,和主线程交替运行

线程都有自己默认的名称
Thread-编号  该编号从0开始

static Thread currentThread():获取当前线程对象。
getName():获取线程名称。

设置线程名称:setName或者通过构造函数
*/

class Test extends Thread
{
    public Test(String name)
    {
        super(name);//通过构造函数给线程取名。
    }
    public void run(){
        for(int x = 0;x <10;x++)
        {
            System.out.println((Thread.currentThread()==this)+"...."+this.getName()+"run..."+x);
        }
    }
}
class  ThreadTest
{
    public static void main(String[] args) 
    {
        Test t1 = new Test("one----");
        Test t2 = new Test("two++++");
        t1.start();
        t2.start();
        for(int i = 0 ;i<20;i++)
            System.out.println("hello world"+i);
    }
}


//方法二
class Ticket implements Runnable
{
    private int tick = 10;
    public void run()
    {
        while(true)
        {
            if(tick>0)
            {
                System.out.println(Thread.currentThread().getName()+"sale:"+tick--);
            }
        }
    }
}
class  TicketDemo
{
    public static void main(String[] args) 
    {
        Ticket t = new Ticket();

        Thread t1 = new Thread(t);
        Thread t2 = new Thread(t);
        Thread t3 = new Thread(t);
        Thread t4 = new Thread(t);
        t1.start();
        t2.start();
        t3.start();
        t4.start();

    }
}

7.死锁/线程间通信

/*
死锁程序经典案例。面试可以用

*/

class Test implements Runnable
{
    private boolean flag;
    Test(boolean flag)
    {
        this.flag = flag;
    }
    public void run()
    {
        if(flag)
        {
            while(true)
            {
                synchronized(MyLock.locka)
                {
                    System.out.println("if locka");
                    synchronized(MyLock.lockb)
                    {
                        System.out.println("if lockb");
                    }
                }
            }
        }
        else
        {
            while(true)
            {
                synchronized(MyLock.lockb)
                {
                    System.out.println("else lockb");
                    synchronized(MyLock.locka)
                    {
                        System.out.println("else locka");
                    }
                }
            }
        }
    }
}

class MyLock
{
    static Object locka = new Object();
    static Object lockb = new Object();
}

class  DeadLockTest
{
    public static void main(String[] args) 
    {
        Thread t1= new Thread(new Test(true));
        Thread t2= new Thread(new Test(false));
        t1.start();
        t2.start();

    }
}

/*
经典:面试用。

JDK1.5中提供了多线程升级解决方案
将同步synchronized替换成显示的Lock操作
将Object中的wait,notify,notifyAll,替换了condition对象。
该对象可以通过Lock锁进行获取

该示例中,实现了本方只唤醒对方的操作。

*/
class Resource
{
    private String name;
    private int count = 1;
    private boolean flag = false;
    
    private Lock lock = new ReentrantLock();
    private Condition condition_pro = lock.newCondition();
    private Condition condition_con = lock.newCondition();

    public void set(String name)throws InterruptedException
    {
        lock.lock();
        try
        {
            while(flag)
            condition_pro.await();
            this.name = name+"--"+count++;
            
            System.out.println(Thread.currentThread().getName()+"...生产者........."+this.name);
            flag = true;
            condition_con.signal();
        }finally
        {
            lock.unlock();//释放锁的动作一定要执行,放在finally里面
        }       
    }
    public void out()throws InterruptedException
    {
        lock.lock();
        try
        {
            while(!flag)
                condition_con.await();
            System.out.println(Thread.currentThread().getName()+"...消费者..."+this.name);
            flag = false;
            condition_pro.signal();

        }finally
        {
            lock.unlock();
        }
        

    }
}

class Producer implements Runnable
{
    private Resource res;

    Producer(Resource res)
    {
        this.res = res;
    }
    public void run()
    {
        while(true)
        {
            try
            {
                res.set("+商品+");
            }
            catch (InterruptedException e)
            {
            }
            
        }
    }
}
class Consumer implements Runnable
{
    private Resource res;
    Consumer(Resource res)
    {
        this.res = res;
    }
    public void run()
    {
        while(true)
        {
            try
            {
                res.out();
            }
            catch (InterruptedException e)
            {
            }
        }
    }
}


/*
线程间通讯:
其实就是多个线程在操作同一个资源
但是操作的动作不同。
*/

class Res
{
    private String name;
    private String sex;
    private boolean flag = false;
    public synchronized void set(String name,String sex)
    {
        this.name = name;
        this.sex = sex;
    }

    public synchronized void out()
    {
        System.out.println(name+"....."+sex);
    }
}


class Input implements Runnable
{
    private Res r;
    //Object obj = new Object();
    Input(Res r)
    {
        this.r = r;
    }
    public void run()
    {
        int x = 0;
        while(true)
        {
            //synchronized(Input.class)  只要在内存中是唯一的对象就行
            synchronized(r)
            {
                if(r.flag)
                    try{r.wait();}catch(Exception e){}
                if(x == 0)
                {
                    r.name = "mike";
                    r.sex = "man";
                }
                else
                {
                    r.name = "丽丽";
                    r.sex = "女";
                }
                x = (x+1)%2;
                r.flag = true;
                r.notify();
            }
        }
    }
}
class Output implements Runnable
{
    private Res r;
    //Object obj = new Object();
    Output(Res r)
    {
        this.r = r;
    }
    public void run()
    {
        while(true)
        {
            //synchronized(Input.class)  只要在内存中是唯一的对象就行
            synchronized(r)
            {
                if(!r.flag)
                    try{r.wait();}catch(Exception e){}
                System.out.println(r.name+"..."+r.sex);
                r.flag = false;
                r.notify();
            }
        }
    }
}

class InputOutput 
{
    public static void main(String[] args) 
    {
        Res r = new Res();

        Input in = new Input(r);
        Output op = new Output(r);

        Thread t1 = new Thread(in);
        Thread t2 = new Thread(op);

        t1.start();
        t2.start();
    }
}

/*
wait():
nofity():
notifyAll():
都使用在同步中,因为要对持有监视器(锁)的线程操作。
所以要使用在同步中,因为只有同步才具有锁。

为什么这些操作线程的方法要定义在Object类中呢?

因为这些方法在操作同步中线程时,都必须要标识它们所操作线程持有的锁,
只有同一个锁上的被等待线程,可以被同一个锁上的notify唤醒,
不可以对不同锁中的线程进行唤醒。

也就是说,等待和唤醒必须是同一个锁,而锁可以是任意对象,所以
可以被任意对象调用的方法定义在Object类中。

*/
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,335评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,895评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,766评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,918评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,042评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,169评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,219评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,976评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,393评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,711评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,876评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,562评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,193评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,903评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,699评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,764评论 2 351

推荐阅读更多精彩内容