最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

關(guān)于Java從本地文件復(fù)制到網(wǎng)絡(luò)文件上傳

 更新時(shí)間:2023年04月11日 09:46:39   作者:CrazyDragon_King  
這篇文章主要介紹了關(guān)于Java從本地文件復(fù)制到網(wǎng)絡(luò)文件上傳,File?和?IO?流其實(shí)是很相似的,都是將文件從一個(gè)地方轉(zhuǎn)移到另一個(gè)地方,這也是流的特點(diǎn)之一,需要的朋友可以參考下

文件復(fù)制和文件上傳

最近在看文件和IO流相關(guān)的東西,寫了一些代碼,發(fā)現(xiàn)這個(gè)有很多很有趣的地方。特別是對 File 和 IO 流的使用之后,我對這部分知識有了更深入的理解。今天就嘗試了從本地文件復(fù)制到網(wǎng)絡(luò)文件上傳,發(fā)現(xiàn)這部分其實(shí)是很相似的,都是將文件從一個(gè)地方轉(zhuǎn)移到另一個(gè)地方,這也是流的特點(diǎn)之一。 相信,看我博客之后,你也會有相同的理解。

文件復(fù)制

文件復(fù)制: 將一個(gè)本地文件從一個(gè)目錄,復(fù)制到另一個(gè)目錄。(通過本地文件系統(tǒng))

主要代碼

package dragon;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 本地文件復(fù)制:
 * 將文件從一個(gè)地方復(fù)制到另一個(gè)地方。
 * 
 * @author Alfred
 * */
public class FileCopy {
	
	public FileCopy() {}
	
	public void fileCopy(String target, String output) throws IOException {
		File targetFile = new File(target);
		File outputPath = new File(output);
		
		this.init(targetFile, outputPath);
		
		/**注意這里使用了 try with resource 語句,所以不需要顯示的關(guān)閉流了。
		 * 而且,再關(guān)閉流操作中,會自動調(diào)用 flush 方法,如果不放心,
		 * 可以在每個(gè)write 方法后面,強(qiáng)制刷新一下。
		 * */
		try (
			BufferedInputStream bis = new BufferedInputStream(new FileInputStream(targetFile));                //創(chuàng)建輸出文件
			BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(outputPath, "copy"+targetFile.getName())))){
			int hasRead = 0;
			byte[] b = new byte[1024];
			while ((hasRead = bis.read(b)) != -1) {
				bos.write(b, 0, hasRead);
			}
		}
		System.out.println("文件復(fù)制成功");
	}
	
	//數(shù)據(jù)校驗(yàn)及初始化工作
	private void init(File targetFile, File outputPath) throws FileNotFoundException {
		if (!targetFile.exists()) {
			throw new FileNotFoundException("目標(biāo)文件不存在:"+targetFile.getAbsolutePath());
		} else {
			if (!targetFile.isFile()) {
				throw new FileNotFoundException("目標(biāo)文件是一個(gè)目錄:"+targetFile.getAbsolutePath());
			}
		}	
		
		if (!outputPath.exists()) {
			if (!outputPath.mkdirs()) {   
				throw new FileNotFoundException("無法創(chuàng)建輸出路徑:"+outputPath.getAbsolutePath());
			}
		} else {
			if (!outputPath.isDirectory()) {
				throw new FileNotFoundException("輸出路徑不是一個(gè)目錄:"+outputPath.getAbsolutePath());
			}
		}
	}
}

測試類

package dragon;

import java.io.IOException;

public class FileCopyTest {
	public static void main(String[] args) throws IOException {
		String target = "D:/DB/BuilderPattern.png";
		String output = "D:/DBC/dragon/";
		FileCopy copy = new FileCopy();
		copy.fileCopy(target, output);
	}
}

執(zhí)行結(jié)果

注意:右邊文件是復(fù)制的結(jié)果,左邊的不是。(下面會提到!)

在這里插入圖片描述

說明

