Dave Tolls wrote:
Michael Mutek wrote:
Does anyone have an idea why my list is apparently not storing the added elements correctly, but just overwrting itself with every new
element I want to add?
The first place I would check is how you are maintaining the full List in testStagingArea.
I'm taking a bit of a guess here, but I'm going to suggest this is a new List each time, and so will only ever contain the single StagingAreaItem when it is serialised.
Exactly how you ensure that List is correct before adding a new element is up to you, and likely depends on the system itself.
Campbell Ritchie wrote:. . . I did try running some straightforward code. . . .
Paul Clapham wrote:
Michael Mutek wrote:Does anyone have an idea why my list is apparently not storing the added elements correctly, but just overwrting itself with every new element I want to add?
Yes. When you open a file for output, that's what it does. If there was anything there in a file of that name before, it's thrown away. Unless you use the FileOutputStream(File, boolean) constructor in which you can say you want to append to the file.
Ah nice one, I have not even known this constructor before - will have a look.
Since by now I have solved my problem and all works fine now, but there is quite a bit of laborious code in my solution, specifically 'helper-lists'.
With using FileOutputStream(File, boolean)' I might get rid of them (because my .ser-file will not be overwritten every time I call the add()_method),
which would lead to a nicer solution - will try it out.
You may also be having a problem because you don't close the file after you finish writing to it. Because you didn't do that, the last part of the output may not be flushed to wherever on disk the file is located.
Fixed that one in the meanwhile by using try-with-ressources-statements.
And some parts of your code are excessively complicated. In one method you pass a File object and you want to put that object into a FileOutputStream. So you should just do that. Converting the File object to a String and then back to a File is at best a waste of time. Probably it doesn't do any harm but why bother?
Yeah, there are up to now still many redundancies and it does not look too nice...
Will try to refactor a lot to get a nicer outcome.
I have to say that I didn't read most of that post. It looks like you're tryiing to build a workaround for problems which would be better addressed by just doing things in the straightforward (and correct) way.
At first, one must know how to do it str8-forward to do it str8-forward - seems I lack too many basics for solving this task in a more solid way.
Mike Simmons wrote:
Campbell Ritchie wrote:I am afraid that, as far as I know, it can't be done. You can only serialise one object at a time in an XYZ.ser file.
Michael Mutek wrote:. . . I cannot story multiple objects within my .ser-file, right?
How can this be done? . . .
Sure you can. You can, for example, write a file with five objects in a row, simply by calling writeObject() five times with five different arguments, then closing the stream, and file. Then when you read it, you call readObject() five times in a row. Works just fine.
The problem, though, is that this requires you to know in advance how many objects will be in the file. Often, you don't know that. So there are several possible solutions:
1. Write N objects, then when deserializing, just read objects in a loop until you get an error from an end-of-file. This is messy, and may be hard to distinguish between a normal end-of-file error, and other errors that indicate other problems.
2. Use writeInt() and readInt() to write and read the number of objects at the beginning of the file. To write 5 objects, use writeInt(5), then use writeObject() 5 times. To read, use readInt(), then call readObject() that number of times.
3. Just put everything in a list or array, and write the list / array.
This is basically storing everything (and also every update (add or remove)) into a list-object (or array-object) and only then serialize this list/array-object?
If so, I like that best for know and will try that out.
4. Define a custom object to signal the end of file. Write as many objects as you want, then write your EOF object. To read, just keep reading in a loop, and when you find an EOF object, you're done.
Option 3 is by far the easiest and most common (which is why it was already suggested). Option 4 can be useful if you don't know in advance how many objects there will be, and you don't want to store them all in memory at once. Option 2 can make sense as part of a custom serialization method. And option 1 is really only done by accident.
Campbell Ritchie wrote:Does that matter, as long as you get a recognisable hash from it?
Michael Mutek wrote:. . . I know that the SHA-1 is outdated . . .I am afraid that, as far as I know, it can't be done. You can only serialise one object at a time in an XYZ.ser file.
. . . I cannot story multiple objects within my .ser-file, right?
Actually thinking about my aimed usecase, security does not matter here indeed.
I just need basically distinctive, unique "IDs", i.e. hashes to avoid collisions...so yeah, thinking more about it, SHA-1 is here in general sufficient.
How can this be done? . . .
Yeah, I was thinking a lot yesterday about that, but could not wrap my head around it, but before going to sleep it hit me, that it makes sense that it cannot be done. As you said, I can serialize only one single object at one time.
If I serialize later one more time, the now serialized object will just overwrite the content in my .ser-file - is this correct?
If so, then my solutionthought would be following:
When I want to represent a kind of staging are like in gitHHub (only simpler), then what I need at first is an object where I can store the current
working-directory which I want to add to my staging Area.
So basically for instance a object from the type List.
After that, I can serialize this list-object and store its contents in my .ser-file (= representation of my staging area).
Now, lets say I want to add to my staging area another file (like I have tried - test2.txt-file).
At this point if I serialize it right away, then it would just overwrite the contents which are in my .ser-file - is this correct?
So what I need to do is to just add this new test2-txt-file into my list-object and then serialize my (updated) list-object again...
Would you agree with my solution idea or do I still get it wrong?
You can create a List<XYZ> and serialise that; most standard List implementations are serialisable. Its elements are rather like fields of the List, and fields of an object are serialised along with it. As long as those fields can be serialised at all.
Otherwise you would need multiple xyz.ser files; you can try adding date and time or hash to their names.
Oops, the next time I should make a habit of at first reading the whole post before starting to reply back right away D:
is this what you say basically the same what my solution idea says?
And yeah, I rather want to keep it as simple as possible and would therefore try your first slution-idea and skip for now the idea with
adding multiple .ser-files and somehow label them distinctively.
Campbell Ritchie wrote:There is probably an FX class corresponding to JFileChooser. If you are already writing FX, try an FX class first. If you become proficient in FX, you may never need to use Swing. But that isn't either of the naughty things I thought I was doing.
Yes, you did use something almost identical to line 8. But it is not a case of the line being empty. When the buffered reader reaches the end of the file, it returns null from readLine(). That is how it signals completion of its task.
Oops, I actually meant this in my brain, but have for some unknown reason (maybe exhaustion^^) stated something which is wrong in my post above.
Yeah, clearly - the task there is to execute the while-loop as long as there is content in the file, i.e. til the end of the file.
A single iteration ends apparently when there is a 'new line' incoming - so after every line, a new iteration of the loop will begin.
You start by assigning line with whatever is read next, and you need additional () because != has a higher precedence than =. When you have assigned line, you test whether it is null. It there is an empty String, that suggests the enter key has been pressed twice, and readLine() will return a 0‑length String. You may wish to test for empty Strings in the body of the loop, or not.
Ah that is intersting.
Let's say we have one text-file with two paragraphs, where between thos two paragraphs two or more empty lines are existent, e.g.
In this case, reading from the file using the method would be a problem, since it would think that the file came to an end, after "Hello world!" ?
I think the subejct of your second thread is different enough from this one to merit a second thread.
Campbell Ritchie wrote:Can we have that very simply. Are you trying to serialise multiple objects to the same Path?
Yeah, basically the goal is to serialize multiple objects into the same .ser-file.
That won't work; you will only retain the most recently serialised object.
What are you serialising, and why are you serialising anything?
I want to track for potential changes/modification of the contents inside the files.
I plan to track for changes by using a MerkleTree (I have already implemented the code).
If I understand it correct, the idea of a MerkleTree is that two hashes from two children will create throughout concatenating them (hash1 + hash2) and then hashing the concatenated hash throughout a SHA-Algorithm (I have already implemented one),
the hash from its parent.
I have simplified my problem to having only two files and one parent-directory for now - when it works, I will extend the problem.
See the attached image.
Why doesn't your object have the digest hash as a field? You can probably find ready‑made classes that will calculate an SHA256 or similar for you. You need to be circumspect about when you call that method, so you aren't storing anything with an out of date SHA.
I know that the SHA-1 is outdated + there are ready classes for it. But for this task, I want to use still the SHA-1 and implement it myself (already done and it works, as you can see in my image in the first post -> the file gets a hash).
The objects have an attribute hash, as well as an attribute name (=filename).
But the hash needs to be created based on the content of the file using my convertToHash-method.
If you are doing version control, why do you need a serialised object? Why can't you simply use text files? Much easier and less error‑prone; I heard that Oracle want to get rid of serialisation because it is error‑prone, anyway.
Yeah, but for this task, I need to use Serialization for the cvs.
It's not my call...
edit: Or maybe I understand the task wrong? What does this sentence mean in our context:
"so you have to serialize the information stored in the “staging area” and load
again before every following call."
Maybe I shall not serialize from the beginning, but:
1.) At first store the objects normally in the .ser-file (which reperesents the staging area).
2.) And afterwards serialize/deserialize this .ser-file?
Was it maybe meant like that or totally differently and I do not get it at all?
Why are you using new File in line 5? Why aren't you using try with resources? I can't see that output stream being closed anywhere, which means the file may be locked as write‑only.
Tim Holloway wrote:
Note for your own sanity's sake: Java has the convention that the "real", that is forward slash may be used as a filepath separator on all OS's, including Windows. So rather than this:
Because just one dropped backslash can ruin your whole day. Plus it helps if you ever need to run on a non-Windows OS, and that's no longer a rare occurrence. And may get rarer if Microsoft doesn't keep screwing up Windows 10.
Jj Roberts wrote:I'm not at my computer, so I can't help much. You are using the wrong class for reading text. Instead, look into the Reader classes, and maybe the Scanner class. The I/O learning trail from Oracle here is an excellent place to start.
Hope that helps for now.