Java 1.8 FileOutputStream Creating a Directory - java

I seem to be having a problem with the 1.8 JDK this project was built using the 1.7 JDK but i'm having a problem i can't quite understand.
So i have a ConfigReader Class.
public class ConfigReader {
private static ConfigReader _inst;
public static ConfigReader GetInstance(){
if(_inst == null){
_inst = new ConfigReader();
}
return _inst;
}
private String basePath = "Config/";
public <T extends Serializable> void Write(T in, String filename)
{
String path = basePath+filename+".bin";
try
{
File f = new File(path);
f.mkdirs();
FileOutputStream fileOut =
new FileOutputStream(path);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(in);
out.close();
fileOut.close();
System.out.println("Saved config file '"+path+"'");
}catch(IOException i)
{
System.out.println("Failed to create config file '"+path+"'");
}
}
public boolean ConfigExists(String filename)
{
String path = basePath+filename+".bin";
File finfo = new File(path);
return finfo.exists();
}
public <T extends Serializable> T Read(T readin, String filename)
{
String path = basePath+filename+".bin";
try
{
FileInputStream fileIn = new FileInputStream(path);
ObjectInputStream in = new ObjectInputStream(fileIn);
readin = (T) in.readObject();
in.close();
fileIn.close();
return readin;
}catch(IOException i)
{
System.out.println("Failed to read '"+path+"'");
return null;
}catch(ClassNotFoundException c)
{
System.out.println("Failed to unserialize '"+path+"'");
c.printStackTrace();
return null;
}
}
}
But for some reason when the Write Method is called it's creating directories E.G
Reading a file:
boolean cfgExists = ConfigReader.GetInstance().ConfigExists("Global.cfg");
if(_inst == null && !cfgExists){
_inst = new Global();
}else if(cfgExists){
_inst = ConfigReader.GetInstance().Read(_inst, "Global.cfg");
}
Writing a file:
ConfigReader.GetInstance().Write(this, "Global.cfg");
I end up with the empty directory "Global.cfg.bin" not a file. i'm slightly confused why this is now happening...

Your call to f.mkdirs() is creating the directory with a path that is identical to your intended file path. Call f.getParentFile().mkdirs() instead and that should clear it up.

Related

Java - Pass a variable from user input to another java file

I am new to Java and I have a project to do, so I have a java file and the user have to choose from a listing of files in a directory. The input from user is saved in a variable (fileName). I want to use that variable in another java file for doing some other work. I searched online but didn't find any solution that works for me. Probably I've done something wrong.
code of the first file:
public class Director {
private static void copyFileUsingStream(File source, File dest) throws IOException {
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream(source);
os = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
} finally {
is.close();
os.close();
}
}
public static void main(String[] args) throws IOException {
// Creates an array in which we will store the names of files and directories
String[] pathnames;
// Creates a new File instance by converting the given pathname string
// into an abstract pathname
File f = new File("C:\\Users\\miltos\\Desktop\\polimesa\\available_videos");
// Populates the array with names of files and directories
pathnames = f.list();
System.out.println("Files in the directory:");
// For each pathname in the pathnames array
for (String pathname : pathnames) {
// Print the names of files and directories
System.out.println(pathname);
}
Scanner myObj = new Scanner(System.in); // Create a Scanner object
System.out.println("Enter file name");
String fileName = myObj.nextLine();
File source = new File("C:\\Users\\miltos\\Desktop\\polimesa\\available_videos\\" + fileName);
File dest = new File("C:\\Users\\miltos\\Desktop\\polimesa\\raw_videos\\" + fileName);
copyFileUsingStream(source, dest);
}
}
code of the second file that i want to use the input:
public class TestFFMpeg {
static Logger log = LogManager.getLogger(TestFFMpeg.class);
public static void main(String[] args) {
FFmpeg ffmpeg = null;
FFprobe ffprobe = null;
try {
log.debug("Initialising FFMpegClient");
ffmpeg = new FFmpeg("C:\\Users\\miltos\\ffmpeg\\bin\\ffmpeg.exe");
ffprobe = new FFprobe("C:\\Users\\miltos\\ffmpeg\\bin\\ffprobe.exe");
} catch (IOException e) {
e.printStackTrace();
}
log.debug("Creating the transcoding");
FFmpegBuilder builder = new FFmpegBuilder()
.setInput("C:\\Users\\miltos\\Desktop\\polimesa\\raw_videos\\" + filename) //updated
.addOutput("C:\\Users\\miltos\\Desktop\\polimesa\\videos\\" + filename) //updated
.setVideoBitRate(200000)
.done();
log.debug("Creating the executor");
FFmpegExecutor executor = new FFmpegExecutor(ffmpeg, ffprobe);
log.debug("Starting the transcoding");
// Run a one-pass encode
executor.createJob(builder).run();
log.debug("Transcoding finished");
}
}
I created a variable names filename in class second also, which you will pass from the class one , while creating an object of class second like
TestFFMpeg obj = new TestFFMpeg();
obj.methodInSecondClass(filename);
Second Class :
public class TestFFMpeg {
static Logger log = LogManager.getLogger(TestFFMpeg.class);
public void methodInSecondClass(String filename){
FFmpeg ffmpeg = null;
FFprobe ffprobe = null;
try {
log.debug("Initialising FFMpegClient");
ffmpeg = new FFmpeg("C:\\Users\\miltos\\ffmpeg\\bin\\ffmpeg.exe");
ffprobe = new FFprobe("C:\\Users\\miltos\\ffmpeg\\bin\\ffprobe.exe");
} catch (IOException e) {
e.printStackTrace();
}
log.debug("Creating the transcoding");
FFmpegBuilder builder = new FFmpegBuilder()
.setInput("C:\\Users\\miltos\\Desktop\\polimesa\\available_videos\\"+filename) //this is where i want the same variable
.addOutput("C:\\Users\\miltos\\Desktop\\polimesa\\videos\\"+filename) //this is where i want the same variable
.setVideoBitRate(200000)
.done();
log.debug("Creating the executor");
FFmpegExecutor executor = new FFmpegExecutor(ffmpeg, ffprobe);
log.debug("Starting the transcoding");
// Run a one-pass encode
executor.createJob(builder).run();
log.debug("Transcoding finished");
}
}

