Saving new File to any directory Groovy - spring

I keep getting file or directory does not exist. I am running within a Groovy script that creates a Spring Application Context. I am easily reading in a different file using the same type of pathing. However, the file I am reading is in the class path of Spring. This script might be run by any number of people with different file systems, so I can't hard code a path. I need a relative path.
This is above in the class but important info.
private static String saveFilesToLocation = "/retrieve/";
Here is the code.
CSVReader reader = new CSVReader(new InputStreamReader(balanceFile), SEPARATOR)
String[] nextLine
int counter = 0;
while ((nextLine = reader.readNext()) != null) {
counter++
if (nextLine != null && (nextLine[0] != 'FileLocation') ) {
counter++;
try {
//Remove 0, only if client number start with "0".
String fileLocation = nextLine[0];
byte[] fileBytes = documentFileService.getFile(fileLocation);
if (fileBytes != null) {
String fileName = fileLocation.substring(fileLocation.indexOf("/") + 1, fileLocation.length());
File file = new File(saveFilesToLocation+fileLocation);
file.withOutputStream {
it.write fileBytes
}
println "$counter) Wrote file ${fileLocation} to ${saveFilesToLocation+fileLocation}"
} else {
println "$counter) UNABLE TO RETRIEVE FILE: $fileLocation";
}
} catch (Exception e) {
e.printStackTrace()
}
}
}
The paths in Strings have what I would expect in them, no extra characters.
UPDATE:
Thanks loteq Your answer would work too, and has better grooviness than our final result that worked. Since it is a sort of one off, we don't have the time to change to the nicer version you have.
Here is the code that worked for us, it is identical to above except the saveFilesToLocation is set to a directory that already exists now. The one before didn't exist and we would have needed to call mkdir like loteq
suggested.
private static String saveFilesToLocation = "/tmp/retrieve/";
CSVReader reader = new CSVReader(new InputStreamReader(balanceFile), SEPARATOR)
String[] nextLine
int counter = 0;
while ((nextLine = reader.readNext()) != null) {
if (nextLine != null && (nextLine[0] != 'FileLocation') ) {
counter++;
try {
//Remove 0, only if client number start with "0".
String fileLocation = nextLine[0];
byte[] fileBytes = documentFileService.getFile(fileLocation);
if (fileBytes != null) {
String fileName = fileLocation.substring(fileLocation.indexOf("/") + 1, fileLocation.length());
File file = new File(saveFilesToLocation+fileName);
file.withOutputStream {
it.write fileBytes
}
println "$counter) Wrote file ${fileLocation} to ${saveFilesToLocation+fileLocation}"
} else {
println "$counter) UNABLE TO RETRIEVE FILE: $fileLocation";
}
} catch (Exception e) {
e.printStackTrace()
}
} else {
counter++;
}
}

