SmbFileOutputStream write creating corrupted jpg files - java

I'm using JCIFS SmbFileOutputStream write to upload jpg (and mp4) files to a share on a local Windows network. While this works well most of the time, I sometimes find that the resulting files are corrupt - e.g. if it's a jpg perhaps only the top part of the photo will be legible/visible.
I have the upload in a try/catch block, but it is not throwing an exception. Is there any way that I can verify that a file has been uploaded correctly?
try {
if (debugging_on) {
logger.info("UploadService.011 UploadFiles: uploading file:" + destFileName);
}
SmbFileOutputStream sfos = new SmbFileOutputStream(sFile);
FileInputStream fileInputStream = new FileInputStream(new File(
sSourceFilePath));
byte[] buf = new byte[16 * 1024 * 1024];
int len;
while ((len = fileInputStream.read(buf)) > 0) {
sfos.write(buf, 0, len);
}
fileInputStream.close();
sfos.close();
// Update the database to include the date/time of this upload
millisStart = Calendar.getInstance().getTimeInMillis();
sql = "UPDATE upload_history SET file_uploaded_date = "
+ millisStart + " WHERE filename = '" + filename + "'";
db.execSQL(sql);
} catch (Exception e) {
mNotifyBuilder.setContentText("Upload error - check folder permissions");
mNotificationManager.notify(1, mNotifyBuilder.build());
return "WriteFailure";

sfos.close();
needs to go before
fileInputStream.close();
Close the output before you close the input,
Adding 'sfos.flush()' couldn't hurt.

Related

Filetransfer over Socket in Java, wont go out of while-loop

I am trying to create a simple server-client-program where the user can upload and download files. I have got the Sockets and Streams to work, and I can upload a file to the server. But whenever one file has been uploaded the Server-side seems to get stuck in the loop that reads the streams and forwards it to the Server-file.
Server Code:
InputStream in = clientSocket.getInputStream();
String filePath = "......."
+ op[1];
System.out.println(op[0] + ": " + filePath);
FileOutputStream out = new FileOutputStream(filePath);
byte[] bytes = new byte[16*1024];
int count;
while ((count = in.read(bytes)) > 0) {
out.write(bytes, 0, count);
}
Client Code:
String filePath = "...."
+ path;
System.out.println("Attempting: " + filePath);
dos = new DataOutputStream(serverSocket.getOutputStream());
fis = new FileInputStream(filePath);
byte[] buffer = new byte[4096];
while (fis.read(buffer) > 0) {
dos.write(buffer);
}
dos.flush();
fis.close();
The problem is that the program gets stuck at the while-loop, so the Server can not perform anything else. There are no errors or anything...
You never close the stream on the client side. Add dos.close() after dos.flush()!

How to know video is successfully uploaded or not?

I have a method which takes a file and upload it on given path.
Here is my service
public String fileUpload(MultipartFile file) throws IOException {
log.debug("uploading video");
File fileUpload = new File(file.getOriginalFilename());
if (!file.isEmpty()) {
InputStream inputStream = file.getInputStream();
byte[] buf = new byte[1024];
FileOutputStream fileOutputStream = new FileOutputStream(new File(
fileUploadPath + File.separator
+ file.getOriginalFilename()));
int numRead = 0;
while ((numRead = inputStream.read(buf)) >= 0) {
fileOutputStream.write(buf, 0, numRead);
}
inputStream.close();
fileOutputStream.close();
}
else {
return Constants.EMPTY_FILE;
}
}
After uploading the file i have to save it information in my database.File size could be 1GB or 2GB.My problem is how would i know the file is fully uploaded or not.So that i can save it status uploaded successfully in my db.
Anyone please help me looking into this ?
You can create a MD5 hash before uploading the file. Take a look at this on creating MD5 hash with JavaScript via How to calculate md5 hash of a file using javascript.
And after the file is completely uploaded, you can use MessageDigest to create another MD5 hash to compare it again the one before the upload. (See example: http://javarevisited.blogspot.com/2013/06/how-to-generate-md5-checksum-for-files.html)

What is the accurate way to read/download a file from the server (in Java)?

In my client-server application I have used a command (GET filename)to download a file into the client side. I have used the build in read() method to read the file. My teachers said it's not a very good practice to implement this read method. The reason is either it doesn't tell how exactly the file is reading from the server or it somehow is not able to download dynamic (large) file size. But at the moment I see that it's working fine. Since I am still in intermediate level in java, I need to learn the best way to do this job. How it could be improved in coding? That is I want to improve the while looping part in ClientSide.
I have pasted the relevent code:
ClientSide:
............
............
if (request.startsWith("GET")) {
File file = new File(request.substring(4));
is = socket.getInputStream();
fos = new FileOutputStream(file);
byte[] buffer = new byte[socket.getReceiveBufferSize()];
int bytesReceived = 0;
while ((bytesReceived = is.read(buffer)) >=0) {
//while ((bytesReceived = is.read(buffer))>=buffer) {
fos.write(buffer, 0, bytesReceived);
}
request = "";
fos.close();
is.close();
}
.................
.................
ServerSide:
.................
.................
else if (request.startsWith("GET")) {
System.out.println("");
String filename = request.substring(4);
File file = new File(System.getProperty("user.dir"));
File[] files = file.listFiles();
if (fileExists(files, filename)) {
file = new File(filename);
int fileSize = (int) file.length();
outputToClient.print("Status OK\r\n"
+ "Size " + fileSize + "KB" + "\r\n"
+ "\r\n"
+ "File " + filename + " Download was successfully\r\n");
outputToClient.flush();
// reading files
fis = new FileInputStream(file);
os = socket.getOutputStream();
byte[] buffer = new byte[2^7-1];
int bytesRead = 0;
while ((bytesRead = fis.read(buffer))!= -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
fis.close();
} else {
outputToClient.print("Status 400\r\n"
+ "File " + filename + " not found\r\n"
+ "\r\n");
outputToClient.flush();
}
}
outputToClient.flush();
}
.................
.................
You need to consume the rest of the HTTP response headers, by reading until you get a blank line, if you haven't already done that.
Apart from that, your code looks fine to me, except that I would use a much bigger buffer than 127, at least 8192, possibly a multiple of that.
Ask your teacher what (on earth) he's talking about.

unable to download the file using java

I've just implemented a jsp program to upload a file into my PC folder. The path of this folder is E:\UploadedFile. The file name i want to download is assad.xml (the one i have just uploaded). This is how i am trying to download it. Please check my code and correct me if i am wrong.
<%#page import="java.io.*,java.net.*"%>
<%
System.setProperty("http.proxyHost", "192.168.1.10");
System.setProperty("http.proxyPort", "8080");
try {
/*
* Get a connection to the URL and start up
* a buffered reader.
*/
long startTime = System.currentTimeMillis();
System.out.println("Connecting to URL...\n");
URL url = new URL("E://UploadedFiles/");
url.openConnection();
InputStream reader = url.openStream();
/*
* Setup a buffered file writer to write
* out what we read from the website.
*/
FileOutputStream writer = new FileOutputStream("E:/assad.xml");
byte[] buffer = new byte[153600]; // Buffer for 150K blocks at a time
int totalBytesRead = 0;
int bytesRead = 0;
System.out.println("Reading ZIP file 150KB blocks at a time.\n");
while ((bytesRead = reader.read(buffer)) > 0){
writer.write(buffer, 0, bytesRead);
buffer = new byte[153600];
totalBytesRead += bytesRead;
}
long endTime = System.currentTimeMillis();
System.out.println("Done. " + (new Integer(totalBytesRead).toString()) + " bytes
read (" +
(new Long(endTime - startTime).toString())+ " millseconds).\n");
writer.close();
reader.close();
}catch (MalformedURLException e){
e.printStackTrace();
}
catch (IOException e){
e.printStackTrace();
}
%>
The name of the folder in which i have just uploaded my file is UploadedFiles and its in E: drive. The name of the file i want to download is assad.xml. Its available inside this folder.
Probably you inverted the filename, like Renjith said. For a more consistent API take a look at: http://hc.apache.org/httpcomponents-core-ga/index.html

File download code downloads files larger than original

I'm downloading some .zip files though when I try to unzip them, I get "data error".. Now I went and saw the downloaded files, and they are bigger than the original. Could this be the reason of the error?
Code to download the file:
URL=intent.getStringExtra("DownloadService_URL");
FileName=intent.getStringExtra("DownloadService_FILENAME");
Path=intent.getStringExtra("DownloadService_PATH");
try{
URL url = new URL(URL);
URLConnection conexion = url.openConnection();
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
lenghtOfFile/=100;
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(Path+FileName);
byte data[] = new byte[1024];
long total = 0;
int count = 0;
while ((count = input.read(data)) != -1) {
output.write(data);
total += count;
notification.setLatestEventInfo(context, contentTitle, "Starting download " + FileName + " " + (total/lenghtOfFile), contentIntent);
mNotificationManager.notify(1, notification);
}
output.flush();
output.close();
input.close();
Code to UnZip:
try {
String zipFile = Path + FileName;
FileInputStream fin = new FileInputStream(zipFile);
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null) {
UnzipCounter++;
if (ze.isDirectory()) {
dirChecker(ze.getName());
} else {
FileOutputStream fout = new FileOutputStream(Path
+ ze.getName());
while ((Unziplength = zin.read(Unzipbuffer)) > 0) {
fout.write(Unzipbuffer, 0, Unziplength);
}
zin.closeEntry();
fout.close();
}
}
zin.close();
File f = new File(zipFile);
f.delete();
notification.setLatestEventInfo(context, contentTitle, "File successfully downloaded", contentIntent);
mNotificationManager.notify(1, notification);
} catch (Exception e) {
notification.setLatestEventInfo(context, contentTitle, "Problem in downloading file ", contentIntent);
mNotificationManager.notify(1, notification);
}
}
The unzip proccess starts but stops after extracting some files with that error.. I tried anothe r .zip file and I got CRC Failed error.. I tested both .zip files with winrar..
Original file size: 3.67mb .. Download file size: 3.93mb
You always write the complete byte array to the disk without checking how much data you read in.
Also from a performance point of view anything <1500byte (ie usual ethernet MTU) is a pretty bad idea - though I think Java buffers that somewhere below anyhow, but why risk anything.

Categories

Resources