Objects showing null when importing and deserializing

Currently passing a HashMap<byte[],byte[]> where both values are there prior serialization within the TMap, visible in the FILEPATH, whilst the program is running, shows the keys and values. I've tried changing it to a non static field but alas, when loading the TMap on the constructor of the object the Map holds null. Here's the code used to save and load the TMap. Has anyone got any suggestions?
public void loadTMap() {
HashMap<byte[], byte[]> TMap = new HashMap<>();
File f = new File("FILEPATH);
if(f.exists()) {
try {
FileInputStream fileIn = new FileInputStream("FILEPATH");
ObjectInputStream in = new ObjectInputStream(fileIn);
TMap = (HashMap<byte[], byte[]>) in.readObject();
in.close();
fileIn.close();
} catch (IOException i) {
} catch (ClassNotFoundException c) {
}
}
}
public void saveTMap(HashMap<byte[], byte[]> TMap) {
try {
FileOutputStream fileOut = new FileOutputStream(FILEPATH);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(TMap);
out.close();
fileOut.close();
} catch (IOException i) {
i.printStackTrace();
}
}
In your code TMap is written and read correctly. The problem is that you can not use a byte array as key for the map as equals compares the reference of the byte array and not the contents.
Wrap your key in custom class and implement equals and hashCode like this:
public class ByteArrayKey implements Serializable {
private byte[] content;
public ByteArrayKey(byte[] content) {
this.content = content;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ByteArrayKey that = (ByteArrayKey) o;
return Arrays.equals(content, that.content);
}
#Override
public int hashCode() {
return Arrays.hashCode(content);
}
}
Then change you load and save methods like this:
public static HashMap<ByteArrayKey, byte[]> loadTMap() {
HashMap<ByteArrayKey, byte[]> TMap = new HashMap<>();
File f = new File(FILEPATH);
if (f.exists()) {
try {
FileInputStream fileIn = new FileInputStream(FILEPATH);
ObjectInputStream in = new ObjectInputStream(fileIn);
TMap = (HashMap<ByteArrayKey, byte[]>) in.readObject();
in.close();
fileIn.close();
} catch (IOException i) {
i.printStackTrace();
} catch (ClassNotFoundException c) {
c.printStackTrace();
}
}
return TMap;
}
public static void saveTMap(HashMap<ByteArrayKey, byte[]> TMap) {
try {
FileOutputStream fileOut = new FileOutputStream(FILEPATH);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(TMap);
out.close();
fileOut.close();
} catch (IOException i) {
i.printStackTrace();
}
}

Java read a file into an arraylist of objects and return that arraylist

I need to write a class that has two static methods: writeFile and readFile. However, after I do my readFile(), it returns nothing.
class writereadFile {
public static void writeFile(ArrayList<Object> list, File file){
try {
try (FileOutputStream fos = new FileOutputStream(file);ObjectOutputStream oos = new ObjectOutputStream(fos)) {
oos.writeObject(list);
oos.close();
}
}catch(IOException e){e.getMessage();}
}
public static ArrayList<Object> readFile(ArrayList<Object>list, File file){
try {
try (FileInputStream fis = new FileInputStream(file);ObjectInputStream ois = new ObjectInputStream(fis)) {
Object o = ois.readObject();
list = (ArrayList<Object>) o;
ois.close();
}
}catch(IOException | ClassNotFoundException e){e.getMessage();}
System.out.println(list);
return list;
}
}
EDIT:
This my class for testing. My object is an arraylist of custom objects if you need the custom object just comment.
class main {
public static void main(String[] args) {
Date date = new Date();
Book b1 = new Book("abc", "Phi", true, date, null);
Book b2 = new Book("cba", "Someone", true, date, null);
Books booklist = new Books();
booklist.add(b1);
booklist.add(b2);
File filetoDo = new File("book.txt");
//write arraylist into file
writereadFile.writeFile(booklist, filetoDo);
//clear the arraylist
booklist.clear();
//read book from file
writereadFile.readFile(booklist, filetoDo);
System.out.println(booklist);
}
}
Your test should read:
bookList = writereadFile.readFile(booklist, filetoDo);
and, by the way, you should really refactor your readFile method to simply:
public static ArrayList<Object> readFile(File file)
You can't modify the argument reference like that, since Java is always pass-by-value call semantics. (You could modify the list argument contents inside the function, but that's not what you are doing.)
If you are using Java 8 try using Streams:
public static readFile(String filePath) {
List<Object> list = new ArrayList<>();
try (Stream<String> stream = Files.lines(Paths.get(filePath))) {
stream.forEach(list::add);
} catch (IOException e) {
e.printStackTrace();
}
return list;
}
I'm playing around this topic a bit on my own, so below you can find some code snippets that might help you.
Examples are very short and simple, so I hope you will not just use e.printStackTrace() in your code :)
public class ExternalIO {
private ExternalIO() {
}
public static ObjectOutputStream objectOutputStream(String basePath, String pathToFile) throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream(createFileIfDoesNotExist(absolutePath(basePath, pathToFile)));
return new ObjectOutputStream(fileOutputStream);
}
public static ObjectInputStream objectInputStream(String basePath, String pathToFile) throws IOException {
FileInputStream fileInputStream = new FileInputStream(absolutePath(basePath, pathToFile));
return new ObjectInputStream(fileInputStream);
}
private static File createFileIfDoesNotExist(String absolutePath) throws IOException {
File file = new File(absolutePath);
if (file.exists()) {
return file;
}
file.getParentFile().mkdirs();
file.createNewFile();
return file;
}
private static String absolutePath(String basePath, String pathToFile) {
return Paths.get(basePath, pathToFile).toAbsolutePath().toString();
}
}
output usage:
List<ItemType> input = null; //create your input list here
try (ObjectOutputStream objectOutputStream = ExternalIO.objectOutputStream(CONFIG, FILENAME)) {
objectOutputStream.writeObject(input);
} catch (Exception e) {
e.printStackTrace();
}
input usage:
try (ObjectInputStream objectInputStream = ExternalIO.objectInputStream(CONFIG, FILENAME)) {
return (List<ItemType>) objectInputStream.readObject();
} catch (Exception e) {
e.printStackTrace();
}
hope that helps ; )

