# Verzeichnisstrukturen & Dateien über Socketverb. übertra



## ConBug (13. Jul 2004)

Moin!
Ich habe folgendes Anliegen:
Ich möchte Dateien in ihren Verzeichnisstrukturen von einem Rechner auf einen Server übertragen. Der Server läuft und lauscht auf einen Port. Der Client kann momentan eine Datei übertragen, die auch sauber ankommt. Hier mal
der Code:



```
****************************************************
Server Class
****************************************************
import java.io.*;
import java.net.*;

public class Server
{

	private int port;
	
	Server()
	{
		port = 1024;
	}
	
	Server(int port)
	{
		this.port = port;
	}
	
	public int getPort()
	{
		return port;
	}
	
	public void start()
	{
		System.out.println("\nServer gestartet!\n----------------");

		char[] whirl = {'|','/','-','\\'};
		byte[] buffer = new byte[65536];
		int len;

		try
		{
			ServerSocket serverSock = new ServerSocket(port);
			Socket inSock;
			
			while(true)			
			{
				try
				{			
					inSock = serverSock.accept();
			
					InputStream in = inSock.getInputStream();
				
					int fnameLen = in.read();
			
					in.read(buffer, 0, fnameLen);
			
					String fname = new String();
					char[] array = new char[fnameLen];
						
					for (int i=0; i < fnameLen; i++)
						fname = fname + (array[i] = (char) buffer[i]);
			
					System.out.print(">> Uebertragung: '" + fname + "'  ");
						
					FileOutputStream fos = new FileOutputStream(fname);
					
					int w = 0;
					int x = 0;
							
					while ((len = in.read(buffer)) !=  -1)
					{
						if (x == 300)
						{
							System.out.print("\b" + whirl[w++]);
							if (w == 4)
								w=0;
							x=0;
						}
						
					
						fos.write(buffer, 0, len);
						x++;											
					}
			
					fos.close();
					System.out.println("\b beendet!");
					in.close();
					inSock.close();
				}
				catch(IOException e)
				{
					System.err.println("Eine Verbindung ist fehlgeschlagen!");
					System.err.println("Grund: " + e.getMessage());
					System.err.println("Server weiterhin aktiv...");
				}
			}
		}
		catch(IOException e)
		{System.err.println("Fehler bei I/O!: " + e.getMessage());}

	System.out.println("----------------\nServer beendet!");
	}
}
****************************************************
Server Run
****************************************************
public class ServerTest
{

	public static void main(String[] args)
	{
		Server myServer;
		
		myServer = new Server(1024);
		
		myServer.start();
	}
}
****************************************************
****************************************************
Client Class
****************************************************
import java.io.*;
import java.net.*;


public class ClientV2
{
	private String dateiname, serverIP;
	private int buffersize, serverPort;
	
	ClientV2(String dateiname, String serverIP)
{
	this.dateiname=dateiname;
	this.serverIP=serverIP;
	buffersize=1024;
	serverPort=1024;
}

ClientV2(String dateiname, String serverIP, int buffersize, int serverPort)
{
	this.dateiname=dateiname;
	this.serverIP=serverIP;
	this.buffersize=buffersize;
	this.serverPort=serverPort;
	
}

void datenUebertragen()
{

	
	System.out.println("Client gestartet!\n----------------");
		
			byte[] buffer = new byte[buffersize];
			int len = 0;
		
			try
			{
			
				Socket outSock = new Socket(serverIP, serverPort);
			
				OutputStream out = outSock.getOutputStream();
			
				String fname = dateiname;
				int fnameLen = fname.length();
			
				out.write(fnameLen);
				buffer = fname.getBytes();
				out.write(buffer, 0, fnameLen);
									
				FileInputStream fis = new FileInputStream(fname);
								
				while ((len=fis.read(buffer)) != -1)
				{
					out.write(buffer, 0, len);
				}
				fis.close();
				out.close();
				outSock.close();
				System.out.println("----------------\n Client getötet");
			}
			catch(IOException e)
			{
				System.err.println("Das war wohl nix! 6 setzen: "+ e.getMessage());
			}
}
}
****************************************************
Client Run
****************************************************

public class TestClient 
{

	public static void main(String[] args) 
	{
		ClientV2 myClient1;
		ClientV2 myClient2;
		myClient1=new ClientV2("ersteDatei.pdf", "192.168.1.4", 1024, 1024);
	//	myClient2=new ClientV2("andereDatei.gif", "192.168.1.4", 1024, 1024);
		myClient1.datenUebertragen(); 
	//	myClient2.datenUebertragen();
		
	}
}
****************************************************
****************************************************
```