上面的代碼只是將一個(gè)本地文件從一個(gè)目錄,復(fù)制到另一個(gè)目錄,還是比較簡單的,這只是一個(gè)原理性的代碼,來說明輸入輸出流的應(yīng)用。將文件從一個(gè)地方復(fù)制到另一個(gè)地方。

網(wǎng)絡(luò)文件傳輸(TCP)

**網(wǎng)絡(luò)文件傳輸(TCP):**使用套接字(TCP)進(jìn)行演示,文件從一個(gè)地方復(fù)制到另一個(gè)地方。(通過網(wǎng)絡(luò)的方式。)

主要代碼

Server

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
	public static void main(String[] args) throws IOException {
		try (
			ServerSocket server = new ServerSocket(8080)){
			Socket client = server.accept();			
			//開始讀取文件
			try (
				BufferedInputStream bis = new BufferedInputStream(client.getInputStream());
				BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("D:/DBC/dragon", System.currentTimeMillis()+".jpg")))){
				int hasRead = 0;
				byte[] b = new byte[1024];
				while ((hasRead = bis.read(b)) != -1) {
					bos.write(b, 0, hasRead);
				}
			}
			System.out.println("文件上傳成功。");
		}
	}
}

Client

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class Client {
	public static void main(String[] args) throws UnknownHostException, IOException {
		try (Socket client = new Socket("127.0.0.1", 8080)){
			File file = new File("D:/DB/netFile/001.jpg");	
			//開始寫入文件
			try (
				BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
				BufferedOutputStream bos = new BufferedOutputStream(client.getOutputStream())){
				int hasRead = 0;
				byte[] b = new byte[1024];
				while ((hasRead = bis.read(b)) != -1) {
					bos.write(b, 0, hasRead);
				}
			}
		}
	}
}

執(zhí)行效果

執(zhí)行程序

在這里插入圖片描述

注意:這個(gè)上傳文件的目錄和本地文件復(fù)制是在同一個(gè)目錄,但是使用的方式不一樣,文件的命名方式不一樣,使用的是當(dāng)前的毫秒數(shù)。 復(fù)制前文件

在這里插入圖片描述

復(fù)制后文件

在這里插入圖片描述

說明

通過網(wǎng)絡(luò)的方式使用流,使用傳輸層的TCP協(xié)議,綁定了 8080 端口,這里需要一些網(wǎng)絡(luò)的知識,不過都是最基本的知識??梢钥闯鰜恚厦孢@個(gè) Server端和 Client端的代碼很簡單,甚至都沒有實(shí)現(xiàn)傳輸文件的后綴名!(哈哈,其實(shí)是我對套接字編程不太熟悉,傳輸文件名的話,我一開始嘗試,但是沒有成功。不過這個(gè)不影響這個(gè)例子,套接字我會抽時(shí)間來看的。哈?。?注意這里我要表達(dá)的意思通過網(wǎng)絡(luò)將文件從一個(gè)地方復(fù)制到另一個(gè)地方。(使用較為的是傳輸層的協(xié)議)

網(wǎng)絡(luò)文件傳輸(HTTP)

HTTP 是建立在 TCP/IP 協(xié)議之上的應(yīng)用層協(xié)議,傳輸層協(xié)議使用起來感覺還是比較麻煩的,不如應(yīng)用層協(xié)議用起來方便。

網(wǎng)絡(luò)文件傳輸(HTTP): 這里使用 Servlet(3.0以上)(JSP)技術(shù)來舉例,就以我們最常使用的文件上傳為例。

使用 HTTP 協(xié)議將文件從一個(gè)地方復(fù)制到另一個(gè)地方。

使用 apache 組件實(shí)現(xiàn)文件上傳

注意:因?yàn)樵嫉耐ㄟ^ Servlet 上傳文件較為麻煩,現(xiàn)在都是使用一些組件來達(dá)成這個(gè)文件上傳的功能的。(我沒有找到文件上傳最原始的寫法,想必應(yīng)該是很繁瑣的吧!) 這里使用兩個(gè)jar包:

  • commons-fileupload-1.4.jar
  • commons-io-2.6.jar

