I was trying to write simple "FTP" program, but then suddenly an error occured. So this is a network with client and server and a server storages files uploaded from client, there is also a possibility to download files from server. But when I upload file it is saved in Server directory as an empty file, will someone help me find an error in code?
Here is Client
String nameOfFileToUp = fileFromFileChooser.getName();
System.out.println("fileChooserfile name= " + fileFromFileChooser.getName());
System.out.println("File path= " + fileFromFileChooser.getPath());
pw.println(nameOfFileToUp);
File sendFile = new File(fileFromFileChooser.getPath());
FileInputStream fis = new FileInputStream(sendFile);
int size =(int) fileFromFileChooser.length();
byte[] buffer = new byte[size+1];
int bytes = 0;
while((bytes = fis.read(buffer)) != -1)
{
out.write(buffer,0,bytes);
}
fis.close();
Where pw is PrintWriter,
And Server
FileOutputStream fos = new FileOutputStream(f);
DataOutputStream dops = new DataOutputStream(fos);
while(done)
{
fc = in.readLine();
if(fc == null)
{
done = false;
}
else
{
dops.writeChars(fc);
}
}
fos.close();
Can anyone help? Please
You need to flush/close the output stream.
Also, your server should not be reading by "line", it should be reading bytes (just like your client code).
Related
This question already has answers here:
Java multiple file transfer over socket
(3 answers)
Closed 5 years ago.
I am writing a program that has a client and server where the client will send a img file to the server. The code below is for the server where it will get stuck on that while loop from obIn.read blocking on its last run, so it never is able to return -1 and break the loop. It does break the loop for my Client. So I tried to flush it after the loop on the Client but it doesn't seem to do any good. I don't want to close obOut because that will in return close the socket which I want to keep open. The server end is where it receives the bites from the obIn(inputstream that is an instance variable) and writes it to a file that I have created.
//server receives file
File file = new File("image/image.png");
BufferedOutputStream fileOut = new BufferedOutputStream(new FileOutputStream(file));
byte[] bytes = new byte[1000];
int c = 0;
while((c = obIn.read(bytes)) != -1) {
fileOut.write(bytes, 0, c);
fileOut.flush();
System.out.println(c);
}
System.out.println(c);
fileOut.close();
System.out.println("File Created");
//Client
String imgPath = in.nextLine();
File file = new File(imgPath);
BufferedInputStream fileIn = new BufferedInputStream(new FileInputStream(file));
byte[] bytes = new byte[1000];
int c = 0;
while((c = fileIn.read(bytes)) != -1) {
obOut.write(bytes, 0, c);
obOut.flush();
System.out.println(c);
}
obOut.write(bytes, 0, 1000);
obOut.flush();
System.out.println(c);
fileIn.close();
System.out.println("File Sent");
This image is the output where the server is on top and the client is on bottom. That is where I found that the Server is stuck blocking.
Here is where I found this method and tried making it work for my setup. This is my first time working with streams.
In your client class try replacing write and flush function out side of while loop with obOut.close();
I have a functionality for add attachment. When we attach any file, it is uploaded to FTP server. For viewing purpose, there is a link that shows the file content from FTP server within the browser itself. I can open the file after downloading it from FTP server but i don't want to download or save the file on local machine. is there any way to open the file from FTP server without downloading or saving it on local machine?
The code that i wrote.
FTPClient ftpClient = new FTPClient();
ftpClient.connect(ftpServerIp);
boolean connectionStatus = ftpClient.login(ftpServerUserName, ftpServerPassword);
if(connectionStatus){
log.info("Connected successfully.");
}
ftpClient.changeWorkingDirectory(ftpServerUploadPath);
fos = new FileOutputStream(fileName);
boolean result = ftpClient.retrieveFile(fileName, fos);
log.info("result==>"+result);
Here the result is coming as true while retrieving the file. but i am not able to display the file contents. Is there any way to achieve it?
Any help is appreciated. Thanks in advance.
I have solved the problem by using below code.
FTPClient ftpClient = new FTPClient();
ftpClient.connect(ftpServerIp);
boolean connectionStatus = ftpClient.login(ftpServerUserName, ftpServerPassword);
if(connectionStatus){
log.info("Connected successfully.");
}
ftpClient.changeWorkingDirectory(ftpServerUploadPath);
InputStream stream = ftpClient.retrieveFileStream(fileName);
int length = 0;
ServletContext context = getServletConfig().getServletContext();
String mimetype = context.getMimeType( fileName );
response.setContentType( (mimetype != null) ? mimetype : "application/octet-stream" );
response.setHeader( "Content-Disposition", "attachment; filename=\"" + fileName + "\"" );
byte[] bbuf = new byte[fileName.length()];
DataInputStream in = new DataInputStream(stream);
while ((in != null) && ((length = in.read(bbuf)) != -1))
{
out.write(bbuf,0,length);
}
in.close();
out.flush();
out.close();
I got working over socket file sender, it worked perfectly, but I couldn't send large files with it. Always got heap error. Then I changed the code of client, so it would send file in chunks. Now I can send big files, but there is new problem. Now I recieve small files empty and larger files for example videos can't be played. Here is the code of client that sends file:
public void send(File file) throws UnknownHostException, IOException {
// Create socket
hostIP = "localhost";
socket = new Socket(hostIP, 22333);
//Send file
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
OutputStream os = socket.getOutputStream();
//Sending size of file.
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF(file.getName() + ":" + userName);
byte[] arr = new byte[1024];
try {
int len = 0;
while ((len = dis.read(arr)) != -1) {
dos.write(arr, 0, len);
}
} catch (IOException ex) {
ex.printStackTrace();
}
dos.flush();
socket.close();
}
and here is the server code:
void start() throws IOException {
// Starts server on port.
serverSocket = new ServerSocket(port);
int bytesRead;
while (true) {
connection = serverSocket.accept();
in = connection.getInputStream();
clientData = new DataInputStream(in);
String[] data = clientData.readUTF().split(":");
String fileName = data[0];
String userName = data[1];
output = new FileOutputStream("C:/" + fileName);
long size = clientData.readLong();
byte[] buffer = new byte[1024];
// Build new file
while (size > 0 && (bytesRead = clientData.read(buffer, 0, (int) Math.min(buffer.length, size))) != -1) {
output.write(buffer, 0, bytesRead);
size -= bytesRead;
}
output.close();
}
}
You failed to write out the length of the file to the stream in the client:
long size = clientData.readLong();
So that call in the server is reading the first 8 bytes of the actual file and who knows what that quantity is. You don't have to read the length from the stream since you only wrote a single file. After reading the filename, and username (not very secure is it?) you can just read the stream until EOF. If you ever wanted to send multiple files over the same open socket then you'd need to know the length before reading the file.
Also your buffers for reading are way to small. You should be at a minimum of 8192 instead of 1024. And you'll want to put all .close() in a finally block to make sure your server and clients shutdown appropriately if there is an exception ever.
I'm having a tough time figuring something out. (I'm pretty new to all this.)
I wrote this java pgm to ftp a large file to a destination server.
Here's the code (codes been modified a bit for display):
public static void ftpUpload(String path, String upfileName, String dirName) throws Exception
{
FTPClient client = new FTPClient();
client.addProtocolCommandListener((ProtocolCommandListener) new PrintCommandListener(new PrintWriter(System.out)));
client.enterLocalPassiveMode();
FileInputStream fis = null;
int reply;
try {
client.connect(ftpserver);
client.login(ftpuserid, ftppasswd);
reply = client.getReplyCode();
if(FTPReply.isPositiveCompletion(reply)){
client.changeWorkingDirectory(ftpdirectoryName + "/" + dirName);
boolean mkDir = client.makeDirectory(getCurrentMMMYY().toLowerCase());
client.changeWorkingDirectory(getCurrentMMMYY().toLowerCase());
//Create an InputStream of the file to be uploaded
fis = new FileInputStream(path + upfileName);
//Store file to server
client.storeFile(upfileName, fis);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fis != null) {
fis.close();
}
client.logout();
//client.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Something weird is happening on files I'm sending...
One of my files on the origination server is 82575786 in size, and when I ftp this file it almost sends the entire file. It actually sends 82574867. (missing 919)
Another file on the origination server is 717885, and when I ftp this file it almost sends the entire file. It actually sends 717522. (missing 363)
I pulled the log to see if something crashed, but it didn't show anything wrong with the transfer. Here are the 2 log entries showing the transfer.
[08/09/11 20:21:13:618 EDT] 00000043 SystemOut O 221-You have transferred 717522 bytes in 1 files.
221-You have transferred 82574867 bytes in 1 files.
Anyone's help would greatly be appreciated.
Thanks
Dan.
Are you transferring in ASCII mode instead of binary? ASCII mode converts CR/LF to LF and vice-versa depending on server and client settings.
Are you using Apache's FTP client? It says the default is ASCII, you could try setting BINARY_FILE_TYPE with setFileType:
client.setFileType(FTPClient.BINARY_FILE_TYPE);
To upload a binary File you have to use the FTP.BINARY_FILE_TYPE but is not enough.
You are using only an INPUT stream, and you need to use an outputstream too
I hope that this example will help you:
FTPClient client = new FTPClient();
client.connect("192.168.30.20");
client.login("pwd", "pwd");
client.setFileType(FTP.BINARY_FILE_TYPE);
String path_base = "/myPath/";
InputStream fis = new FileInputStream("A.pdf");
OutputStream os = client.storeFileStream(path_base+ "B.pdf");
byte buf[] = new byte[8192];
int bytesRead = fis.read(buf);
while (bytesRead != -1) {
os.write(buf, 0, bytesRead);
bytesRead = fis.read(buf);}
fis.close();
os.close();
client.completePendingCommand();
client.logout();
client.disconnect();
Hii i am uploading a file to server using socket and i need the percent of file loaded?how can i do that?i have the maximun value i.e the file length ,how can i get how much file has been uploaded?
FileInputStream fis = new FileInputStream(fil);
BufferedInputStream in = new BufferedInputStream(fis);
BufferedOutputStream out = new BufferedOutputStream(skt.getOutputStream());
//Write the file to the server socket
int i;
while ((i = in.read()) != -1) {
publishProgress(???);
out.write(i);
System.out.println(i);
}
I need to pass the length of file uploded in the publishProgress method.
using buffered copying
FileInputStream fis = new FileInputStream(fil);
BufferedInputStream in = new BufferedInputStream(fis);
BufferedOutputStream out = new BufferedOutputStream(skt.getOutputStream());
//Write the file to the server socket
int i;
int written = 0;
byte[] buf = new byte[512];
while ((i = in.read(buff)) != -1) {
out.write(buff,0,i);
written += i;
publishProgress((double)written/length);
//passing a double value from 0-1 to say how much is transmitted (length is length of file)
System.out.println(buff+", "+i);
}
To do this you need to do one of a couple of things:
Use a Flash uploader such as swfupload (see http://demo.swfupload.org/Documentation/) as these typically provide access to upload progress of this sort.
Provide a back channel of your own: perform the form submit with Ajax and then while the form submit occurs you run a javascript timer that hits a URL on the server with a key of some kind that corresponds to the upload. The URL on the server looks up how much of the file has been uploaded and returns that number and you pass that through to your uploadProgress method.
Below is your modified code. written holds the number of ints written to the socket.
FileInputStream fis = new FileInputStream(fil);
BufferedInputStream in = new BufferedInputStream(fis);
BufferedOutputStream out = new BufferedOutputStream(skt.getOutputStream());
//Write the file to the server socket
int i;
int written = 0;
while ((i = in.read()) != -1) {
out.write(i);
publishProgress(++written);
System.out.println(i);
}
javax.swing.ProgressMonitorInputStream