Ich würde nun gerne anstatt ersteDatei.pdf und andereDatei.pdf gerne einen "relativen" Verzeichnisbaum übergeben (also alles was unterhalb des Startverzeichnisses der java Anwendung liegt) und auf der Serverseite diese Verzeichnisstruktur replizieren und mit den entsprechenden Dateien der Clientseite "befüllen" .

Gibt es schon irgendwelche sinnvollen Klassen, die vielleicht eine Verzeichnisstruktur liefern, die ich mit 'mkdirs' auf der anderen Seite erzeugen kann, so dass ich die hier beschriebenen Klassen weiterverwenden kann? Oder sollte ich da besser einen ganz anderen Weg gehen? Socketverbindung muss sein und die Abbildung des relativen VErzeichnbaumes...

Wichtig ist halt vor allem, das ich von einem Fileobjekt relative Pfade bekomme...




Gruß ConBug 

PS: Ähhh ich suche hier keine perfekte Lösung...nur eine Idee, wie ich da rangehen kann :shock:


----------



## meez (13. Jul 2004)

Mach ein Archiv draus...z.B.: ZIP Ansonsten müsstest du File Object versenden...


----------



## ConBug (13. Jul 2004)

@meez

Archiv geht nicht, weil das "Gerät" auf dem der Client läuft nicht zippen oder anderweitig packen kann. Das wird über das Versenden von einzelnen Objekten als Bytearray laufen müssen...

 :? 
Gruß ConBug

...aber danke für die Idee!


----------



## meez (13. Jul 2004)

Warum...Du kannst auf dem Client doch einen Archiver implementieren.. ???:L


----------



## ConBug (13. Jul 2004)

Das ist kein Kompuster (so im landläufigen Sinne), auf dem der Client läuft - da läuft Java drauf, irgend ein OS, an das man aber nicht ran kommt und so - daher bin ich auf eine reine Java Lösung angewiesen...

 :arrow: ...soistdasnämlich...  :idea: 

Gruß ConBug


----------



## meez (13. Jul 2004)

Eben....
Hier eine reine Java-Implementation, um ZIP -Dateien zu packen und entpacken....



```
import java.util.*;
import java.util.zip.*;
import java.io.*;


		
	public void Zip(File zipFileName, File baseDir) throws Exception {
		InputStream in;
		ZipOutputStream out;
		Vector files;
		String file;
		int n;
		byte[] byteBuffer;
		byteBuffer = new byte[1024];			
		out = new ZipOutputStream(new FileOutputStream(zipFileName));  
       		

		files = <ALLE FILES, DIE DU WILLST ALS VECTOR ;)>;


		for (int i=0; i<files.size(); i++) {
			file = (String) files.get(i);						
		       	in = new FileInputStream(file);   
			file = file.substring(baseDir.getParent().length(), file.length());   			
			if (! file.startsWith("."))
				file="." + file;		
			out.putNextEntry(new ZipEntry(file));
                	while ((n = in.read(byteBuffer)) != -1)
				out.write(byteBuffer, 0, n);		
  			in.close();
			
         	}
         	out.close();
	}
	
	public void unZip(File zipFileName, File targetDir) throws Exception {
		ZipFile zf;
		ZipEntry entry;		 
		InputStream in;
		OutputStream out;
		File file;
		File dir;		
		int n;
		byte[] byteBuffer;
		byteBuffer = new byte[1024];					 		 
		zf = new ZipFile(zipFileName);					 
		for (Enumeration e = zf.entries();e.hasMoreElements();) {			
			entry = (ZipEntry) e.nextElement();
          		file = new File(targetDir.getPath() + "/" + entry.getName());
			if (entry.isDirectory()) 
      				file.mkdirs();				
    			else {			
				dir = new File(file.getParent());
				dir.mkdirs();
				in = zf.getInputStream(entry);								
				out = new FileOutputStream(file);
				while ((n = in.read(byteBuffer)) != -1)
					out.write(byteBuffer, 0, n);
				in.close();	
				out.close();			
			}
			
	  	}
		
        }
```


----------



## ConBug (13. Jul 2004)

:idea:  :idea:  :idea:  :idea:  Aaaaah!

Das ist ja eine ganz spannende Variante... Klingt gut und praktisch, da bastel ich mal ein wenig dran rum...


Danke Dir!

Gruß ConBug!


----------



## ConBug (13. Jul 2004)

...die andere Variante läuft auch...ich muss für die Optik noch die Klassen ein wenig auseinander rupfen und dann poste ich das morgen auch hier!

Gruß ConBug

 :wink:


----------



## meez (13. Jul 2004)

Zweifle nie wieder an meiner Weisheit... :meld:


----------



## ConBug (14. Jul 2004)

meez hat gesagt.:
			
		

> Zweifle nie wieder an meiner Weisheit... :meld:



...*extremverbeug* ... nein Meister... natürlich nicht Meister ...nie wieder Meister...

Dazu fällt mir noch ein:
*
Wir leben zwar alle unter demselben Himmel, haben aber deswegen lange noch nicht alle denselben Horizont. 
*
 :wink:  :wink: 

Hier mal mein Code:


```
++++++++++++++++++++++++++++++++++++++
ServerClass
++++++++++++++++++++++++++++++++++++++

/******************************************
 * Server öffnet eine Socket Verbindung über
 * die ByteArrays mpfangen werden. Die Dateien
 * werden auf dem Server mit ihren relativen 
 * Pfaden abgespeichert.
 ******************************************/
 
import java.io.*;
import java.net.*;

public class Server
{

	private int port;
	
	Server()
	{
		port = 1024;
	}
	
	Server(int port)
	{
		this.port = port;
	}
	public void start()
	{
		System.out.println("\nServer gestartet!\n----------------");

		//Das Wichtigste überhaupt ;-)
                                char[] whirl = {'|','/','-','\\'};
		byte[] buffer = new byte[65536];
		int len;
		
		try
		{
			ServerSocket serverSock = new ServerSocket(port);
			Socket inSock;
			
			while(true)			
			{
				try
				{			
					inSock = serverSock.accept();
			
					InputStream in = inSock.getInputStream();
				
					int fnameLen = in.read();
			
					in.read(buffer, 0, fnameLen);
			
					String fname = new String();
					char[] array = new char[fnameLen];
						
					for (int i=0; i < fnameLen; i++)
						fname = fname + (array[i] = (char) buffer[i]);
					
						
					System.out.println(fname);	
					
					File newf = new File ("Kopie\\" + fname);
					
					
					System.out.print(">> Uebertragung: '" + fname + "'  ");
					
					newf.getParentFile().mkdirs();
					
					FileOutputStream fos = new FileOutputStream(fname);
					
					int w = 0;
					int x = 0;
							
					while ((len = in.read(buffer)) !=  -1)
					{
						if (x == 300)
						{
							System.out.print("\b" + whirl[w++]);
							if (w == 4)
								w=0;
							x=0;
						}
						x++;
					
						fos.write(buffer, 0, len);
																	
					}
			
					fos.close();
					System.out.println("\b beendet!");
					in.close();
					inSock.close();
				}
				catch(IOException e)
				{
					System.err.println("Eine Verbindung ist fehlgeschlagen!");
					System.err.println("Grund: " + e.getMessage());
					System.err.println("Server weiterhin aktiv...");
				}
			}
			
		}
		catch(IOException e)
		{System.err.println("Fehler bei I/O!: " + e.getMessage());}

	System.out.println("----------------\nServer beendet!");
	}
}
++++++++++++++++++++++++++++++++++++++
ServerMain
++++++++++++++++++++++++++++++++++++++
public class ServerTest
{

	public static void main(String[] args)
	{
		Server myServer;	
		myServer = new Server(1024);	
		myServer.start();
	}
}

++++++++++++++++++++++++++++++++++++++
ClientClass
++++++++++++++++++++++++++++++++++++++

/****************************************
 * ClientCopy arbeitet mit einem Array von 
 * File Objekten und sendet Byte Arrays  
 * an eine Server IP, auf einen Port.
 * ***************************************/

import java.io.*;
import java.net.*;

public class ClientCopy
{
	private File[] dateien;
	private String serverIP;
	private int buffersize, serverPort;
	
	ClientCopy(File[] dateien, String serverIP)
	{
		this.dateien=dateien;
		this.serverIP=serverIP;
		buffersize=1024;
		serverPort=1024;
	}

	ClientCopy(File[] dateien, String serverIP, int buffersize, int serverPort)
	{
		this.dateien=dateien;
		this.serverIP=serverIP;
		this.buffersize=buffersize;
		this.serverPort=serverPort;
	}

	void datenUebertragen()
	{
		System.out.println("Client gestartet!\n----------------");
		
		byte[] buffer = new byte[buffersize];
		int len = 0;
		
		try
		{	
						
				for (int i=0; i < dateien.length; i++)
			{
				Socket outSock = new Socket(serverIP, serverPort);
				OutputStream out = outSock.getOutputStream(); 
				String fname = dateien[i].getPath();
				
				int fnameLen = fname.length();
			
				out.write(fnameLen);
				buffer = fname.getBytes();
				out.write(buffer, 0, fnameLen);
									
				FileInputStream fis = new FileInputStream(dateien[i].getAbsolutePath());
				System.out.println(">"+fname);
				System.out.println(">"+fis);
				System.out.println(dateien[i].getAbsolutePath());
					
				while ((len=fis.read(buffer)) != -1)
				{
					out.write(buffer, 0, len);
				}
				fis.close();
				out.close();
				outSock.close();
			}		
			
			System.out.println("----------------\n Client getötet");
		}
		catch(IOException e)
		{System.err.println("Java wurde zerstört, wenden Sie sich an Ihren Administrator: "+ e.getMessage());}
	}
}

++++++++++++++++++++++++++++++++++++++
FoundFilesCopy
++++++++++++++++++++++++++++++++++++++

/****************************************
 * FoundFilesCopy arbeitet mit einem relativen
 * Verzeichnispfad und durchsucht ihn 
 * rekursiv nach Dateien. Fileobjekte dieser 
 * Dateien werden in einem Array gesammelt 
 * und zurückgegeben.
 * ***************************************/

import java.io.File;

class FoundFilesCopy
{
  private File[] fileNames;
  	  	
  public File[] getContent()
  {
	  return fileNames;
  }
  	
  public File[] gather(String path)
  {
	  File rootFObj, dummyFObj;
		  rootFObj = new File(path);
			
	  String[] entryNames;
	  File[] foundFileNames = new File[0];
   
		  entryNames=rootFObj.list();
			
		  for (int i=0; i < entryNames.length; i++)
		  {
			  dummyFObj = new File(rootFObj.getPath(),entryNames[i]);
		  
			  if (dummyFObj.isFile())
			  {
				  File[] subFoundFileNames = new File[foundFileNames.length + 1 ];
				  for (int j=0; j < foundFileNames.length; j++)
					  subFoundFileNames[j] = foundFileNames[j];
				  								  subFoundFileNames[foundFileNames.length] = dummyFObj;	
				  foundFileNames = subFoundFileNames;
			  }
			  else
			  {
				File[] subContent;
				FoundFilesCopy dContent = new FoundFilesCopy();
			  	
				subContent = dContent.gather(dummyFObj.getPath());
			  	
					File[] subFoundFileNames = new File[subContent.length + foundFileNames.length];
		
					int help = foundFileNames.length;
					for (int j=0; j < foundFileNames.length; j++)
					  subFoundFileNames[j] = foundFileNames[j];
					for (int j=0; j < subContent.length; j++)
							subFoundFileNames[help + j] = subContent[j];
							
					foundFileNames = subFoundFileNames; 		
			  }
		  }

	  return foundFileNames;
  }
}

++++++++++++++++++++++++++++++++++++++
CopyMain
++++++++++++++++++++++++++++++++++++++

import java.io.File;
 
public class CopyMain
{
	
	public static void main(String[] args)
  {
	  System.out.println("Programm gestartet!\n--------------------");
    
	  File rootFObj;
      	
		rootFObj = new File(args[0]);
               
	  System.out.println("Mount <<|-V7-|>> " + rootFObj.getPath()+"\n-------------");
	         
	  File[] fileNames;
		FoundFilesCopy namesGathered = new FoundFilesCopy();
		
		fileNames = namesGathered.gather(rootFObj.getPath());      
	  
		for (int i=0; i < fileNames.length; i++)
		{
					System.out.print(fileNames[i].getName()+ "\t");
					System.out.print(fileNames[i].length()+" Bytes\t");
					System.out.println(fileNames[i].getPath());
		}          
    
		System.out.println("------------");
		System.out.println(fileNames.length + " Dateien gefunden!");
		
		ClientCopy myClient; 
		myClient = new ClientCopy(fileNames, "192.168.1.4", 1024, 1024);
		myClient.datenUebertragen(); 
      
	  System.out.println("--------------------\nProgramm beendet!");
  }

}
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
```
[/b]