There seems to be something add in your code, but I can't be certain that it's a bug.
You compute a fileName and don't really use it to create the target file. Instead you just append the original path to the prefix saveFilesToLocation:
String fileName = fileLocation.substring(fileLocation.indexOf("/") + 1, fileLocation.length());
File file = new File(saveFilesToLocation+fileLocation);
This seems strange.
Then, if fileLocation contains directories that need to be created, then you need to mkdirs() them, otherwise you will get an error.
I will give you 2 snippets, one atht assumes that youir code above is buggy, te other that does what you do in a safer way, in idiomatic groovy.
First lets work with actual File objects instead if Strings:
private static File saveFilesToLocationDir = saveFilesToLocation as File
Version that supposes a bug in the above code:
private static String saveFilesToLocation = "/retrieve/";
private static File saveFilesToLocationDir = saveFilesToLocation as File
CSVReader reader = new CSVReader(new InputStreamReader(balanceFile), SEPARATOR)
String[] nextLine
int counter = 0;
while ((nextLine = reader.readNext()) != null) {
counter++
if (nextLine != null && (nextLine[0] != 'FileLocation')) {
counter++;
try {
//Remove 0, only if client number start with "0".
String fileLocation = nextLine[0];
byte[] fileBytes = documentFileService.getFile(fileLocation);
if (fileBytes != null) {
int firstSlash = fileLocation.indexOf("/") + 1
String fileName = fileLocation[firstSlash..-1]
File destination = new File(saveFilesToLocationDir, fileName)
destination.parentFile.mkdirs()
destination.withOutputStream { it << fileBytes }
println "$counter) Wrote file ${fileLocation} to ${destination.absolutePath}"
} else {
println "$counter) UNABLE TO RETRIEVE FILE: $fileLocation";
}
} catch (Exception e) {
e.printStackTrace()
}
}
}
Version that does not use the created fileName (like you):
private static String saveFilesToLocation = "/retrieve/";
private static File saveFilesToLocationDir = saveFilesToLocation as File
CSVReader reader = new CSVReader(new InputStreamReader(balanceFile), SEPARATOR)
String[] nextLine
int counter = 0;
while ((nextLine = reader.readNext()) != null) {
counter++
if (nextLine != null && (nextLine[0] != 'FileLocation')) {
counter++;
try {
//Remove 0, only if client number start with "0".
String fileLocation = nextLine[0];
byte[] fileBytes = documentFileService.getFile(fileLocation);
if (fileBytes != null) {
int firstSlash = fileLocation.indexOf("/") + 1
String fileName = fileLocation[firstSlash..-1]
File destination = new File(saveFilesToLocationDir, fileLocation)
destination.parentFile.mkdirs()
destination.withOutputStream { it << fileBytes }
println "$counter) Wrote file ${fileLocation} to ${destination.absolutePath}"
} else {
println "$counter) UNABLE TO RETRIEVE FILE: $fileLocation";
}
} catch (Exception e) {
e.printStackTrace()
}
}
}

Related

I want to download files using SpringBoot