注意:在 apache 網(wǎng)站可以下載到。

上傳文件的 Servlet

package com.study;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

/**
 * Servlet implementation class UploadServlet
 */
@WebServlet("/UploadServlet")
public class UploadServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//如果不是文件上傳的話,直接不處理,這樣比較省事
		if (ServletFileUpload.isMultipartContent(request)) {
			//獲?。ɑ蛘邉?chuàng)建)上傳文件的路徑
			String path = request.getServletContext().getRealPath("/image");
			File uploadPath = new File(path);
			if (!uploadPath.exists()) {
				uploadPath.mkdir();
			}
			
			FileItemFactory factory = new DiskFileItemFactory();
			ServletFileUpload upload = new ServletFileUpload(factory);
			List<FileItem> items;
			try {
				items = upload.parseRequest(request);
				Iterator<FileItem> it = items.iterator();
				while (it.hasNext()) {
					FileItem item = it.next();
					//處理上傳文件
					if (!item.isFormField()) {
						String filename = new File(item.getName()).getName();
						System.out.println(filename);
						File file = new File(uploadPath, filename);
						item.write(file);
						response.sendRedirect("success.jsp");
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}

上傳文件的jsp中,只需要一個(gè)form表單即可。

<h1>文件上傳</h1>
<form action="NewUpload" method="post"  enctype="multipart/form-data">
    <input type="file" name="image">
    <input type="submit" value="上傳">
</form>

運(yùn)行效果

說明

雖然這樣處理對于上傳文件很好,但是因?yàn)槭褂玫亩际禽^為成熟的技術(shù),對于想了解輸入輸出流的我們來說,就不是那么好了。從這個(gè)例子中,基本上看不到輸入輸出流的用法了,都被封裝起來了。

使用 Servlet 3.0 以后的新技術(shù)實(shí)現(xiàn)文件上傳

package com.study;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

/**
 * Servlet implementation class FileUpload
 */
@MultipartConfig
@WebServlet("/FileUpload")
public class FileUpload extends HttpServlet {
	private static final long serialVersionUID = 1L;
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		Part part = request.getPart("image");
		String header = part.getHeader("Content-Disposition");
		System.out.println(header);
		String filename = header.substring(header.lastIndexOf("filename=\"")+10, header.lastIndexOf("\""));
		
		String fileSuffix = filename.lastIndexOf(".") != -1 ? filename.substring(filename.lastIndexOf(".")) : "";
		String uploadPath = request.getServletContext().getRealPath("/image");
		File path = new File(uploadPath);
		if (!path.exists()) {
			path.mkdir();
		}
		
		filename = UUID.randomUUID()+fileSuffix;
		try (
			BufferedInputStream bis = new BufferedInputStream(part.getInputStream());
			BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(path, filename)))){
			int hasRead = 0;
			byte[] b = new byte[1024];
			while ((hasRead = bis.read(b)) != -1) {
				bos.write(b, 0, hasRead);
			}
		}
		response.sendRedirect("success.jsp");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

使用 Servlet 3.0 的新特性實(shí)現(xiàn),這里使用了 @MultipartConfig注解。(如果不使用這個(gè)注解,會無法正常工作!感興趣的,可以多去了解一下。)

注意:下面這段代碼,這里我舍近求遠(yuǎn)了,但是這正是我想要看到的。同樣是輸入輸出流,注意這個(gè)和上面的幾個(gè)例子進(jìn)行對比。

try (
	BufferedInputStream bis = new BufferedInputStream(part.getInputStream());
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(path, filename)))){
		int hasRead = 0;
		byte[] b = new byte[1024];
		while ((hasRead = bis.read(b)) != -1) {
			bos.write(b, 0, hasRead);
		}
	}

不使用 apache 組件的更為簡單的方式是下面這種:

package com.study;

import java.io.File;
import java.io.IOException;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

