Maison  >  Article  >  Java  >  Comment copier un fichier local vers un fichier réseau et le télécharger à l'aide de Java ?

Comment copier un fichier local vers un fichier réseau et le télécharger à l'aide de Java ?

WBOY
WBOYavant
2023-04-25 15:49:081477parcourir

    Copie de fichier

    Copie de fichier : Copiez un fichier local d'un répertoire à un autre. (Via le système de fichiers local)

    Code principal
    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;
    
    /**
     * 本地文件复制:
     * 将文件从一个地方复制到另一个地方。
     * 
     * @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 语句,所以不需要显示的关闭流了。
    		 * 而且,再关闭流操作中,会自动调用 flush 方法,如果不放心,
    		 * 可以在每个write 方法后面,强制刷新一下。
    		 * */
    		try (
    			BufferedInputStream bis = new BufferedInputStream(new FileInputStream(targetFile));                //创建输出文件
    			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("文件复制成功");
    	}
    	
    	//数据校验及初始化工作
    	private void init(File targetFile, File outputPath) throws FileNotFoundException {
    		if (!targetFile.exists()) {
    			throw new FileNotFoundException("目标文件不存在:"+targetFile.getAbsolutePath());
    		} else {
    			if (!targetFile.isFile()) {
    				throw new FileNotFoundException("目标文件是一个目录:"+targetFile.getAbsolutePath());
    			}
    		}	
    		
    		if (!outputPath.exists()) {
    			if (!outputPath.mkdirs()) {   
    				throw new FileNotFoundException("无法创建输出路径:"+outputPath.getAbsolutePath());
    			}
    		} else {
    			if (!outputPath.isDirectory()) {
    				throw new FileNotFoundException("输出路径不是一个目录:"+outputPath.getAbsolutePath());
    			}
    		}
    	}
    }
    Classe de test
    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);
    	}
    }
    Résultats d'exécution

    Remarque :Le fichier de droite est le résultat d'une copie, celui de gauche ne l'est pas. (mentionné ci-dessous !)

    Comment copier un fichier local vers un fichier réseau et le télécharger à laide de Java ?

    Explication

    Le code ci-dessus copie simplement un fichier local d'un répertoire à un autre. Il s'agit simplement d'un code de principe pour illustrer les applications du flux de sortie d'entrée. Copiez des fichiers d'un endroit à un autre.

    Transfert de fichiers réseau (TCP)

    **Transfert de fichiers réseau (TCP) : **En utilisant des sockets (TCP) pour la démonstration, les fichiers sont copiés d'un endroit à un autre. (Par le réseau.)

    Code principal

    Serveur

    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);
    				}
    			}
    		}
    	}
    }
    Effet d'exécution

    Programme d'exécution

    Comment copier un fichier local vers un fichier réseau et le télécharger à laide de Java ?

    A noter : L'annuaire et la zone locale de le fichier téléchargé Les fichiers sont copiés dans le même répertoire, mais de différentes manières. Les fichiers sont nommés différemment et le nombre actuel de millisecondes est utilisé. Fichier avant la copie

    Comment copier un fichier local vers un fichier réseau et le télécharger à laide de Java ?

    Fichier après copie

    Comment copier un fichier local vers un fichier réseau et le télécharger à laide de Java ?

    Instructions

    Utilisez le flux via le réseau, utilisez le protocole TCP de la couche de transport, liez le port 8080, certains réseaux sont connaissances requises ici, mais ce sont les connaissances les plus élémentaires. On peut voir que les codes côté serveur et côté client ci-dessus sont très simples, et ils n'implémentent même pas le nom de suffixe du fichier transféré ! (Haha, en fait, je ne suis pas très familier avec la programmation des sockets. En ce qui concerne le transfert de noms de fichiers, je l'ai essayé au début, mais j'ai échoué. Cependant, cela n'affecte pas cet exemple. Je vais prendre le temps de regarder les sockets. Ha !) Notez ce que je veux dire ici Copiez des fichiers d'un endroit à un autre sur le réseau. (Le protocole le plus couramment utilisé est le protocole de couche transport)

    Transfert de fichiers réseau (HTTP)

    HTTP est un protocole de couche application construit sur le protocole TCP/IP. Le protocole de couche transport semble plus difficile à utiliser et ne l'est pas. aussi bon que la couche application. Le protocole est facile à utiliser.

    Transfert de fichiers réseau (HTTP) : Nous utilisons ici la technologie Servlet (3.0 ou supérieur) (JSP) comme exemple, en prenant comme exemple notre téléchargement de fichiers le plus couramment utilisé.

    Copiez des fichiers d'un endroit à un autre en utilisant le protocole HTTP.

    Utilisez des composants Apache pour implémenter le téléchargement de fichiers

    Remarque : étant donné que le téléchargement de fichiers d'origine via Servlet était plus gênant, certains composants sont désormais utilisés pour réaliser cette fonction de téléchargement de fichiers. (Je n'ai pas trouvé la manière la plus originale d'écrire un téléchargement de fichier. Cela doit être très fastidieux !) Deux packages jar sont utilisés ici :

    • commons-fileupload-1.4.jar

    • commons-io -2.6 .jar

    Remarque : peut être téléchargé à partir du site Web d'Apache.

    La Servlet qui télécharge des fichiers

    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)) {
    			//获取(或者创建)上传文件的路径
    			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();
    			}
    		}
    	}
    }

    Dans la jsp qui télécharge des fichiers, un seul formulaire est nécessaire.

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

    Effet de fonctionnement

    Explication

    Bien que ce traitement soit bon pour le téléchargement de fichiers, car il utilise des technologies relativement matures, il n'est pas si bon pour ceux d'entre nous qui veulent comprendre les flux d'entrée et de sortie. À partir de cet exemple, vous ne pouvez pratiquement pas voir l'utilisation des flux d'entrée et de sortie, ils sont tous encapsulés.

    Utilisation de la nouvelle technologie après Servlet 3.0 pour implémenter le téléchargement de fichiers

    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);
    	}
    
    }

    En utilisant les nouvelles fonctionnalités de Servlet 3.0, l'annotation @MultipartConfig est utilisée ici. (Si vous n'utilisez pas cette annotation, elle ne fonctionnera pas correctement ! Si vous êtes intéressé, vous pouvez en savoir plus.)

    Remarque : Dans le code suivant, je vais trop loin ici, mais c'est exactement ce que je souhaite voir. Il s'agit également d'un flux d'entrée et de sortie. Faites attention à comparer cela avec les exemples ci-dessus.

    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);
    		}
    	}

    La méthode la plus simple sans utiliser le composant Apache est la suivante :

    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");
    	}
    
    }

    C'est la seule étape qui écrit réellement le fichier. Les précédentes sont tous des codes liés au traitement des noms de fichiers et des chemins de fichiers téléchargés. Ces trois méthodes d'utilisation de HTTP ont toutes du code qui gère les noms de fichiers et les chemins de téléchargement des fichiers.

    如果通过这段代码,那就更看不出什么东西来了,只知道这样做,一个文件就会被写入相应的路径。

    part.write(filename);

    Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

    Déclaration:
    Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer