implemeting java application update with AppLoader.java - java

I hava a java swing application and would like to use auto update using AppLoader.java class that i found online at
**https://reportmill.wordpress.com/2014/12/04/automatically-update-your-javapackager-applications/
**
has anybody had any experience with this class. i can not seem to implement this class with my application and am getting errors:
java.io.FileNotFoundException: C:\Users\home\Documents\NetBeansProjects\test_update\build\classes (Access is denied)
and
java.lang.RuntimeException: Main Jar not found!

yep, the code seems not working. I did some modification for the code to make it work. please do as follows:
download the file through http://reportmill.com/snap1/SnapCode1.jar.pack.gz
copy this file to C:\Users\home\Documents\NetBeansProjects\test_update\build\classes
copy and paste the code below and give it a run
import java.io.;
import java.lang.reflect.Method;
import java.net.;
import java.text.;
import java.util.jar.;
import javax.swing.*;
import java.util.zip .GZIPInputStream;
/**
* This app
*/
public class AppLoader {
// Constants
static final String AppDirName = "SnapCode";
static final String JarName = "SnapCode1.jar";
static final String JarURL = "http://reportmill.com/snap1/SnapCode1.jar.pack.gz";
static final String MainClass = "snap.app.App";
/**
* Main method - reinvokes main1() on Swing thread in exception handler.
*/
public static void main(final String args[]) {
// Invoke real main with exception handler
try {
main1(args);
} catch (Throwable e) {
JOptionPane.showMessageDialog(null, e.toString());
e.printStackTrace();
}
}
/**
* Main method: - Gets main Jar file from default, if missing - Updates main
* Jar file from local update file, if previously loaded - Load main Jar
* into URLClassLoader, load main class and invoke main method - Check for
* update from remove site in background
*/
public static void main1(final String args[]) throws Exception {
// Make sure default jar is in place
try {
copyDefaultMainJar();
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e.toString());
e.printStackTrace();
}
// If Update Jar exists, copy it into place
File jar = getAppFile(JarName);
File updateJar = getAppFile(JarName + ".update");
if (updateJar.exists()) {
copyFile(updateJar, jar);
jar.setLastModified(updateJar.lastModified());
updateJar.delete();
}
// If jar doesn't exist complain bitterly
if (!jar.exists() || !jar.canRead())
throw new RuntimeException("Main Jar not found!");
// Check for updates in background thread
if (args.length == 0 || !args[0].equals("-snap"))
new Thread(new Runnable() {
public void run() {
checkForUpdatesSilent();
}
}).start();
// Create URLClassLoader for main jar file, get App class and invoke
// main
// URLClassLoader ucl = new URLClassLoader(
// new URL[] { jar.toURI().toURL() });
// Class cls = ucl.loadClass(MainClass); // ucl.close();
// Method meth = cls.getMethod("main", new Class[] { String[].class });
// meth.invoke(null, new Object[] { args });
// if (cls == Object.class)
// ((Closeable) ucl).close(); // Getting rid of warning message for ucl
}
/**
* Copies the default main jar into place for initial run.
*/
private static void copyDefaultMainJar() throws IOException, ParseException {
// Get main jar from app package and get location of working jar file
URL url = AppLoader.class.getProtectionDomain().getCodeSource()
.getLocation();
String path0 = url.getPath();
path0 = URLDecoder.decode(path0, "UTF-8");
path0 = path0 + "SnapCode1.jar.pack.gz" ;
File jar0 = getAppFile(JarName);
File jar1 = new File(path0);
// If app package main jar is newer, copy it into place and set time
if (jar0.exists() && jar0.lastModified() >= jar1.lastModified())
return;
copyFile(jar1, jar0);
}
/**
* Check for updates.
*/
private static void checkForUpdatesSilent() {
try {
checkForUpdates();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Check for updates.
*/
private static void checkForUpdates() throws IOException,
MalformedURLException {
// Get URL connection and lastModified time
File jarFile = getAppFile(JarName);
URL url = new URL(JarURL);
URLConnection connection = url.openConnection();
long mod0 = jarFile.lastModified(), mod1 = connection.getLastModified();
if (mod0 >= mod1) {
System.out.println("No update available at " + JarURL + '(' + mod0
+ '>' + mod1 + ')');
return;
}
// Get update file and write to JarName.update
System.out.println("Loading update from " + JarURL);
byte bytes[] = getBytes(connection);
System.out.println("Update loaded");
File updatePacked = getAppFile(JarName + ".pack.gz"), updateFile = getAppFile(JarName
+ ".update");
writeBytes(updatePacked, bytes);
System.out.println("Update saved: " + updatePacked);
unpack(updatePacked, updateFile);
System.out.println("Update unpacked: " + updateFile);
updateFile.setLastModified(mod1);
updatePacked.delete();
// Let the user know
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JOptionPane
.showMessageDialog(null,
"A new update is available. Restart application to apply");
}
});
}
/**
* Returns the Main jar file.
*/
private static File getAppFile(String aName) {
return new File(getAppDir(), aName);
}
/**
* Returns the Main jar file.
*/
private static File getAppDir() {
return getAppDataDir(AppDirName, true);
}
/**
*
* Utility Methods for AppLoader.
*
*/
/**
* Copies a file from one location to another.
*/
public static File copyFile(File aSource, File aDest) throws IOException {
// Get input stream, output file and output stream
FileInputStream fis = new FileInputStream(aSource);
File out = aDest.isDirectory() ? new File(aDest, aSource.getName())
: aDest;
FileOutputStream fos = new FileOutputStream(out);
// Iterate over read/write until all bytes written
byte[] buf = new byte[8192];
for (int i = fis.read(buf); i != -1; i = fis.read(buf))
fos.write(buf, 0, i);
// Close in/out streams and return out file
fis.close();
fos.close();
return out;
}
/**
* Writes the given bytes (within the specified range) to the given file.
*/
public static void writeBytes(File aFile, byte theBytes[])
throws IOException {
if (theBytes == null) {
aFile.delete();
return;
}
FileOutputStream fileStream = new FileOutputStream(aFile);
fileStream.write(theBytes);
fileStream.close();
}
/**
* Unpacks the given file into the destination file.
*/
public static File unpack(File aFile, File aDestFile) throws IOException {
// Get dest file - if already unpacked, return
File destFile = getUnpackDestination(aFile, aDestFile);
if (destFile.exists() && destFile.lastModified() > aFile.lastModified())
return destFile;
// Create streams: FileInputStream -> GZIPInputStream -> JarOutputStream
// -> FileOutputStream
FileInputStream fileInput = new FileInputStream(aFile);
GZIPInputStream gzipInput = new GZIPInputStream(fileInput);
FileOutputStream fileOut = new FileOutputStream(destFile);
JarOutputStream jarOut = new JarOutputStream(fileOut);
// Unpack file
Pack200.newUnpacker().unpack(gzipInput, jarOut);
// Close streams
fileInput.close();
gzipInput.close();
jarOut.close();
fileOut.close();
// Return destination file
return destFile;
}
/**
* Returns the file that given packed file would be saved to using the
* unpack method.
*/
public static File getUnpackDestination(File aFile, File aDestFile) {
// Get dest file - if null, create from packed file minus .pack.gz
File destFile = aDestFile;
if (destFile == null)
destFile = new File(aFile.getPath().replace(".pack.gz", ""));
// If dest file is directory, change to file inside with packed file
// minus .pack.gz
else if (destFile.isDirectory())
destFile = new File(destFile, aFile.getName().replace(".pack.gz",
""));
// Return destination file
return destFile;
}
/**
* Returns the AppData or Application Support directory file.
*/
public static File getAppDataDir(String aName, boolean doCreate) {
// Get user home + AppDataDir (platform specific) + name (if provided)
String dir = System.getProperty("user.home");
if (isWindows)
dir += File.separator + "AppData" + File.separator + "Local";
else if (isMac)
dir += File.separator + "Library" + File.separator
+ "Application Support";
if (aName != null)
dir += File.separator + aName;
// Create file, actual directory (if requested) and return
File dfile = new File(dir);
if (doCreate && aName != null)
dfile.mkdirs();
return dfile;
}
/**
* Returns bytes for connection.
*/
public static byte[] getBytes(URLConnection aConnection) throws IOException {
InputStream stream = aConnection.getInputStream(); // Get stream for
// connection
byte bytes[] = getBytes(stream); // Get bytes for stream
stream.close(); // Close stream
return bytes; // Return bytes
}
/**
* Returns bytes for an input stream.
*/
public static byte[] getBytes(InputStream aStream) throws IOException {
ByteArrayOutputStream bs = new ByteArrayOutputStream();
byte chunk[] = new byte[8192];
for (int len = aStream.read(chunk, 0, 8192); len > 0; len = aStream
.read(chunk, 0, 8192))
bs.write(chunk, 0, len);
return bs.toByteArray();
}
// Whether Windows/Mac
static boolean isWindows = (System.getProperty("os.name")
.indexOf("Windows") >= 0);
static boolean isMac = (System.getProperty("os.name").indexOf("Mac OS X") >= 0);
}
Your problem is that in your copyFile method FileInputStream takes a wrong File object