/**
 * Servlet implementation class NewUpload
 */
@MultipartConfig
@WebServlet("/NewUpload")
public class NewUpload extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		Part part = request.getPart("image");
		String header = part.getHeader("Content-Disposition");
		System.out.println(header);
		String filename = header.substring(header.lastIndexOf("filename=\"")+10, header.lastIndexOf("\""));
		String fileSuffix = filename.lastIndexOf(".") != -1 ? filename.substring(filename.lastIndexOf(".")) : "";
		String uploadPath = request.getServletContext().getRealPath("/image");
		File path = new File(uploadPath);
		if (!path.exists()) {
			path.mkdir();
		}
		filename = uploadPath+File.separator+System.currentTimeMillis()+UUID.randomUUID().toString()+fileSuffix;
		part.write(filename);
		response.sendRedirect("success.jsp");
	}

}

真正寫入文件的只有這一步了,前面全是處理文件名和上傳文件路徑相關(guān)的代碼。使用 HTTP 的這三種方式都有處理文件名和上傳文件路徑這段代碼。

如果通過這段代碼,那就更看不出什么東西來了,只知道這樣做,一個(gè)文件就會被寫入相應(yīng)的路徑。

part.write(filename);

總結(jié)

這里從本地文件復(fù)制 -> 傳輸層文件復(fù)制 -> 應(yīng)用層文件復(fù)制,一起回顧了流的使用以及它們之間的共通點(diǎn)。這里說復(fù)制似乎不是很好,但是一時(shí)也想不出來什么好的說法,就湊合著看吧。這里的復(fù)制指的是:通過流將一個(gè)文件從一個(gè)地方傳到另一個(gè)地方。無論是本地文件系統(tǒng)還是通過 TCP協(xié)議或者 HTTP協(xié)議實(shí)現(xiàn)。 這幾種方式雖然用法都是不同的,但是仔細(xì)觀察還是能看出來相通之處,無論使用那種方式都離不開輸入、輸出流的使用。使用 HTTP 的方式,大多使用較為成熟的技術(shù),一般不會使用這么原始的代碼來進(jìn)行文件上傳(復(fù)制),但是第二種方式(舍近求遠(yuǎn))中也是使用了流進(jìn)行文件上傳演示,所以也是可以看出來的,雖然使用HTTP的三種方式不一樣,但是底層實(shí)現(xiàn),也是無法脫離 IO流的。 這里也可以看出來,Java EE 技術(shù)也是需要很好的 Java SE作為基礎(chǔ)的,如果你能熟練掌握 Java SE的文件復(fù)制(單個(gè)文件復(fù)制、整個(gè)目錄復(fù)制)、文件合并等操作,學(xué)習(xí) Java EE的文件上傳下載也是很輕松的。(但是,必要的網(wǎng)絡(luò)基礎(chǔ)知識還是需要掌握的,這樣有助于理解這個(gè)網(wǎng)絡(luò)的體系。)

