1.文本文件復(fù)制
/*
將C盤下的一個文本文件復(fù)制到D盤下。
其實就是將C盤下的文件數(shù)據(jù)存儲到D盤下的一個文件中
步驟:
1.在D盤中創(chuàng)建一個文件,用于存儲C盤文件中的數(shù)據(jù)。
2.定義讀取流和C盤文件關(guān)聯(lián)
3.通過不斷的讀寫完成數(shù)據(jù)存儲。
4.關(guān)閉資源。
*/
//方法一
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());
}
}
}
}
//方法二
/*
通過緩沖區(qū)復(fù)制一個文本文件。
*/
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;//相當(dāng)于中轉(zhuǎn)站。
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("寫入關(guān)閉失敗");
}
if(bufr!=null)
try
{
bufr.close();
}
catch (IOException e)
{
throw new RuntimeException("讀取關(guān)閉失敗");
}
}
}
}
2.二進(jìn)制文件(圖片,視頻等)復(fù)制
/*
復(fù)制一個圖片(不要拿字符流處理媒體文件,字符流只處理文字?jǐn)?shù)據(jù))
思路:
1.用字節(jié)讀取流對象和圖片關(guān)聯(lián)
2.用字節(jié)寫入流對象創(chuàng)建一個圖片文件,用于存儲獲取到的圖片數(shù)據(jù)。
3.通過循環(huán)讀寫,完成數(shù)據(jù)的存儲
4.關(guān)閉資源。
*/
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()];//定義一個剛剛好的緩沖區(qū),不用再循環(huán)了。
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.標(biāo)準(zhǔn)鍵盤讀取/標(biāo)準(zhǔn)控制臺輸出
//讀取鍵盤輸入的最常見寫法。
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
//寫入控制臺的最常用寫法。
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
4.UDP
/*
編寫一個聊天程序
有收數(shù)據(jù)的部分和發(fā)數(shù)據(jù)的部分
這兩部分需要同時執(zhí)行,那就需要用到多線程技術(shù),
一個線程控制接收,一個線程控制發(fā)送。
因為收和發(fā)動作是不一致的,所以要定義兩個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("發(fā)送端失敗");
}
}
}
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
/*
需求:客戶端并發(fā)上傳圖片
*/
/*
客戶端
1.服務(wù)端點
2.讀取客戶端已有的圖片數(shù)據(jù)
3.通過socket輸出流將數(shù)據(jù)發(fā)給服務(wù)端
4.讀取服務(wù)端反饋信息
5.關(guān)閉
*/
import java.io.*;
import java.net.*;
class UploadPicClient
{
public static void main(String[] args) throws IOException
{
//主函數(shù)傳參數(shù) 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);
}
//告訴服務(wù)器數(shù)據(jù)寫完了。
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();
}
}
/*
服務(wù)端
這個服務(wù)端有個局限性,當(dāng)A客戶端連接上以后,被服務(wù)端獲取到,服務(wù)端執(zhí)行具體流程。
這時B客戶端連接,只有等待
因為服務(wù)端還沒有處理完A客戶端的請求,還要循環(huán)回來執(zhí)行下次accept方法,所以
暫時獲取不到B客戶端對象。
那么為了可以讓多個客戶端同時并發(fā)訪問服務(wù)端,
那么服務(wù)端最好就是將每個客戶端封裝到一個單獨的線程中,這樣,就可以
同時處理多個客戶端請求。
如何定義線程呢?
只要明確了每一個客戶端要在服務(wù)端執(zhí)行的代碼即可,將該代碼存入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;//只能定義在函數(shù)內(nèi),在外的話是共享數(shù)據(jù),不行的。
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();//服務(wù)器多線程玩法,幾乎所有服務(wù)器都這么玩。
}
}
}
6.多線程實現(xiàn)方式
//方法一:
/*
創(chuàng)建兩個線程,和主線程交替運行
線程都有自己默認(rèn)的名稱
Thread-編號 該編號從0開始
static Thread currentThread():獲取當(dāng)前線程對象。
getName():獲取線程名稱。
設(shè)置線程名稱:setName或者通過構(gòu)造函數(shù)
*/
class Test extends Thread
{
public Test(String name)
{
super(name);//通過構(gòu)造函數(shù)給線程取名。
}
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.死鎖/線程間通信
/*
死鎖程序經(jīng)典案例。面試可以用
*/
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();
}
}
/*
經(jīng)典:面試用。
JDK1.5中提供了多線程升級解決方案
將同步synchronized替換成顯示的Lock操作
將Object中的wait,notify,notifyAll,替換了condition對象。
該對象可以通過Lock鎖進(jìn)行獲取
該示例中,實現(xiàn)了本方只喚醒對方的操作。
*/
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()+"...生產(chǎn)者........."+this.name);
flag = true;
condition_con.signal();
}finally
{
lock.unlock();//釋放鎖的動作一定要執(zhí)行,放在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) 只要在內(nèi)存中是唯一的對象就行
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) 只要在內(nèi)存中是唯一的對象就行
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():
都使用在同步中,因為要對持有監(jiān)視器(鎖)的線程操作。
所以要使用在同步中,因為只有同步才具有鎖。
為什么這些操作線程的方法要定義在Object類中呢?
因為這些方法在操作同步中線程時,都必須要標(biāo)識它們所操作線程持有的鎖,
只有同一個鎖上的被等待線程,可以被同一個鎖上的notify喚醒,
不可以對不同鎖中的線程進(jìn)行喚醒。
也就是說,等待和喚醒必須是同一個鎖,而鎖可以是任意對象,所以
可以被任意對象調(diào)用的方法定義在Object類中。
*/
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。