Related

How to copy resources folder out of jar into program files

I have spent hours and hours searching for the answer and I just can't figure it out, I am trying to copy my resources folder which contains all the images and data files for my game I am working on out of the running jar and into
E:/Program Files/mtd/ It works fine when I run it out of eclipse, but when I export the jar and try it, I get NoSuchFileException
`JAR
Installing...
file:///C:/Users/Cam/Desktop/mtd.jar/resources to file:///E:/Program%20Files/mtd
/resources
java.nio.file.NoSuchFileException: C:\Users\Cam\Desktop\mtd.jar\resources
at sun.nio.fs.WindowsException.translateToIOException(Unknown Source)
at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
at sun.nio.fs.WindowsFileAttributeViews$Basic.readAttributes(Unknown Sou
rce)
at sun.nio.fs.WindowsFileAttributeViews$Basic.readAttributes(Unknown Sou
rce)
at sun.nio.fs.WindowsFileSystemProvider.readAttributes(Unknown Source)
at java.nio.file.Files.readAttributes(Unknown Source)
at java.nio.file.FileTreeWalker.walk(Unknown Source)
at java.nio.file.FileTreeWalker.walk(Unknown Source)
at java.nio.file.Files.walkFileTree(Unknown Source)
at java.nio.file.Files.walkFileTree(Unknown Source)
at me.Zacx.mtd.main.Game.<init>(Game.java:94)
at me.Zacx.mtd.main.Game.main(Game.java:301)`
This is the code I am using:
if (!pfFolder.exists()) {
pfFolder.mkdir();
try {
URL url = getClass().getResource("/resources/");
URI uri = null;
if (url.getProtocol().equals("jar")) {
System.out.println("JAR");
JarURLConnection connect = (JarURLConnection) url.openConnection();
uri = new URI(connect.getJarFileURL().toURI().toString() + "/resources/");
} else if (url.getProtocol().equals("file")) {
System.out.println("FILE");
uri = url.toURI();
}
final Path src = Paths.get(uri);
final Path tar = Paths.get(System.getenv("ProgramFiles") + "/mtd/resources/");
System.out.println("Installing...");
System.out.println(src.toUri() + " to " + tar.toUri());
Files.walkFileTree(src, new SimpleFileVisitor<Path>() {
public FileVisitResult visitFile( Path file, BasicFileAttributes attrs ) throws IOException {
return copy(file);
}
public FileVisitResult preVisitDirectory( Path dir, BasicFileAttributes attrs ) throws IOException {
return copy(dir);
}
private FileVisitResult copy( Path fileOrDir ) throws IOException {
System.out.println("Copying " + fileOrDir.toUri() + " to " + tar.resolve( src.relativize( fileOrDir ) ).toUri());
Files.copy( fileOrDir, tar.resolve( src.relativize( fileOrDir ) ) );
return FileVisitResult.CONTINUE;
}
});
System.out.println("Done!");
} catch (IOException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
This was harder that I thought, but here is how to do it.
here is my copy method Reference https://examples.javacodegeeks.com/core-java/io/file/4-ways-to-copy-file-in-java/
public void copyFile(String inputPath, String outputPath ) throws IOException
{
InputStream inputStream = null;
OutputStream outputStream = null;
try {
inputStream = getClass().getResourceAsStream(inputPath);
outputStream = new FileOutputStream(outputPath);
byte[] buf = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buf)) > 0) {
outputStream.write(buf, 0, bytesRead);
}
}
finally {
inputStream.close();
outputStream.close();
}
Please note the structure of the project of the Jar file in this image Project structure
Now I need to read the Jar file. This is a varition on this solution How can I get a resource "Folder" from inside my jar File? . Both of these methods work together to product the result. I have tested this and it works.
public class Main {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
final String pathPartOne = "test/com";
final String pathPartTwo = "/MyResources";
String pathName = "C:\\Users\\Jonathan\\Desktop\\test.jar";
JarTest test = new JarTest();
final File jarFile = new File(pathName);
if(jarFile.isFile()) { // Run with JAR file
final JarFile jar = new JarFile(jarFile);
final Enumeration<JarEntry> entries = jar.entries(); //gives ALL entries in jar
while(entries.hasMoreElements()) {
final String name = entries.nextElement().getName();
if (name.startsWith(pathPartOne+pathPartTwo + "/")) { //filter according to the path
if(name.contains("."))//has extension
{
String relavtivePath = name.substring(pathPartOne.length()+1);
String fileName = name.substring(name.lastIndexOf('/')+1);
System.out.println(relavtivePath);
System.out.println(fileName);
test.copyFile(relavtivePath, "C:\\Users\\Jonathan\\Desktop\\" + fileName);
}
}
}
jar.close();
}
}
}
Hope that helps.
The problem here is different File Systems. C:/Users/Cam/Desktop/mtd.jar is a File in the WindowsFileSystem. Since it is a file, and not a directory, you cannot access a subdirectory inside the file; C:/Users/Cam/Desktop/mtd.jar/resources is only a valid Path if mtd.jar is actually a directory instead of a file.
In order to access something on a different file system, you must use the path from the root of that file system. For example, if you have a file in D:\dir1\dir2\file, you cannot reach it using a path that begins with C:\ (symbolic links not withstanding); you must use a path that starts at the root of that file system D:\.
A jar file is just a file. It can be located anywhere within a file system, and can be moved, copied or deleted like any regular file. However, it contains within itself its own file system. There is no windows path that can be used to reference any file inside the jar's file system, just like no path starting at C:\ can reference any file within the D:\ file system.
In order to access the contents of a jar, you must open the jar as a ZipFileSystem.
// Autoclose the file system at end of try { ... } block.
try(FileSystem zip_fs = FileSystems.newFileSystem(pathToZipFile, null)) {
}
Once you have zip_fs, you can use zip_fs.getPath("/path/in/zip"); to get a Path to a file within it. This Path object will actually be a ZipFileSystemProvider path object, not a WindowsFileSystemProvider path object, but otherwise it is a Path object that can be opened, read from, etc., at least until the ZipFileSystem is closed. The biggest differences are that path.getFileSystem() will return the ZipFileSystem, and that resolve() and relativize() cannot use path objects where getFileSystem() returns different file systems.
When your project ran from Eclipse, all the resources were in the WindowsFileSystem, so walking the file system tree and copying the resources was straight forward. When your project ran from a jar, the resources were not in the default file system.
Here is a Java class that will copy resources to an installation directory. It will work in Eclipse (with all the resources as individual files), as well as when the application is packaged into a jar.
public class Installer extends SimpleFileVisitor<Path> {
public static void installResources(Path dst, Class<?> cls, String root) throws URISyntaxException, IOException {
URL location = cls.getProtectionDomain().getCodeSource().getLocation();
if (location.getProtocol().equals("file")) {
Path path = Paths.get(location.toURI());
if (location.getPath().endsWith(".jar")) {
try (FileSystem fs = FileSystems.newFileSystem(path, null)) {
installResources(dst, fs.getPath("/" + root));
}
} else {
installResources(dst, path.resolve(root));
}
} else {
throw new IllegalArgumentException("Not supported: " + location);
}
}
private static void installResources(Path dst, Path src) throws IOException {
Files.walkFileTree(src, new Installer(dst, src));
}
private final Path target, source;
private Installer(Path dst, Path src) {
target = dst;
source = src;
}
private Path resolve(Path path) {
return target.resolve(source.relativize(path).toString());
}
#Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
Path dst = resolve(dir);
Files.createDirectories(dst);
return super.preVisitDirectory(dir, attrs);
}
#Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Path dst = resolve(file);
Files.copy(Files.newInputStream(file), dst, StandardCopyOption.REPLACE_EXISTING);
return super.visitFile(file, attrs);
}
}
Called as:
Path dst = Paths.get("C:\\Program Files\\mtd");
Installer.installResources(dst, Game.class, "resources");
I FINALLY FOUND THE ANSWER
I don't want to type out a big, long explanation but for anyone looking for the solution, here it is
`
//on startup
installDir("");
for (int i = 0; i < toInstall.size(); i++) {
File f = toInstall.get(i);
String deepPath = f.getPath().replace(f.getPath().substring(0, f.getPath().lastIndexOf("resources") + "resources".length() + 1), "");
System.out.println(deepPath);
System.out.println("INSTALLING: " + deepPath);
installDir(deepPath);
System.out.println("INDEX: " + i);
}
public void installDir(String path) {
System.out.println(path);
final URL url = getClass().getResource("/resources/" + path);
if (url != null) {
try {
final File apps = new File(url.toURI());
for (File app : apps.listFiles()) {
System.out.println(app);
System.out.println("copying..." + app.getPath() + " to " + pfFolder.getPath());
String deepPath = app.getPath().replace(app.getPath().substring(0, app.getPath().lastIndexOf("resources") + "resources".length() + 1), "");
System.out.println(deepPath);
try {
File f = new File(resources.getPath() + "/" + deepPath);
if (getExtention(app) != null) {
FileOutputStream resourceOS = new FileOutputStream(f);
byte[] byteArray = new byte[1024];
int i;
InputStream classIS = getClass().getClassLoader().getResourceAsStream("resources/" + deepPath);
//While the input stream has bytes
while ((i = classIS.read(byteArray)) > 0)
{
//Write the bytes to the output stream
resourceOS.write(byteArray, 0, i);
}
//Close streams to prevent errors
classIS.close();
resourceOS.close();
} else {
System.out.println("new dir: " + f.getPath() + " (" + toInstall.size() + ")");
f.mkdir();
toInstall.add(f);
System.out.println(toInstall.size());
}
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (URISyntaxException ex) {
// never happens
}
}
}`