How do I delete a file stored in cache? (android)

I am not able delete file that is stored in cache. I am using the cache for several purposes. I am reading and writing but not able to delete. Can someone please help me with this?
//write
public static void writeObject(Context context, String key, Object object)
throws IOException {
Log.d("Cache", "WRITE: context");
FileOutputStream fos = context.openFileOutput(key, Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(object);
oos.close();
fos.close();
}
//read
public static Object readObject(Context context, String key) throws IOException,
ClassNotFoundException {
FileInputStream fis = context.openFileInput(key);
ObjectInputStream ois = new ObjectInputStream(fis);
Object object = ois.readObject();
return object;
}
//delete
public static void clearCahe(String key) throws IOException,ClassNotFoundException {
File file = new File(key);
file.delete();
}
context.openFileOutput(key writes the file to internal memory. The path you can find with getFilesDir() and looks like /data/data/<yourpackagename>/files.
So if you want to delete the file 'key' you have to set up the path for File file = new File(path) as String path = getFilesDir().getAbsolutePath() + "/" + key;.
And use file.exists() to check if the file exists!
use this to clear application data.
public void clearApplicationData()
{
File cache = getCacheDir();
File appDir = new File(cache.getParent());
if (appDir.exists()) {
String[] children = appDir.list();
for (String s : children) {
if (!s.equals("lib")) {
deleteDir(new File(appDir, s));Log.i("TAG", "**************** File /data/data/APP_PACKAGE/" + s + " DELETED *******************");
}
}
}
}
public static boolean deleteDir(File dir)
{
if (dir != null && dir.isDirectory()) {
String[] children = dir.list();
for (int i = 0; i < children.length; i++) {
boolean success = deleteDir(new File(dir, children[i]));
if (!success) {
return false;
}
}
}
return dir.delete();
}
Files
Like the cache directory, your app also has an app-specific directory for holding files. Files in this directory will exist until the app explicitly deletes them or the app is uninstalled. You typically access this directory with Context.getFilesDir(). This can show up as various things on the app info screen, but in your screenshot this is "USB Storage Data".
NOTE: If you want to explicitly place on external media (typically SD card), you can use Context.getExternalFilesDir(String type).
Simple cache manager:
public class CacheManager {
private static final long MAX_SIZE = 5242880L; // 5MB
private CacheManager() {
}
public static void cacheData(Context context, byte[] data, String name) throws IOException {
File cacheDir = context.getCacheDir();
long size = getDirSize(cacheDir);
long newSize = data.length + size;
if (newSize > MAX_SIZE) {
cleanDir(cacheDir, newSize - MAX_SIZE);
}
File file = new File(cacheDir, name);
FileOutputStream os = new FileOutputStream(file);
try {
os.write(data);
}
finally {
os.flush();
os.close();
}
}
public static byte[] retrieveData(Context context, String name) throws IOException {
File cacheDir = context.getCacheDir();
File file = new File(cacheDir, name);
if (!file.exists()) {
// Data doesn't exist
return null;
}
byte[] data = new byte[(int) file.length()];
FileInputStream is = new FileInputStream(file);
try {
is.read(data);
}
finally {
is.close();
}
return data;
}
private static void cleanDir(File dir, long bytes) {
long bytesDeleted = 0;
File[] files = dir.listFiles();
for (File file : files) {
bytesDeleted += file.length();
file.delete();
if (bytesDeleted >= bytes) {
break;
}
}
}
private static long getDirSize(File dir) {
long size = 0;
File[] files = dir.listFiles();
for (File file : files) {
if (file.isFile()) {
size += file.length();
}
}
return size;
}
}
NOTE: The purpose of the cache is to cut down on network activity,
long processes, and provide a responsive UI in your app.
Reference: When to clear the cache dir in Android?.

How to copy file from one location to another location?

I want to copy a file from one location to another location in Java. What is the best way to do this?
Here is what I have so far:
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.List;
public class TestArrayList {
public static void main(String[] args) {
File f = new File(
"D:\\CBSE_Demo\\Demo_original\\fscommand\\contentplayer\\config");
List<String>temp=new ArrayList<String>();
temp.add(0, "N33");
temp.add(1, "N1417");
temp.add(2, "N331");
File[] matchingFiles = null;
for(final String temp1: temp){
matchingFiles = f.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.startsWith(temp1);
}
});
System.out.println("size>>--"+matchingFiles.length);
}
}
}
This does not copy the file, what is the best way to do this?
You can use this (or any variant):
Files.copy(src, dst, StandardCopyOption.REPLACE_EXISTING);
Also, I'd recommend using File.separator or / instead of \\ to make it compliant across multiple OS, question/answer on this available here.
Since you're not sure how to temporarily store files, take a look at ArrayList:
List<File> files = new ArrayList();
files.add(foundFile);
To move a List of files into a single directory:
List<File> files = ...;
String path = "C:/destination/";
for(File file : files) {
Files.copy(file.toPath(),
(new File(path + file.getName())).toPath(),
StandardCopyOption.REPLACE_EXISTING);
}
Update:
see also
https://stackoverflow.com/a/67179064/1847899
Using Stream
private static void copyFileUsingStream(File source, File dest) throws IOException {
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream(source);
os = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
} finally {
is.close();
os.close();
}
}
Using Channel
private static void copyFileUsingChannel(File source, File dest) throws IOException {
FileChannel sourceChannel = null;
FileChannel destChannel = null;
try {
sourceChannel = new FileInputStream(source).getChannel();
destChannel = new FileOutputStream(dest).getChannel();
destChannel.transferFrom(sourceChannel, 0, sourceChannel.size());
}finally{
sourceChannel.close();
destChannel.close();
}
}
Using Apache Commons IO lib:
private static void copyFileUsingApacheCommonsIO(File source, File dest) throws IOException {
FileUtils.copyFile(source, dest);
}
Using Java SE 7 Files class:
private static void copyFileUsingJava7Files(File source, File dest) throws IOException {
Files.copy(source.toPath(), dest.toPath());
}
Or try Googles Guava :
https://github.com/google/guava
docs:
https://guava.dev/releases/snapshot-jre/api/docs/com/google/common/io/Files.html
Use the New Java File classes in Java >=7.
Create the below method and import the necessary libs.
public static void copyFile( File from, File to ) throws IOException {
Files.copy( from.toPath(), to.toPath() );
}
Use the created method as below within main:
File dirFrom = new File(fileFrom);
File dirTo = new File(fileTo);
try {
copyFile(dirFrom, dirTo);
} catch (IOException ex) {
Logger.getLogger(TestJava8.class.getName()).log(Level.SEVERE, null, ex);
}
NB:- fileFrom is the file that you want to copy to a new file fileTo in a different folder.
Credits - #Scott: Standard concise way to copy a file in Java?
public static void copyFile(File oldLocation, File newLocation) throws IOException {
if ( oldLocation.exists( )) {
BufferedInputStream reader = new BufferedInputStream( new FileInputStream(oldLocation) );
BufferedOutputStream writer = new BufferedOutputStream( new FileOutputStream(newLocation, false));
try {
byte[] buff = new byte[8192];
int numChars;
while ( (numChars = reader.read( buff, 0, buff.length ) ) != -1) {
writer.write( buff, 0, numChars );
}
} catch( IOException ex ) {
throw new IOException("IOException when transferring " + oldLocation.getPath() + " to " + newLocation.getPath());
} finally {
try {
if ( reader != null ){
writer.close();
reader.close();
}
} catch( IOException ex ){
Log.e(TAG, "Error closing files when transferring " + oldLocation.getPath() + " to " + newLocation.getPath() );
}
}
} else {
throw new IOException("Old location does not exist when transferring " + oldLocation.getPath() + " to " + newLocation.getPath() );
}
}
Copy a file from one location to another location means,need to copy the whole content to another location.Files.copy(Path source, Path target, CopyOption... options) throws IOException this method expects source location which is original file location and target location which is a new folder location with destination same type file(as original).
Either Target location needs to exist in our system otherwise we need to create a folder location and then in that folder location we need to create a file with the same name as original filename.Then using copy function we can easily copy a file from one location to other.
public static void main(String[] args) throws IOException {
String destFolderPath = "D:/TestFile/abc";
String fileName = "pqr.xlsx";
String sourceFilePath= "D:/TestFile/xyz.xlsx";
File f = new File(destFolderPath);
if(f.mkdir()){
System.out.println("Directory created!!!!");
}
else {
System.out.println("Directory Exists!!!!");
}
f= new File(destFolderPath,fileName);
if(f.createNewFile()) {
System.out.println("File Created!!!!");
} else {
System.out.println("File exists!!!!");
}
Files.copy(Paths.get(sourceFilePath), Paths.get(destFolderPath, fileName),REPLACE_EXISTING);
System.out.println("Copy done!!!!!!!!!!!!!!");
}
You can do it with the Java 8 Streaming API, PrintWriter and the Files API
try (PrintWriter pw = new PrintWriter(new File("destination-path"), StandardCharsets.UTF_8)) {
Files.readAllLines(Path.of("src/test/resources/source-file.something"), StandardCharsets.UTF_8)
.forEach(pw::println);
}
If you want to modify the content on-the-fly while copying, check out this link for the extended example https://overflowed.dev/blog/copy-file-and-modify-with-java-streams/
I modified one of the answers to make it a bit more efficient.
public void copy(){
InputStream in = null;
try {
in = new FileInputStream(Files);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
OutputStream out = new FileOutputStream();
try {
// Transfer bytes from in to out
byte[] buf = new byte[1024];
while (true) {
int len = 0;
try {
if (!((len = in.read(buf)) > 0)) break;
} catch (IOException e) {
e.printStackTrace();
}
try {
out.write(buf, 0, len);
} catch (IOException e) {
e.printStackTrace();
}
}
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void moveFile() {
copy();
File dir = getFilesDir();
File file = new File(dir, "my_filename");
boolean deleted = file.delete();
}
Files.exists()
Files.createDirectory()
Files.copy()
Overwriting Existing Files:
Files.move()
Files.delete()
Files.walkFileTree()
enter link description here
You can use
FileUtils.copy(sourceFile, destinationFile);
https://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/FileUtils.html

Categories

Resources