An attempt was made to implement file downloads through the SpringBoot MVC structure. There is no error, it says it has run normally, but the download does not proceed.
All information about the file is entered correctly, and also the path and name of the file are entered correctly.
I'd like to know why the download doesn't proceed even though there's no error.
#RestController
public class Controller {
#PostMapping("/fileDownload")
public void fileDownload(#RequestBody BoardFileDTO dto,HttpServletRequest request,HttpServletResponse response) throws UnsupportedEncodingException {
//File contains all stored paths, names, and extensions
Path fileNamePath = Paths.get(Directory + dto.getFile_save_name()).toAbsolutePath();
String filename = dto.getFile_save_name(); //The name of the saved file
String downname = dto.getFile_name(); //The name of the file to be saved
if (filename == null || "".equals(filename)) {
filename = downname;
}
try {
String browser = request.getHeader("User-Agent");
//File Encoding
if (browser.contains("MSIE") || browser.contains("Trident")
|| browser.contains("Chrome")) {
filename = URLEncoder.encode(filename, "UTF-8").replaceAll("\\+",
"%20");
} else {
filename = new String(filename.getBytes("UTF-8"), "ISO-8859-1");
}
} catch (UnsupportedEncodingException ex) {
System.out.println("UnsupportedEncodingException");
}
System.out.println(fileNamePath);
File file1 = new File(fileNamePath.toString());
if (!file1.exists()) {
return ;
}
// Specifying a File
response.setContentType("application/octer-stream");
response.setHeader("Content-Transfer-Encoding", "binary;");
response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
try {
OutputStream os = response.getOutputStream();
FileInputStream fis = new FileInputStream(fileNamePath.toString());
int ncount = 0;
byte[] bytes = new byte[512];
while ((ncount = fis.read(bytes)) != -1 ) {
os.write(bytes, 0, ncount);
}
fis.close();
os.close();
} catch (FileNotFoundException ex) {
System.out.println("FileNotFoundException");
} catch (IOException ex) {
System.out.println("IOException");
}
}
}
Your code is a bit convoluted imho. A couple of issues I see with your code
Using Path.toString to convert to a File, use the proper factory methods instead or use java.nio.Files to check the existence.
Your content-type is wrong application/octer-stream isn't a known content-type (you probably want application/octet-stream.
Copying from a Path or File is better done with either the StreamUtils from Spring or the java.nio.Files class (if you already have a Path use that).
#PostMapping("/fileDownload")
public void fileDownload(#RequestBody BoardFileDTO dto, HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
//File contains all stored paths, names, and extensions
Path fileNamePath = Paths.get(Directory, dto.getFile_save_name()).toAbsolutePath();
if (!Files.exists(fileNamePath)) {
return;
}
String filename = determineFilename(dto, request);
// Specifying a File
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
response.setHeader("Content-Transfer-Encoding", "binary;");
response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
try {
Files.copy(fileNamePath, response.getOutputStream());
} catch (IOException ex) {
System.out.println("IOException");
}
}
private static String determineFilename(BoardFileDTO dto, HttpServletRequest request) {
String filename = dto.getFile_save_name(); //The name of the saved file
if (filename == null || "".equals(filename)) {
filename = dto.getFile_name();
}
String browser = request.getHeader("User-Agent");
//File Encoding
if (browser.contains("MSIE") || browser.contains("Trident") || browser.contains("Chrome")) {
filename = URLEncoder.encode(filename, StandardCharsets.UTF_8).replaceAll("\\+", "%20");
} else {
filename = new String(filename.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
}
return filename;
}
It would write it something like that. As you have a path use the java.nio.Files to check for existence and copying. Use constants for mediatypes and charsets.
Your error handling is quite basic (I would say non-existing and at least not proper) as the processing just stops and returns an empty 200 to the client. No information what so ever.
I took the liberty to factor out the logic to determine the filename, which should make your code more readable.

lose of ZLIB inputstream fails when using try with resources

i have function for decompressing zips with multiple entries. Sometimes an exception is catched that states "Unexpected end of ZLIB Input stream". In my opinion it is not possible because i am using try with resrsources.
private boolean decompress(final Path blf) {
final String pathToZip = blf.getParent().toString();
final byte[] buffer = new byte[8192];
try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(blf.toFile()))) {
//We will unzip files in this folder
if (!Files.exists(Paths.get(pathToZip))) {
Files.createDirectory(Paths.get(pathToZip));
}
ZipEntry entry = zipInputStream.getNextEntry();
final Path pathToFile = Paths.get(pathToZip + "\\" + entry.getName());
//Faster procedure if the file already exists
if (Files.exists((pathToFile))) {
loggerAnalysis.log(new LogRecord(Level.INFO, "[Analysis]",
"File already exists, skipping" + pathToFile));
return true;
}
//Iterate over entries
while (entry != null) {
//If directory then create a new directory in uncompressed folder
if (entry.isDirectory()) {
loggerAnalysis.log(new LogRecord(Level.INFO, "[Analysis]",
"Creating Directory:" + pathToFile));
Files.createDirectories(pathToFile);
} else {
Files.createFile(pathToFile);
loggerAnalysis.log(new LogRecord(Level.INFO, "[Analysis]",
"File unzip: " + pathToFile.getFileName()));
try (FileOutputStream fileOutputStream = new FileOutputStream(pathToFile.toString())) {
int len;
while ((len = zipInputStream.read(buffer)) > 0) {
fileOutputStream.write(buffer, 0, len);
}
}
entry = zipInputStream.getNextEntry();
}
}
return true;
} catch (final IOException e) {
loggerAnalysis.log(new LogRecord(Level.ERROR, "[Analysis]", e.getMessage()));
return false;
}
}
best regards

Inserting values into database using JSP