結(jié)語: 熟練的掌握IO流的使用(我也沒有做到,哈哈?。?,可以幫助我們做很多事情,比如使用 Python 編寫爬蟲很簡單,但是如果掌握爬蟲的基本原理,我們也可以通過Java來實(shí)現(xiàn)。(這就對你對JavaIO流要有一定的掌握,否則會感覺到很難做到。)今天這個(gè)博客,主要是想說明,上面幾種方式之間的共通性,不知到你有沒有理解到。(具體的細(xì)節(jié)我沒有怎么說明,不過這都是一些基礎(chǔ)知識,應(yīng)該是不難的。)

到此這篇關(guān)于關(guān)于Java從本地文件復(fù)制到網(wǎng)絡(luò)文件上傳的文章就介紹到這了,更多相關(guān)Java本地文件復(fù)制到網(wǎng)絡(luò)上傳內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 使用Spring由構(gòu)造方法自動裝配

    使用Spring由構(gòu)造方法自動裝配

    這篇文章主要介紹了使用Spring由構(gòu)造方法自動裝配,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • java自定義驗(yàn)證器的實(shí)現(xiàn)示例

    java自定義驗(yàn)證器的實(shí)現(xiàn)示例

    在對外暴露接口中,我們通常會對入?yún)⑦M(jìn)行驗(yàn)證,比如一些字符串非空判斷等,本文主要介紹了java自定義驗(yàn)證器的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • 解決java轉(zhuǎn)義json出現(xiàn)\u0000 等亂碼的問題

    解決java轉(zhuǎn)義json出現(xiàn)\u0000 等亂碼的問題

    這篇文章主要介紹了解決java轉(zhuǎn)義json出現(xiàn)\u0000 等亂碼的問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03
  • 關(guān)于SpringCloud分布式系統(tǒng)中實(shí)現(xiàn)冪等性的幾種方式

    關(guān)于SpringCloud分布式系統(tǒng)中實(shí)現(xiàn)冪等性的幾種方式

    這篇文章主要介紹了關(guān)于SpringCloud分布式系統(tǒng)中實(shí)現(xiàn)冪等性的幾種方式,冪等函數(shù),或冪等方法,是指可以使用相同參數(shù)重復(fù)執(zhí)行,并能獲得相同結(jié)果的函數(shù),這些函數(shù)不會影響系統(tǒng)狀態(tài),也不用擔(dān)心重復(fù)執(zhí)行會對系統(tǒng)造成改變,需要的朋友可以參考下
    2023-10-10
  • Java中將File轉(zhuǎn)化為MultipartFile的操作

    Java中將File轉(zhuǎn)化為MultipartFile的操作

    這篇文章主要介紹了Java中將File轉(zhuǎn)化為MultipartFile的操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • JAVA中的字段校驗(yàn)(validation)

    JAVA中的字段校驗(yàn)(validation)

    這篇文章主要介紹了JAVA中的字段校驗(yàn)(validation)用法,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • 對arraylist中元素進(jìn)行排序?qū)嵗a

    對arraylist中元素進(jìn)行排序?qū)嵗a

    這篇文章主要介紹了對arraylist中元素進(jìn)行排序?qū)嵗a,還是比較不錯的,這里分享給大家,供需要的朋友參考。
    2017-11-11
  • Java線程組與未處理異常實(shí)例分析

    Java線程組與未處理異常實(shí)例分析

    這篇文章主要介紹了Java線程組與未處理異常,結(jié)合實(shí)例形式分析了java線程組處理異常的相關(guān)技巧與操作注意事項(xiàng),需要的朋友可以參考下
    2019-09-09
  • Java計(jì)時(shí)新姿勢StopWatch詳解

    Java計(jì)時(shí)新姿勢StopWatch詳解

    這篇文章主要介紹了Java計(jì)時(shí)新姿勢StopWatch,最近公司來了個(gè)大佬,從他那里學(xué)到不少東西,其中一個(gè)就是計(jì)時(shí)的新姿勢「StopWatch」,需要的朋友可以參考下
    2019-07-07
  • 詳解Java8新特性Stream之list轉(zhuǎn)map及問題解決

    詳解Java8新特性Stream之list轉(zhuǎn)map及問題解決

    這篇文章主要介紹了詳解Java8新特性Stream之list轉(zhuǎn)map及問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09

最新評論

水富县| 额敏县| 沅陵县| 宣化县| 余庆县| 古交市| 广丰县| 广西| 六盘水市| 义乌市| 吉木萨尔县| 水富县| 太保市| 秦皇岛市| 武鸣县| 赤水市| 呈贡县| 金昌市| 岢岚县| 保定市| 武平县| 邹平县| 长顺县| 德庆县| 剑河县| 红桥区| 江川县| 库车县| 湘西| 萨嘎县| 丁青县| 资源县| 宝清县| 葵青区| 周口市| 五大连池市| 比如县| 永新县| 吴江市| 陵水| 叙永县|