Das kopiert ganze Filesysteme ohne zu packen und legt sie realtiv auf dem Server ab. Der Clientparameter sollten natürlich mit Port und IP mit dem Server korrespondieren...

Gruß ConBug

@meez
Deine Zipvariante ist so schick, die werde ich auch noch reinbasteln.... Daaaaanke!!!

 :toll:  :toll:  :applaus:  :applaus:  :applaus:  :applaus:  :toll:  :toll:


----------



## Guest (15. Jul 2004)

weiter gehts....

Das ist ja jetzt alles ganz schick und spannend (weil geht), es überträgt komplette Verzeichnisse und schreibt sie in ein einmaliges mit Datum und Uhrzeit generiertes Verezeichnis.

Ich habe mir so gedacht, nun könnte es ja passieren, dass 2 Clients gleichzeitig (kurz nacheinander) auf den Server zugreifen - was passiert: 

Der Server legt soviele Verzeichnisse an, wie es Clientanfragen gibt wirft aber die Dateien durcheinander ...ist ihm nicht zu verübeln...
Da dachte ich mir so: Threads...

Der Server landet in einer Endlosschleife, sobald der Client eine Datei übertragen hat - der Client beendet sich mit FehlerGemacht (also Exception) und Socket closed.

Ich veruche mal den relevanten Code zusammenzustellen: 