<%
if (MultipartFormDataRequest.isMultipartFormData(request))
{
// Uses MultipartFormDataRequest to parse the HTTP request.
MultipartFormDataRequest mrequest = new MultipartFormDataRequest(request);
String todo = null;
if (mrequest != null) todo = mrequest.getParameter("todo");
if ( (todo != null) && (todo.equalsIgnoreCase("upload")) )
{
Hashtable files = mrequest.getFiles();
if ( (files != null) && (!files.isEmpty()) )
{
UploadFile file = (UploadFile) files.get("uploadfile");
if (file != null)
out.println("");
//out.println(report1);
String sever = mrequest.getParameter("sever");
String ease = mrequest.getParameter("ease");
String logo = "C:/uploads/"+file.getFileName(); // Uses the bean now to store specified by jsp:setProperty at the top.
String dana = mrequest.getParameter("danalysis");
String loc = mrequest.getParameter("loc");
String state = mrequest.getParameter("state");
String Sr = mrequest.getParameter("Sr");
String Doc_ID = mrequest.getParameter("doc");
String impact = mrequest.getParameter("impact");
String desc = mrequest.getParameter("desc");
String ref = mrequest.getParameter("ref");
String recom = mrequest.getParameter("recom");
try
{
String connectionURL = "jdbc:mysql://localhost:3306/mssg";
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection con=DriverManager.getConnection(connectionURL, "root","");
out.println("OK!\n");
PreparedStatement ps1=con.prepareStatement("insert into report values(?,?,?,?,?,?,?,?,?,?,?,?)");
ps1.setString(1,Doc_ID);
ps1.setString(2,Sr);
ps1.setString(3,sever);
ps1.setString(4,ease);
ps1.setString(5,state);
ps1.setString(6,loc);
ps1.setString(7,desc);
ps1.setString(8,impact);
ps1.setString(9,dana);
ps1.setString(10,logo);
ps1.setString(11,recom);
ps1.setString(12,ref);
int count=ps1.executeUpdate();
if(count > 0)
{
out.println("successfully inserted");
//response.sendRedirect("/index.jsp");
}
else
{
out.println("error occured");
}
}
catch (Exception e)
{
System.out.println("error in program:-"+e);
}
upBean.store(mrequest, "uploadfile");
}
else
{
out.println("<li>No uploaded files");
}
}
}
%>
In the above code I get all the values also file is uploading but not able to insert these values into database. I think I made a very small mistake, please tell me what is the problem in the above code. This code is working until connection but after prepare statement it's not working.
This is beacuse you have used try and catch block.
In the jsp page life cycle, the jsp page is translated in the servlets. so the code for the database connectivity will be automatically placed in the try catch block.
Just remove the try catch block.

how to calculate the file size in C#

In my asp mvc 3 application, I have an action which allows the user to download a given file.
Here is the code :
public FilePathResult DownloadFile(string fileName)
{
try
{
string uploadsDocumentPath = System.Configuration.ConfigurationManager.AppSettings["uploadsDocumentPath"].ToString();
string ext = Path.GetExtension(fileName).ToLower();
Microsoft.Win32.RegistryKey regKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext); // henter info fra windows registry
if (regKey != null && regKey.GetValue("Content Type") != null)
{
mimeType = regKey.GetValue("Content Type").ToString();
}
return File(uploadsDocumentPath + fileName, mimeType, fileName);
}
catch (Exception)
{
throw;
}
}
I want to be able to allow only files with size less than 150MB to be downloaded. But I can't find how to calculate this type of file's size.
Any ideas ?
I guess this should work:
FileInfo file = new FileInfo(uploadsDocumentPath + fileName);
if(file.Length > 157286400)
{
// Return error here.
}

BlackBerry - Downloaded images are corrupted on wifi with HttpConnection