Copying images from JAR file to a folder outside

My file structure:
This is how it looks using netbeans project:
-src
-images
-*.jpg
-stock
-*.java
-images (exact copy of -images)
and here is my jar
-jar
-images
-*.jpg
-stock
-*.java
-images (folder is created but files don't get copied)
My files imagesCopy is the one that I create and ImagesOrg is the one inside .jar / src
File imagesCopy = new File("images");
File imagesOrg = new File(URLDecoder.decode(getClass().getResource("/images").getPath()));
if (!imagesCopy.exists()) {
imagesCopy.mkdir();
for(final File child : imagesOrg.listFiles()) {
try{
Files.copy(child.toPath(), Paths.get(imagesCopy.getAbsolutePath()+"/"+child.getName()), REPLACE_EXISTING);
}catch(Exception e){
System.out.println(e);
}
}
}
The problem definitely lies with:
File imagesOrg = new File(URLDecoder.decode(getClass().getResource("/images").getPath()));
When compiling it it gives me, which is the proper directory
D:\Code\build\classes\images
which is the right directory, but when using this program from jar file I get:
D:\Code\dist\file:\D:\Code\dist\egz.jar!\images
and I assume that it should just be:
D:\Code\dist\egz.jar!\images
without that first part
Probably the simplest way to do it is like this:
public static void main(String[] args) throws URISyntaxException, IOException {
File imagesCopy = new File("C:\\Users\\<YOURNAMEHERE>\\images");
URI uri = ImageCopy.class.getResource("/images").toURI();
if (!uri.toString().startsWith("file:")) {
Map<String, String> env = new HashMap<>();
env.put("create", "true");
FileSystems.newFileSystem(uri, env);
}
Path imagesOrg = Paths.get(uri);
System.out.println(imagesOrg);
if (!imagesCopy.exists()) {
imagesCopy.mkdir();
try(DirectoryStream<Path> paths = Files.newDirectoryStream(imagesOrg)) {
for (final Path child : paths) {
System.out.println(child);
try {
String targetPath = imagesCopy.getAbsolutePath() + File.separator + child.getFileName().toString();
System.out.println(targetPath);
Files.copy(child, Paths.get(targetPath), StandardCopyOption.REPLACE_EXISTING);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
It's not super-pretty, but it works. Might need to fiddle with the code if you have nested directories.
Note that you must create the FileSystem before accessing it (as per the Oracle Docs). I don't know why this is required, but there we go.
I've tested this and it will copy files from inside your JAR to wherever you would like.
Here is a simple code to do it. You can adapt as you need.
package br.com.jjcampos.main;
//imports here
public class CopyImage {
private static ClassLoader loader = CopyImage.class.getClassLoader();
public static void main(String[] args) throws IOException {
InputStream stream = loader.getResourceAsStream("br/com/jjcampos/images/test.jpg");
OutputStream outputStream =
new FileOutputStream(new File("c:/temp/newImage.jpg"));
int read = 0;
byte[] bytes = new byte[1024];
while ((read = stream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
outputStream.close();
}
}
Understand that you can't copy a source from a stream (your jar) as a list of files. Unless you want to unpack it first. My suggestion is you to add a txt file with the list of your images then you read this file and use suggested code to copy each one.
Something like this:
public class CopyImage {
private static ClassLoader loader = CopyImage.class.getClassLoader();
public static void main(String[] args) throws IOException {
copyImages("c:/temp/");
}
public static void copyImages(String pathDestiny) throws IOException{
InputStream listOfFiles = loader
.getResourceAsStream("br/com/jjcampos/images/listImages.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(listOfFiles));
String line;
while ( (line = reader.readLine())!=null ){
InputStream stream = loader.getResourceAsStream("br/com/jjcampos/images/"
+ line);
OutputStream outputStream =
new FileOutputStream(new File(pathDestiny + line));
int read = 0;
byte[] bytes = new byte[1024];
while ((read = stream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
outputStream.close();
}
}
}
And your listImages.txt with
test.jpg
And you should decide if you put the full path on the text file or not to use in your code.

Hashing a .raw file shows NullPointerException in Java

I want to hash a file in Java by calling a file that ends with .raw. These are the codes I used:
FileSearch.java
public class FileSearch
{
private static final File file = null;
public static File findfile(File file) throws IOException
{
String drive = (new DetectDrive()).USBDetect();
Path start = FileSystems.getDefault().getPath(drive);
Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
#Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
{
if (file.toString().endsWith(".raw"))
{
System.out.println(file);
}
return FileVisitResult.CONTINUE;
}
});
return file;
}
public static void main(String[] args) throws Exception
{
Hash hasher = new Hash();
FileSearch.findfile(file);
try
{
if (file.toString().endsWith("raw"))
{
hasher.hash(file);
}
} catch (IOException e)
{
e.printStackTrace();
}
}
}
Hash.java
public class Hash
{
public void hash(File file) throws Exception
{
MessageDigest md = MessageDigest.getInstance("MD5");
FileInputStream fis = new FileInputStream(file);
byte[] dataBytes = new byte[1024];
int nread = 0;
while ((nread = fis.read(dataBytes)) != -1)
{
md.update(dataBytes, 0, nread);
};
byte[] mdbytes = md.digest();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < mdbytes.length; i++)
{
sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
}
System.out.println("Digest(in hex format):: " + sb.toString());
}
}
The first code is used to find the file and perform hash by running the main method and the second code is the method for hashing the file (by MD5). However, when I run the it gives an ouput:
"name of raw file"
Exception in thread "main" java.lang.NullPointerException at FileSearch.main(FileSearch.java:33)
line 33 is the if (file.toString().endsWith("raw")) portion. Anyone knows how I can fix this?
You never initalize file with anything (Well, you initalize it with null)
private static final File file = null;
So when you call
if (file.toString().endsWith("raw"))
file can only be null.
What you probably want is just
file = FileSearch.findfile(file);
See:
What is a NullPointerException, and how do I fix it?

Loading and saving a data file in android

I am doing a simple application that loads and saves files in java. I am trying to port it over to Android and am having trouble getting it to see the file.
The file path I am currently using is
private static final String SAVE_FILE_PATH = "data/save";
Here is the function that loads the data from the file:
public void loadData() throws FileNotFoundException {
File file = new File(SAVE_FILE_PATH);
Scanner scanner;
if (file.exists()) {
scanner = new Scanner(new FileInputStream(file));
try {
while (scanner.hasNextLine()) {
allPlayers.add(new Player(scanner.nextLine()));
}
} finally {
scanner.close();
}
}
else {
System.out.println("No file found");
}
} finally {
scanner.close();
}
}
}
While getExternalStorageDirectory() gets you the path to the SD card, consider using Activity.getExternalFilesDir() which will return (and create if necessary) a directory that's nominally private to your application. It also has the advantage that it will be auto-deleted for you if the application is uninstalled. This is new in API 8, so you might not want to use it if you're supporting older devices.
Otherwise, you'll have to follow ρяσѕρєя K's advice. Don't forget to create the storage directory you want to use. My code typically looks like this:
/**
* Utility: Return the storage directory. Create it if necessary.
*/
public static File dataDir()
{
File sdcard = Environment.getExternalStorageDirectory();
if( sdcard == null || !sdcard.isDirectory() ) {
// TODO: warning popup
Log.w(TAG, "Storage card not found " + sdcard);
return null;
}
File datadir = new File(sdcard, "MyApplication");
if( !confirmDir(datadir) ) {
// TODO: warning popup
Log.w(TAG, "Unable to create " + datadir);
return null;
}
return datadir;
}
/**
* Create dir if necessary, return true on success
*/
public static final boolean confirmDir(File dir) {
if( dir.isDirectory() ) return true;
if( dir.exists() ) return false;
return dir.mkdirs();
}
Now use this to specify your save file:
File file = new File(dataDir(), "save");
Scanner scanner;
if (file.exists()) {
// etc.
}

Error with GwtUpload Servlet

I'm trying to implement the Basic example for the GwtUpload library, as found here.
In my server code, I get the following error:
Exception java.lang.ClassCastException: org.apache.commons.fileupload.disk.DiskFileItem cannot be cast to org.apache.commons.fileupload.FileItem
I can't figure out why this is happening. DiskFileItem is a subclass of FileItem and should work. I've stepped through in the debugger and confirmed that the two classes are what they appear to be, yet the assignment fails.
Even more strangely, when I attempt to call the FileItem methods in the watch window, I have no problems, but if I attempt to access them in the code, I get the error.
Here is my Servlet code:
public class GwtUploadServlet extends UploadAction
{
private static final long serialVersionUID = 1L;
/**
* Maintain a list with received files and their content types.
*/
Hashtable<String, String> receivedContentTypes = new Hashtable<String, String>();
/**
* Maintain a list with received files.
*/
Hashtable<String, File> receivedFiles = new Hashtable<String, File>();
/**
* Override executeAction to save the received files in a custom place and
* delete this items from session.
*/
#Override
public String executeAction(HttpServletRequest request,
List<FileItem> sessionFiles) throws UploadActionException
{
String response = "";
int cont = 0;
for ( int i = 0 ; i < sessionFiles.size(); i++ )
{
if (false == sessionFiles.get(i).isFormField())
{
cont++;
try
{
// / Create a temporary file placed in the default system
// temp folder
File file = File.createTempFile("upload-", ".bin");
sessionFiles.get(i).write(file);
// / Save a list with the received files
receivedFiles.put(sessionFiles.get(i).getFieldName(), file);
receivedContentTypes.put(sessionFiles.get(i).getFieldName(),
sessionFiles.get(i).getContentType());
// / Send a customized message to the client.
response += "File saved as " + file.getAbsolutePath();
}
catch (Exception e)
{
throw new UploadActionException(e);
}
}
}
// / Remove files from session because we have a copy of them
removeSessionFileItems(request);
// / Send your customized message to the client.
return response;
}
/**
* Get the content of an uploaded file.
*/
#Override
public void getUploadedFile(HttpServletRequest request,
HttpServletResponse response) throws IOException
{
String fieldName = request.getParameter(PARAM_SHOW);
File f = receivedFiles.get(fieldName);
if (f != null)
{
response.setContentType(receivedContentTypes.get(fieldName));
FileInputStream is = new FileInputStream(f);
copyFromInputStreamToOutputStream(is, response.getOutputStream());
}
else
{
renderXmlResponse(request, response, ERROR_ITEM_NOT_FOUND);
}
}
/**
* Remove a file when the user sends a delete request.
*/
#Override
public void removeItem(HttpServletRequest request, String fieldName)
throws UploadActionException
{
File file = receivedFiles.get(fieldName);
receivedFiles.remove(fieldName);
receivedContentTypes.remove(fieldName);
if (file != null)
{
file.delete();
}
}
}
Make sure you don't have multiple versions of commons-fileupload on the classpath.

Categories