Behavior of InputStream vs. CharacterStream - filereader

I am trying to understand the difference between behavior of any byte oriented stream (say FileInputStream) and any Character oriented stream (say FileReader).
I went through the following: http://docs.oracle.com/javase/tutorial/essential/io/charstreams.html
First program:
`import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyBytes {
public static void main(String[] args) throws IOException {
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("xanadu.txt");
out = new FileOutputStream("outagain.txt");
int c;
while ((c = in.read()) != -1) {
out.write(c);
}
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}
`
Second program:
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CopyCharacters {
public static void main(String[] args) throws IOException {
FileReader inputStream = null;
FileWriter outputStream = null;
try {
inputStream = new FileReader("xanadu.txt");
outputStream = new FileWriter("characteroutput.txt");
int c;
while ((c = inputStream.read()) != -1) {
outputStream.write(c);
}
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
}
}
It says:
in CopyCharacters, the int variable holds a character value in its last 16 bits; in CopyBytes, the int variable holds a byte value in its last 8 bits.
My question is: I wanted to check this above sentence so printed value of c (integer defined in program) while it was being copied. Now the value of c must be different at consecutive reads because in byte stream it reads byte by byte, so have byte value, while in character stream it reads character by character, so has character ASCII value. But it is giving same values of c. Why?

Tried to think it in different way, If my source file has only one character say 'a'.
Now CopyBytes should run while loop atleast 2 times because character takes 2 bytes. But it is running only once.
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
//in CopyCharacters, the int variable holds a character value in its last 16 bits;
//in CopyBytes, the int variable holds a byte value in its last 8 bits.
public class CopyCharacters {
public static void main(String[] args) throws IOException {
FileReader inputStream = null;
FileWriter outputStream = null;
try {
inputStream = new FileReader("source.txt");
outputStream = new FileWriter("characteroutput.txt");
int c;
while ((c = inputStream.read()) != -1) {
System.out.println("one");
outputStream.write(c);
}
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
}
}
Here one is printed only once

Related

How to change textfield inputs to only numbers in javafx? [duplicate]

This question already has answers here:
What is the recommended way to make a numeric TextField in JavaFX?
(24 answers)
Restricting a TextField input to hexadecimal values in Java FX
(3 answers)
Closed 3 years ago.
I have a credit card page in my java fx program. I am trying to make it so that the inputs only allow numbers. At the moment it only gives an error if the fields are empty. But no error occurs if text is included?
I have tried changing it from String to integer, but that doesn't work.
public void thankyoupage(ActionEvent actionEvent) throws IOException {
String cardno = cardtf.getText();
String expdate1 = expirytf1.getText();
String expdate2 = expirytf2.getText();
String cvvnum = cvvtf.getText();
if (cardno.equals("") || expdate1.equals("") ||
expdate2.equals("") || cvvnum.equals("")) {
Alert alert = new Alert(Alert.AlertType.WARNING, "Enter Full Details", ButtonType.OK);
alert.showAndWait();
} else{
Window mainWindow = confirmbut.getScene().getWindow();
Parent newRoot = FXMLLoader.load(getClass().getResource("Thankyou.fxml"));
mainWindow.getScene().setRoot(newRoot);
}
}
Any links or changes would be nice.
You should attach a TextFormatter to your TextField. I have attached a sample on using Decimals - since you are using money, this might make the most sense.
On your text field you simply add the TextFormatter - this will prevent entry of anything other than what you allow.
//For Example
moneyTextField.setTextFormatter(new DecimalTextFormatter(0, 2));
--Below is the control code.
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.function.UnaryOperator;
import javafx.scene.control.TextFormatter;
import javafx.util.StringConverter;
public class DecimalTextFormatter extends TextFormatter<Number> {
private static DecimalFormat format = new DecimalFormat("#.0;-#.0");
public DecimalTextFormatter(int minDecimals, int maxDecimals) {
super(getStringConverter(minDecimals, maxDecimals), 0, getUnaryOperator(maxDecimals, true,-1));
}
public DecimalTextFormatter(int minDecimals, int maxDecimals, boolean allowsNegative) {
super(getStringConverter(minDecimals, maxDecimals), 0, getUnaryOperator(maxDecimals, allowsNegative,-1));
}
public DecimalTextFormatter(int minDecimals, int maxDecimals, boolean allowsNegative , int maxNoOfDigitsBeforeDecimal) {
super(getStringConverter(minDecimals, maxDecimals), 0, getUnaryOperator(maxDecimals, allowsNegative, maxNoOfDigitsBeforeDecimal));
}
private static StringConverter<Number> getStringConverter(int minDecimals, int maxDecimals) {
return new StringConverter<Number>() {
#Override
public String toString(Number object) {
if (object == null) {
return "";
}
String format = "0.";
for (int i = 0; i < maxDecimals; i++) {
if (i < minDecimals) {
format = format + "0";
} else {
format = format + "#";
}
}
format = format + ";-" + format;
DecimalFormat df = new DecimalFormat(format);
String formatted = df.format(object);
return formatted;
}
#Override
public Number fromString(String string) {
try {
if (string == null) {
return null;
}
return format.parse(string);
} catch (ParseException e) {
return null;
}
}
};
}
private static UnaryOperator<javafx.scene.control.TextFormatter.Change> getUnaryOperator(int maxDecimals,
boolean allowsNegative, int noOfDigitsBeforeDecimal) {
return new UnaryOperator<TextFormatter.Change>() {
#Override
public TextFormatter.Change apply(TextFormatter.Change change) {
if (!allowsNegative && change.getControlNewText().startsWith("-")) {
return null;
}
if (change.getControlNewText().isEmpty()) {
return change;
}
ParsePosition parsePosition = new ParsePosition(0);
Object object = format.parse(change.getControlNewText(), parsePosition);
if (change.getCaretPosition() == 1) {
if (change.getControlNewText().equals(".")) {
return change;
}
}
if (object == null || parsePosition.getIndex() < change.getControlNewText().length()) {
return null;
} else {
if(noOfDigitsBeforeDecimal != -1)
{
int signum = new BigDecimal(change.getControlNewText()).signum();
int precision = new BigDecimal(change.getControlNewText()).precision();
int scale = new BigDecimal(change.getControlNewText()).scale();
int val = signum == 0 ? 1 : precision - scale;
if (val > noOfDigitsBeforeDecimal) {
return null;
}
}
int decPos = change.getControlNewText().indexOf(".");
if (decPos > 0) {
int numberOfDecimals = change.getControlNewText().substring(decPos + 1).length();
if (numberOfDecimals > maxDecimals) {
return null;
}
}
return change;
}
}
};
}
}
You have to use regular expressions to validate fields. You can learn more about regular expression here https://regexr.com/
String cardno = cardtf.getText();
if (cardno.equals("") || expdate1.equals("") || expdate2.equals("") || cvvnum.equals("")) {
Alert alert = new Alert(Alert.AlertType.WARNING, "Enter Full Details", ButtonType.OK);
alert.showAndWait();
}else if (cardno.matches("/^[A-Za-z ]+$/")){
Alert alert = new Alert(Alert.AlertType.WARNING, "It Can not contain letters", ButtonType.OK);
alert.showAndWait();
}else{
//Else Part
}
Here is a piece of code that should help you doing the trick by checking at every input if the text contains only numbers an a maximum of one "," as the decimal separator.
There is already a post showing how to do this.
Post
import javafx.beans.value.ObservableValue;
import javafx.scene.control.TextField;
public class NumberField extends TextField {
public NumberField () {
initSpellListener();
}
public final void initSpellListener() {
this.textProperty().addListener((ObservableValue<? extends String> observable, String oldValue, String newValue) -> {
if (!newValue.matches("\\d*")) {
this.setText(newValue.replaceAll("[^\\d,]", ""));/*The comma here "[^\\d,]" can be changed with the dot*/
StringBuilder aus = new StringBuilder();
aus.append(this.getText());
boolean firstPointFound = false;
for (int i = 0; i < aus.length(); i++) {
if (aus.charAt(i) == ',') {/*Change the , with . if you want the . to be the decimal separator*/
if (!firstPointFound) {
firstPointFound = true;
} else {
aus.deleteCharAt(i);
}
}
}
newValue = aus.toString();
this.setText(newValue);
} else {
this.setText(newValue);
}
});
}}
[As soon as I find the post I will credit this code.]
if (!newValue.matches("\\d*"))
this part of the code checks with a regex expression if the new string value doesn't contain only numbers, and then with this code
this.setText(newValue.replaceAll("[^\\d,]", ""));
it replaces all the non-digit or comma chars.
Finally the for-loop checks if only exists one comma ad if other are found they are deleted.
To help you with regex writing here is a very useful site : Online regex
Then you can use this object as a normal TextField:
#FMXL
private NumberField nf;

RocksDB: how to use ttl in java?

I am testing rocksdb for java api. I put a key-value entry into the map, and then wait for 20s, then get from map. Why the entry is not deleted?
this is my code:
import org.rocksdb.Options;
import org.rocksdb.RocksDBException;
import org.rocksdb.TtlDB;
public class Test2 {
public static void main(String[] args) throws Exception {
TtlDB.loadLibrary();
Options options = new Options()
.setCreateIfMissing(true);
TtlDB db = TtlDB.open(options, args[0],20,false);
if(args.length > 3 && "put".equals(args[1])) {
db.put(args[2].getBytes(), args[3].getBytes());
}
byte[] arr = db.get(args[2].getBytes());
if(arr != null) {
System.out.println(new String(arr));
} else {
System.out.println(arr);
}
System.out.println(db.get(args[2].getBytes()));
Thread.sleep(21000);
System.out.println(db.get(args[2].getBytes()));
db.close();
}
}
Expired TTL values are deleted in compaction only:(Timestamp + ttl < time_now)
https://github.com/facebook/rocksdb/wiki/Time-to-Live

JavaFX TimeTextField

Base Article:
[https://community.oracle.com/thread/2552039?start=0&tstart=0][1]
I extend the solution from the oracle community with the event filters in the constructor for a better user ergonomics.
The JavaFX TimeTextField provides all functions needed for time handling.
Unfortunately it's missing in the JavaFX Standard in Java8, where a time handling field is a must in my point of view as in other technologies it is possible.
The thread in the oracle community is not as frequent as I expect it, please test it and try to improve it! We need it...
Features:
- only numeric keys are accepted.
- validation for a given time format
- (my improvement) when the last number of a block like hours or minutes was reached, the cursor jumps to the next block.
package test;
import java.util.regex.Pattern;
import javafx.beans.binding.Bindings;
import javafx.application.Application;
import javafx.beans.binding.IntegerBinding;
import javafx.beans.property.ReadOnlyIntegerProperty;
import javafx.beans.property.ReadOnlyIntegerWrapper;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.IndexRange;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TimeTextFieldTest extends Application {
#Override
public void start(Stage primaryStage) {
VBox root = new VBox(5);
root.setPadding(new javafx.geometry.Insets(5));
Label hrLabel = new Label();
Label minLabel = new Label();
Label secLabel = new Label();
TimeTextField timeTextField = new TimeTextField();
hrLabel.textProperty().bind(Bindings.format("Hours: %d", timeTextField.hoursProperty()));
minLabel.textProperty().bind(Bindings.format("Minutes: %d", timeTextField.minutesProperty()));
secLabel.textProperty().bind(Bindings.format("Seconds: %d", timeTextField.secondsProperty()));
root.getChildren().addAll(timeTextField, hrLabel, minLabel, secLabel);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
public static class TimeTextField extends TextField {
enum Unit {
HOURS, MINUTES, SECONDS
};
private final Pattern timePattern;
private final ReadOnlyIntegerWrapper hours;
private final ReadOnlyIntegerWrapper minutes;
private final ReadOnlyIntegerWrapper seconds;
public TimeTextField() {
this("00:00:00");
this.addEventFilter(KeyEvent.KEY_TYPED, new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent inputevent) {
int c = TimeTextField.this.getCaretPosition();
if (c <= 7) {
if (!"1234567890:".contains(inputevent.getCharacter().toLowerCase())) {
inputevent.consume();
}
} else {
inputevent.consume();
}
}
});
this.addEventFilter(KeyEvent.KEY_RELEASED, new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent inputevent) {
boolean withMinutes = false;
if (TimeTextField.this.getText() != null && TimeTextField.this.getText().length() >= 5
&& TimeTextField.this.getText().indexOf(":") == 2) {
withMinutes = true;
}
boolean withSeconds = false;
if (TimeTextField.this.getText() != null && TimeTextField.this.getText().length() == 8
&& TimeTextField.this.getText().lastIndexOf(":") == 5) {
withSeconds = true;
}
int c = TimeTextField.this.getCaretPosition();
if (((c == 2 && withMinutes) || (c == 5 && withSeconds))
&& (inputevent.getCode() != KeyCode.LEFT && inputevent.getCode() != KeyCode.BACK_SPACE)) {
TimeTextField.this.forward();
inputevent.consume();
}
}
});
}
public TimeTextField(String time) {
super(time);
// timePattern = Pattern.compile("\\d\\d:\\d\\d:\\d\\d");
timePattern = Pattern.compile("([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]");
if (!validate(time)) {
throw new IllegalArgumentException("Invalid time: " + time);
}
hours = new ReadOnlyIntegerWrapper(this, "hours");
minutes = new ReadOnlyIntegerWrapper(this, "minutes");
seconds = new ReadOnlyIntegerWrapper(this, "seconds");
hours.bind(new TimeTextField.TimeUnitBinding(Unit.HOURS));
minutes.bind(new TimeTextField.TimeUnitBinding(Unit.MINUTES));
seconds.bind(new TimeTextField.TimeUnitBinding(Unit.SECONDS));
}
public ReadOnlyIntegerProperty hoursProperty() {
return hours.getReadOnlyProperty();
}
public int getHours() {
return hours.get();
}
public ReadOnlyIntegerProperty minutesProperty() {
return minutes.getReadOnlyProperty();
}
public int getMinutes() {
return minutes.get();
}
public ReadOnlyIntegerProperty secondsProperty() {
return seconds.getReadOnlyProperty();
}
public int getSeconds() {
return seconds.get();
}
#Override
public void appendText(String text) {
// Ignore this. Our text is always 8 characters long, we cannot
// append anything
}
#Override
public boolean deleteNextChar() {
boolean success = false;
// If there's a selection, delete it:
final IndexRange selection = getSelection();
if (selection.getLength() > 0) {
int selectionEnd = selection.getEnd();
this.deleteText(selection);
this.positionCaret(selectionEnd);
success = true;
} else {
// If the caret preceeds a digit, replace that digit with a zero
// and move the caret forward. Else just move the caret forward.
int caret = this.getCaretPosition();
if (caret % 3 != 2) { // not preceeding a colon
String currentText = this.getText();
setText(currentText.substring(0, caret) + "0" + currentText.substring(caret + 1));
success = true;
}
this.positionCaret(Math.min(caret + 1, this.getText().length()));
}
return success;
}
#Override
public boolean deletePreviousChar() {
boolean success = false;
// If there's a selection, delete it:
final IndexRange selection = getSelection();
if (selection.getLength() > 0) {
int selectionStart = selection.getStart();
this.deleteText(selection);
this.positionCaret(selectionStart);
success = true;
} else {
// If the caret is after a digit, replace that digit with a zero
// and move the caret backward. Else just move the caret back.
int caret = this.getCaretPosition();
if (caret % 3 != 0) { // not following a colon
String currentText = this.getText();
setText(currentText.substring(0, caret - 1) + "0" + currentText.substring(caret));
success = true;
}
this.positionCaret(Math.max(caret - 1, 0));
}
return success;
}
#Override
public void deleteText(IndexRange range) {
this.deleteText(range.getStart(), range.getEnd());
}
#Override
public void deleteText(int begin, int end) {
// Replace all digits in the given range with zero:
StringBuilder builder = new StringBuilder(this.getText());
for (int c = begin; c < end; c++) {
if (c % 3 != 2) { // Not at a colon:
builder.replace(c, c + 1, "0");
}
}
this.setText(builder.toString());
}
#Override
public void insertText(int index, String text) {
// Handle an insert by replacing the range from index to
// index+text.length() with text, if that results in a valid string:
StringBuilder builder = new StringBuilder(this.getText());
builder.replace(index, index + text.length(), text);
final String testText = builder.toString();
if (validate(testText)) {
this.setText(testText);
}
this.positionCaret(index + text.length());
}
#Override
public void replaceSelection(String replacement) {
final IndexRange selection = this.getSelection();
if (selection.getLength() == 0) {
this.insertText(selection.getStart(), replacement);
} else {
this.replaceText(selection.getStart(), selection.getEnd(), replacement);
}
}
#Override
public void replaceText(IndexRange range, String text) {
this.replaceText(range.getStart(), range.getEnd(), text);
}
#Override
public void replaceText(int begin, int end, String text) {
if (begin == end) {
this.insertText(begin, text);
} else {
// only handle this if text.length() is equal to the number of
// characters being replaced, and if the replacement results in
// a valid string:
if (text.length() == end - begin) {
StringBuilder builder = new StringBuilder(this.getText());
builder.replace(begin, end, text);
String testText = builder.toString();
if (validate(testText)) {
this.setText(testText);
}
this.positionCaret(end);
}
}
}
private boolean validate(String time) {
if (!timePattern.matcher(time).matches()) {
return false;
}
String[] tokens = time.split(":");
assert tokens.length == 3;
try {
int hours = Integer.parseInt(tokens[0]);
int mins = Integer.parseInt(tokens[1]);
int secs = Integer.parseInt(tokens[2]);
if (hours < 0 || hours > 23) {
return false;
}
if (mins < 0 || mins > 59) {
return false;
}
if (secs < 0 || secs > 59) {
return false;
}
return true;
} catch (NumberFormatException nfe) {
// regex matching should assure we never reach this catch block
assert false;
return false;
}
}
private final class TimeUnitBinding extends IntegerBinding {
final Unit unit;
TimeUnitBinding(Unit unit) {
this.bind(textProperty());
this.unit = unit;
}
#Override
protected int computeValue() {
// Crazy enum magic
String token = getText().split(":")[unit.ordinal()];
return Integer.parseInt(token);
}
}
}
}