In my app I need to download several images from a server. I use this code to get a byte array :
HttpConnection connection = null;
InputStream inputStream = null;
byte[] data = null;
try
{
//connection = (HttpConnection)Connector.open(url);
connection = (HttpConnection)Connector.open(url, Connector.READ_WRITE, true);
int responseCode = connection.getResponseCode();
if(responseCode == HttpConnection.HTTP_OK)
{
inputStream = connection.openInputStream();
data = IOUtilities.streamToBytes(inputStream);
inputStream.close();
}
connection.close();
return data;
}
catch(IOException e)
{
return null;
}
The url are formed with the suffix ";deviceSide=false;ConnectionType=MDS - public" (without spaces) and it is working perfectly well.
The problem is that with phones that do not have a sim card, we can't connect to the internet via the MDS server. So we changed to use the connection factory and let BB choose whatever he wants :
ConnectionFactory connFact = new ConnectionFactory();
ConnectionDescriptor connDesc;
connDesc = connFact.getConnection(url);
if (connDesc != null)
{
final HttpConnection httpConn;
httpConn = (HttpConnection)connDesc.getConnection();
try
{
httpConn.setRequestMethod(HttpConnection.GET);
final int iResponseCode = httpConn.getResponseCode();
if(iResponseCode == HttpConnection.HTTP_OK)
{
InputStream inputStream = null;
try{
inputStream = httpConn.openInputStream();
byte[] data = IOUtilities.streamToBytes(inputStream);
return data;
}
catch(Exception e)
{
e.printStackTrace();
return null;
}
finally{
try
{
inputStream.close();
} catch (IOException e)
{
e.printStackTrace();
return null;
}
}
}
}
catch (IOException e)
{
System.err.println("Caught IOException: " + e.getMessage());
}
}
return null;
The connection works because it select the good prefix (interface=wifi in our case), but this create another problem.
Some images are not well downloaded, some of them (not the sames at each try) are corrupted, but only when the phone use a wifi connection to get these images.
How can I avoid this problem ? What method to get a connection do I have to use ? Is it possible to check if the user have a sim card in orderto use MDS - public ?
Here is an example of a corrupted image :
error image http://nsa30.casimages.com/img/2012/06/28/120628033716123822.png
try this:
public static String buildURL(String url) {
String connParams = "";
if (WLANInfo.getWLANState() == WLANInfo.WLAN_STATE_CONNECTED) {
connParams = ";interface=wifi"; //Connected to a WiFi access point.
} else {
int coverageStatus = CoverageInfo.getCoverageStatus();
//
if ((coverageStatus & CoverageInfo.COVERAGE_BIS_B) == CoverageInfo.COVERAGE_BIS_B) {
connParams = ";deviceside=false;ConnectionType=mds-public";
} else if ((coverageStatus & CoverageInfo.COVERAGE_DIRECT) == CoverageInfo.COVERAGE_DIRECT) {
// Have network coverage and a WAP 2.0 service book record
ServiceRecord record = getWAP2ServiceRecord();
//
if (record != null) {
connParams = ";deviceside=true;ConnectionUID=" + record.getUid();
} else {
connParams = ";deviceside=true";
}
} else if ((coverageStatus & CoverageInfo.COVERAGE_MDS) == CoverageInfo.COVERAGE_MDS) {
// Have an MDS service book and network coverage
connParams = ";deviceside=false";
}
}
Log.d("connection param"+url+connParams);
//
return url+connParams;
}
private static ServiceRecord getWAP2ServiceRecord() {
String cid;
String uid;
ServiceBook sb = ServiceBook.getSB();
ServiceRecord[] records = sb.getRecords();
//
for (int i = records.length -1; i >= 0; i--) {
cid = records[i].getCid().toLowerCase();
uid = records[i].getUid().toLowerCase();
//
if (cid.indexOf("wptcp") != -1
&& records[i].getUid().toLowerCase().indexOf("wap2") !=-1
&& uid.indexOf("wifi") == -1
&& uid.indexOf("mms") == -1) {
return records[i];
}
}
//
return null;
}
What happens when you append interface=wifi? Can you run the network diagnostic tool attached to below kb article and run all tests with SIM removed
http://supportforums.blackberry.com/t5/Java-Development/What-Is-Network-API-alternative-for-legacy-OS/ta-p/614822
Please also note that when download large files over BES/MDS there are limits imposed by MDS. Please ensure you review the below kb article
http://supportforums.blackberry.com/t5/Java-Development/Download-large-files-using-the-BlackBerry-Mobile-Data-System/ta-p/44585
You can check to see if coverage is sufficient for BIS_B (MDS public) but that won't help you if you are trying to support SIM-less users. I wonder if the problem is in an incomparability between the connection on Wi-Fi and IOUtilities.streamToBytes(). Try coding as recommended in the API documents.

Resources