FileDescriptor Class in Java - java

According to the Documentation,
java.io.FileDescriptor works for opening a file having a specific name. If there is any content present in that file it will first erase
all that content and put “Beginning of Process” as the first line.
My FILE.txt file contains content as my name 'Jaimin Modi' only.
Now, below is one sample for the use of FileDescriptor class in java:
import java.io.*;
public class NewClass
{
public static void main(String[] args) throws IOException
{
// Initializing a FileDescriptor
FileDescriptor geek_descriptor = null;
FileOutputStream geek_out = null;
// HERE I'm writing "GEEKS" in my file
byte[] buffer = {71,69,69,75,83};
try{
geek_out = new FileOutputStream("FILE.txt");
// This getFD() method is called before closing the output stream
geek_descriptor = geek_out.getFD();
// writes byte to file output stream
geek_out.write(buffer);
// USe of sync() : to sync data to the source file
geek_descriptor.sync();
System.out.print("\nUse of Sync Successful ");
}
catch(Exception excpt)
{
// if in case IO error occurs
excpt.printStackTrace();
}
finally
{
// releases system resources
if(geek_out!=null)
geek_out.close();
}
}
}
Am getting below output/content in FILE.txt as 'GEEKS'.
So, What I have done next is just commented the lines for the use of FileDescriptor.
Commented below lines :
FileDescriptor geek_descriptor = null;
geek_descriptor = geek_out.getFD();
geek_descriptor.sync();
and again changed content in FILE.txt as 'Jaimin Modi'.
then just executed. What am getting in FILE.txt :
'GEEKS'..!!
Am getting the same result with and without the use of FileDescriptor.
So, What is the main use of FileDescriptor here. Confused a little. Please guide.

Related

How do I handle storage in a Java console app that cannot use DB?

I am given an assignment where we are not allowed to use a DB or libraries but only textfile for data storage.
But it has rather complex requirements, for e.g. many validations, because of that, we need to "access the db" (i.e. read the textfile) many times.
My question is: should I create a class like this:
class SomeRepository{
static ArrayList<Users> users = new ArrayList();
public SomeRepository(){
//instantiate this class on program load
//In constructor, we read the text file, instantiate and store everything inside the arraylist.
}
//public getOneUser(){ // for get methods, we don't read from text file at all }
/public save() { //text file saving code overhere }
}
Is this a good approach to solve the above problem? Currently, what we are doing is reading and writing to the text file every time we want to retrieve some data or write something new.
Wouldn't this be too expensive in terms of heap space memory? Or should I just read/write to the text file for every method?
public class IOManager {
public static void writeObjToTxtFile(String fileName, Object object) {
File file = new File(fileName + ".txt");//File will be created in the root directory where the program runs.
try (FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos);) {
oos.writeObject(object);
} catch (IOException e) {
e.printStackTrace();
}
}
public static Object readObjFromTxtFile(String fileName) {
Object obj = null;
File file = new File(fileName + ".txt");
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis);
obj = ois.readObject();
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
return obj;
}
}
Add this class to your project. Since it's general for all Objects, you can pass and receive Objects like these as well: ArrayList<Users>. Play around and Tinker with it to fit whatever your specific purpose is. Hint: You can write other custom methods that calls these methods. eg:
public static void writeUsersToFile(ArrayList<Users> usersArrayList){
writeObjToTxtFile("users",usersArrayList);
}
Ps. Make sure your Objects implement Serializable. Eg:
public class Users implements Serializable {
}
I would suggest reading the contents of your file to a dynamic list such as an arraylist at the start of your program. Make the required queries/changes to your arraylist and then write that arraylist to your file when the program is set to close. This will save significant time over repeated file reads/writes.
This isn't without it's drawbacks, though. You don't want to hogg up memory in case of very large files - but considering this is an assignment, that may not be the case. Additionally, should your program terminate prior to the write at the end, all changes made to your database during the current execution will be lost.

Java memory Mapped File from Windows system

I'm trying something new,
There is an application who send data to a memory-mapped file located at Local\MemFileName
I would like to read it in java,
I tried some tutorials like https://www.baeldung.com/java-mapped-byte-buffer, https://howtodoinjava.com/java7/nio/memory-mapped-files-mappedbytebuffer/
But all seem to read a file in JVM, or I did not understand...
How can I read the content of the file Located in windows system Local\MemFileName
Thanks!
Following: Example code of what i tried
public class Main {
private static final String IRSDKMEM_MAP_FILE_NAME = StringEscapeUtils.unescapeJava("Local\\IRSDKMemMapFileName");
private static final String IRSDKDATA_VALID_EVENT = StringEscapeUtils.unescapeJava("Local\\IRSDKDataValidEvent");
public static final CharSequence charSequence = "Local\\IRSDKMemMapFileName";
public static void main(String[] args) throws IOException, InterruptedException {
System.out.println(charSequence);
try (RandomAccessFile file = new RandomAccessFile(new File(IRSDKMEM_MAP_FILE_NAME), "r")) {
//Get file channel in read-only mode
FileChannel fileChannel = file.getChannel();
//Get direct byte buffer access using channel.map() operation
MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size());
// the buffer now reads the file as if it were loaded in memory.
System.out.println("Loaded " + buffer.isLoaded()); //prints false
System.out.println("capacity" + buffer.capacity()); //Get the size based on content size of file
//You can read the file from this buffer the way you like.
for (int i = 0; i < buffer.limit(); i++) {
System.out.println((char) buffer.get()); //Print the content of file
}
}
}
}
To read a memory mapped file:
Open a FileChannel on the file using FileChannel.open.
Invoke the map method on the FileChannel to create a MappedByteBuffer covering the area of the file you want to read.
Read the data from the MappedByteBuffer.
The solution for me was to use a WindowsService.class implementing methods from JNA library, as you can see:
My Library
With this I could open a file mapped in Windows system.
All the previous answers was correct for a file accessible from JVM, but from outside the JVM it was impossible.
Thanks !