```
+++++++++++++++++++++++++++++++++++++++++++
ServerStart
+++++++++++++++++++++++++++++++++++++++++++
public class ServerTest
{

	public static void main(String[] args)
	{
		Server myServer;
		
		myServer = new Server(1024);
		
		myServer.start();
	}
}
+++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++
ServerClass
+++++++++++++++++++++++++++++++++++++++++++
import java.io.*;
import java.net.*;


public class Server
{

	private int port;
	
	Server()
	{
		port = 1024;
	}
	
	Server(int port)
	{
		this.port = port;
	}
		
	public void start()
	{
		System.out.println("\nServer gestartet!\n----------------");
		
		
		ServerSocket serverSock=null;

		try
		{
			serverSock = new ServerSocket(port);
			Socket inSock=null;
			
			while(true)			
			{
				try
				{			
					inSock = serverSock.accept();
					new SingleService(inSock);
					try
					{
						Thread.sleep(1500);
					}
					catch(InterruptedException e){}
				}
				catch(IOException e)
				{
					System.err.println("Eine Verbindung ist fehlgeschlagen!");
					System.err.println("Grund: " + e.getMessage());
					System.err.println("Server weiterhin aktiv...");
				}
			}
		}
		catch(IOException e)
		{
			System.err.println("ServerSocket Fehler: " + e.getMessage());
		}
		finally
		{
			try
			{
				serverSock.close();
			}
			catch(IOException e){}
			System.out.println("----------------\nServer beendet!");
		}
	}
}
+++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++
ServerThreadClass
+++++++++++++++++++++++++++++++++++++++++++

import java.net.*;
import java.io.*;

public class SingleService extends Thread
{
	private Socket inSock;
	
	SingleService(Socket inSock)
	{
		this.inSock = inSock;
		start();
	}

	
	public void run()
	{
		
		byte[] buffer = new byte[65536];
		int len, last=0;
		DirDate dirdate = new DirDate();
	
		while(true)			
		{
			try
			{			
				InputStream in = inSock.getInputStream();
				  
				int fnameLen = in.read();
					
				in.read(buffer, 0, fnameLen);
			
				String fname = new String();
				char[] array = new char[fnameLen];
						
				for (int i=0; i < fnameLen; i++)
					fname = fname + (array[i] = (char) buffer[i]);
						
				File newfile = new File (dirdate.getDirDate()+ "\\" + fname);
					
				System.out.print(">> Uebertragung: '" + fname + "'  ");
					
				newfile.getParentFile().mkdirs();
					
				FileOutputStream fos = new FileOutputStream(dirdate.getDirDate()+ "\\" + fname);
					
											
				while ((len = in.read(buffer)) !=  -1)
				{
						fos.write(buffer, 0, len);
				}
			
				fos.close();
				System.out.println(" beendet!");
				if ((last = in.read()) == 1)
				{
					in.close();
					inSock.close();
					break;
				
				}
								
				in.close();
			}
			catch(IOException e)
			{
				System.err.println("Eine Verbindung ist fehlgeschlagen!");
				System.err.println("Grund: " + e.getMessage());
				System.err.println("Server weiterhin aktiv...");
			}
		}
	}
}
--------------------------------------------------------------------------------------

Fehlermeldung auf dem Server ist:
"Eine VErbindung ist fehlgeschlagen
Grund: Socket closed
Server ist weiterhin aktiv"
```

Eine Datei wird richtig übertragen - dann funzt es nicht mehr...

Ich muss ja sich Socket nach jeder Datei schließen, sonst wird eine Datei mit der Größe des Gesamtverzeichnisses erzeugt - das ist auch dumm - 

Wo ist denn hier der Wurm?

Gruß ConBug


----------



## ConBug (15. Jul 2004)

*
....das letzte is nicht von Gast sondern von ConBug....war wohl nicht eingelocht...
*


Gruß ConBug


----------



## ConBug (16. Jul 2004)

Progblem ist gelöst... soll ichs posten oder ist  es schon lang genug?

Gruß ConBug

 :###


----------