Filereader does not go to next line

import java.util.*;
import java.io.*;
import java.text.DecimalFormat;
My problem is that once it starts the loop it just reads the first line on the file and writes it infinitely amount of times.
What I want is for it to go to the next line and so on
(The code is basically what I want but it is not finished)
public class Lab0234
{
public static void main(String [] args) throws FileNotFoundException
{
DecimalFormat two = new DecimalFormat("00.00");
Scanner keyboard = new Scanner(System.in);
Scanner inputFile = new Scanner(new FileReader("Lab02Input.txt"));
double sPrice = inputFile.nextDouble();
double sOwned = inputFile.nextDouble();
double aDiv = inputFile.nextDouble();
double mValue;
double mYield;
mValue = getValue(sPrice, sOwned);
mYield = getYield(sPrice, aDiv);
PrintWriter reportFile = new PrintWriter("Lab02Report.txt");
reportFile.println("Stock Value and Yield Report");
reportFile.println("");
reportFile.print("Stock ");
reportFile.print("Price ");
reportFile.print("Shares ");
reportFile.print("Value ");
reportFile.print("Dividend ");
reportFile.println("Yield");
while(inputFile.hasNext())
{
if (inputFile.hasNext())
{
reportFile.print(" ");
reportFile.print(sPrice+" ");
reportFile.print(sOwned+" ");
getValue(sPrice, sOwned);
reportFile.print(two.format(mValue)+" ");
reportFile.print(aDiv+" ");
getYield(sPrice, aDiv);
reportFile.println(two.format(mYield)+" ");
inputFile.close();
reportFile.close();
}
/*else
{
inputFile.close();
reportFile.close();
}*/
}
//inputFile.close();
//reportFile.close();
}
public static double getValue(double sPrice, double sOwned)
{
//DecimalFormat two = new DecimalFormat("00.00"); //Decimal format
double mValue;
mValue = (sPrice * sOwned);
//System.out.printf("Stock Value is " + mValue);
return mValue;
}
public static double getYield(double sPrice, double aDiv)
{
//DecimalFormat two = new DecimalFormat("00.00"); //Decimal format
double mYield;
mYield = (aDiv * sPrice);
//System.out.printf("\nDividend Yield is " + two.format(mYield));
return mYield;
}
}
You never call next() on your inputFile:
while(inputFile.hasNext())
{
String x = inputFile.next();
if (inputFile.hasNext())
Try do it like this
try {
BufferedReader br = new BufferedReader(new FileReader(filePath));
String line;
while ((line = br.readLine()) != null) {
// do somthing
}
br.close();
} catch (Exception e) {
System.out.print("Problem!");
}

How to accept mine if any conflicts occur while pull-rebase in JGit

I have a piece of code that does pull with rebase:
private void pullWithRebase(Git git) throws GitAPIException {
git.checkout().setName("master").call();
List<Ref> branches = git.branchList().setListMode(ListBranchCommand.ListMode.ALL).call();
String remoteMasterBranchName = "refs/remotes/origin/master";
for (Ref ref : branches) {
if (remoteMasterBranchName.equals(ref.getName())) {
PullResult result = git.pull().setRemoteBranchName("master").setRebase(true).call();
return;
}
}
}
However it doesn't work if any conflicts occur while merging. If they do occur, I want to accept mine
I ended up just merging two branches and directly resolving any conflicts by modifying files.
private static final String CONFLICT_HEAD_MARKER = "<<<<<<<";
private static final String CONFLICT_BORDER_MARKER = "=======";
private static final String CONFLICT_UPSTREAM_MARKER = ">>>>>>>";
private boolean acceptHead;
public void resolve(File file) throws IOException {
File temp = new File(file.getParent(), "temp" + System.currentTimeMillis());
try(BufferedReader reader = new BufferedReader(new FileReader(file));
BufferedWriter writer = new BufferedWriter(new FileWriter(temp))) {
String currentLine;
boolean removePartition = false;
while((currentLine = reader.readLine()) != null) {
if (currentLine.contains(CONFLICT_HEAD_MARKER)) {
removePartition = !acceptHead;
continue;
} else if (currentLine.contains(CONFLICT_BORDER_MARKER)) {
removePartition = acceptHead;
continue;
} else if (currentLine.contains(CONFLICT_UPSTREAM_MARKER)) {
removePartition = false;
continue;
}
if (!removePartition) {
writer.write(currentLine + System.getProperty("line.separator"));
}
}
}
FileUtils.forceDelete(file);
FileUtils.moveFile(temp, file);
}

Resources