Appending data in a CSV in selenium automation

I have a CSV file in Resources of my automation script and I need to amend one cell value to a parameter value I get by creating a folder in a site, I ran this code but then an error comes:
"(The process cannot access the file because it is being used by another process)".
Can anyone let me know how to write my parameter value to CSV file cell, please.
TIA
Method:
public static void writeCSV(String filePath, String separator) throws IOException {
try (OutputStream fileStream = new BufferedOutputStream(new FileOutputStream(filePath));
Writer outStreamWriter = new OutputStreamWriter(fileStream, StandardCharsets.UTF_8);
BufferedWriter buffWriter = new BufferedWriter(outStreamWriter)) {
buffWriter.append("https://mobile/sample_v4.zip");
buffWriter.append(separator);
buffWriter.append(createdTitle);
buffWriter.append(separator);
buffWriter.append("http://2-title-conversion/documentlibrary");
buffWriter.append(separator);
buffWriter.append("TRUE");
buffWriter.append(separator);
buffWriter.append("TRUE");
buffWriter.flush();
}
#Test segment,
loginPg.writeCSV("C:\\Users\\urathya\\Documents\\Automation\\03-11\\resources\\CS.csv",",");
You are not closing the output stream, please close it, it will close file and you can use the same file to append the data.

Change in file after creating FileOutputStream object even without writing anything into file

EDIT (for the sake of confusion): null has been written into the files "abc" and "efg".
After running the following code, the contents of file "abc" change which were initially null , and I get EOFException in every next execution :
ObjIStream = new ObjectInputStream(new FileInputStream("abc"));
M[][] objs = (M[][]) ObjIStream.readObject();
FS.objs = objs;
ObjIStream.close();
Here, FS.objs is a static member of class FS of type M[][] type.
On the other hand, this one has no effect on the file and I don't get any Exceptions after any number of executions:
ObjIStream = new ObjectInputStream(new FileInputStream("abc"));
M[][] objs = (M[][]) ObjIStream.readObject();
ObjIStream.close();
EDIT: I just found the trouble that exists in class FS in this form:
static{
try {
ObjOStream = new ObjectOutputStream(new FileOutputStream("abc"));
ObjOStream.close();
ObjOStream = new java.io.ObjectOutputStream(new java.io.FileOutputStream("efg"));
ObjOStream.close();
}
catch (IOException ex) { }
}
How is it troubling anyways?
The problem is new FileOutputStream("abc") itself, which means new FileOutputStream("abc", false). It cleans up all the data in file because you are not going to append anything. It calls FileOutputStream.open(String name, boolean append) which is a private native function. It erases everything in file in overwrite mode.

Error in displaying a doc file reading that from a document on console in java

I tried to display the data from a doc file on console then i got this error
run:
The document is really a RTF file
Exception in thread "main" java.lang.NullPointerException
at DocReader.readDocFile(DocReader.java:36)
at DocReader.main(DocReader.java:47)
Java Result: 1
BUILD SUCCESSFUL (total time: 4 seconds)
can any one explain where i went wrong
the code is
import java.io.File;
import java.io.FileInputStream;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.extractor.WordExtractor;
public class DocReader {
public void readDocFile() {
File docFile = null;
WordExtractor docExtractor = null ;
WordExtractor exprExtractor = null ;
try {
docFile = new File("C:\\web.doc");
FileInputStream fis=new FileInputStream(docFile.getAbsolutePath());
HWPFDocument doc=new HWPFDocument(fis);
docExtractor = new WordExtractor(doc);
}
catch(Exception exep)
{
System.out.println(exep.getMessage());
}
String [] docArray = docExtractor.getParagraphText();
for(int i=0;i<docArray.length;i++)
{
if(docArray[i] != null)
System.out.println("Line "+ i +" : " + docArray[i]);
}
}
public static void main(String[] args) {
DocReader reader = new DocReader();
reader.readDocFile();
}
}
The document is really a RTF file
That's a typical message of an IllegalArgumentException from the HWPFDocument constructor. To the point it means that the supplied file is actually a (Wordpad) RTF file whose .rtf extension has incorrectly been renamed to .doc.
Supply a real MS Word .doc file instead and fix your code to not continue the flow when an exception has occurred. You need to throw it.
Just open the file in some Document program like Microsoft Office. Now save the same file with "Save As" option and choose .doc format.
That means, at line 36 of DocReader.java file, you are trying to invoke an API from an object but the object is not being created yet. So, the solution is to create an instance of the class first before making that API invocation.
UPDATE
My hunch tells me the NullPointerException happens at docExtractor.getParagraphText() because the docExtractor doesn't get initialized properly. Instead of swallowing the exception, print the stacktrace to figure out the actual problem, like this:-
try {
...
}
catch(Exception exep) {
exep.printStackTrace(); // do this
}

Categories