How to determine File Format? DOS/Unix/MAC - java

I have written the following method to detemine whether file in question is formatted with DOS/ MAC, or UNIX line endings.
I see at least 1 obvious issue:
1. i am hoping that i will get the EOL on the first run, say within first 1000 bytes. This may or may not happen.
I ask you to review this and suggest improvements which will lead to hardening the code and making it more generic.
THANK YOU.
new FileFormat().discover(fileName, 0, 1000);
and then
public void discover(String fileName, int offset, int depth) throws IOException {
BufferedInputStream in = new BufferedInputStream(new FileInputStream(fileName));
FileReader a = new FileReader(new File(fileName));
byte[] bytes = new byte[(int) depth];
in.read(bytes, offset, depth);
a.close();
in.close();
int thisByte;
int nextByte;
boolean isDos = false;
boolean isUnix = false;
boolean isMac = false;
for (int i = 0; i < (bytes.length - 1); i++) {
thisByte = bytes[i];
nextByte = bytes[i + 1];
if (thisByte == 10 && nextByte != 13) {
isDos = true;
break;
} else if (thisByte == 13) {
isUnix = true;
break;
} else if (thisByte == 10) {
isMac = true;
break;
}
}
if (!(isDos || isMac || isUnix)) {
discover(fileName, offset + depth, depth + 1000);
} else {
// do something clever
}
}

Your method seems unnecessarily complicated. Why not:
public class FileFormat {
public enum FileType { WINDOWS, UNIX, MAC, UNKNOWN }
private static final char CR = '\r';
private static final char LF = '\n';
public static FileType discover(String fileName) throws IOException {
Reader reader = new BufferedReader(new FileReader(fileName));
FileType result = discover(reader);
reader.close();
return result;
}
private static FileType discover(Reader reader) throws IOException {
int c;
while ((c = reader.read()) != -1) {
switch(c) {
case LF: return FileType.UNIX;
case CR: {
if (reader.read() == LF) return FileType.WINDOWS;
return FileType.MAC;
}
default: continue;
}
}
return FileType.UNKNOWN;
}
}
Which puts this in a static method that you can then call and use as:
switch(FileFormat.discover(fileName) {
case WINDOWS: ...
case MAC: ...
case UNKNOWN: ...
}

Here's a rough implementation that guesses the line ending type based on a simple majority and falls back on unknown in a worst-case scenario:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.EnumMap;
import java.util.Map;
import java.util.Scanner;
class LineEndings
{
private enum ExitState
{
SUCCESS, FAILURE;
}
public enum LineEndingType
{
DOS("Windows"), MAC("Mac OS Classic"), UNIX("Unix/Linux/Mac OS X"), UNKNOWN("Unknown");
private final String name;
private LineEndingType(String name)
{
this.name = name;
}
public String toString()
{
if (null == this.name) {
return super.toString();
}
else {
return this.name;
}
}
}
public static void main(String[] arguments)
{
ExitState exitState = ExitState.SUCCESS;
File inputFile = getInputFile();
if (null == inputFile) {
exitState = ExitState.FAILURE;
System.out.println("Error: No input file specified.");
}
else {
System.out.println("Determining line endings for: " + inputFile.getName());
try {
LineEndingType lineEndingType = getLineEndingType(inputFile);
System.out.println("Determined line endings: " + lineEndingType);
}
catch (java.io.IOException exception) {
exitState = ExitState.FAILURE;
System.out.println("Error: " + exception.getMessage());
}
}
switch (exitState) {
case SUCCESS:
System.exit(0);
break;
case FAILURE:
System.exit(1);
break;
}
}
private static File getInputFile()
{
File inputFile = null;
Scanner stdinScanner = new Scanner(System.in);
while (true) {
System.out.println("Enter the input file name:");
System.out.print(">> ");
if (stdinScanner.hasNext()) {
String inputFileName = stdinScanner.next();
inputFile = new File(inputFileName);
if (!inputFile.exists()) {
System.out.println("File not found.\n");
}
else if (!inputFile.canRead()) {
System.out.println("Could not read file.\n");
}
else {
break;
}
}
else {
inputFile = null;
break;
}
}
System.out.println();
return inputFile;
}
private static LineEndingType getLineEndingType(File inputFile)
throws java.io.IOException, java.io.FileNotFoundException
{
EnumMap<LineEndingType, Integer> lineEndingTypeCount =
new EnumMap<LineEndingType, Integer>(LineEndingType.class);
BufferedReader inputReader = new BufferedReader(new FileReader(inputFile));
LineEndingType currentLineEndingType = null;
while (inputReader.ready()) {
int token = inputReader.read();
if ('\n' == token) {
currentLineEndingType = LineEndingType.UNIX;
}
else if ('\r' == token) {
if (inputReader.ready()) {
int nextToken = inputReader.read();
if ('\n' == nextToken) {
currentLineEndingType = LineEndingType.DOS;
}
else {
currentLineEndingType = LineEndingType.MAC;
}
}
}
if (null != currentLineEndingType) {
incrementLineEndingType(lineEndingTypeCount, currentLineEndingType);
currentLineEndingType = null;
}
}
return getMostFrequentLineEndingType(lineEndingTypeCount);
}
private static void incrementLineEndingType(Map<LineEndingType, Integer> lineEndingTypeCount, LineEndingType targetLineEndingType)
{
Integer targetLineEndingCount = lineEndingTypeCount.get(targetLineEndingType);
if (null == targetLineEndingCount) {
targetLineEndingCount = 0;
}
else {
targetLineEndingCount++;
}
lineEndingTypeCount.put(targetLineEndingType, targetLineEndingCount);
}
private static LineEndingType getMostFrequentLineEndingType(Map<LineEndingType, Integer> lineEndingTypeCount)
{
Integer maximumEntryCount = Integer.MIN_VALUE;
Map.Entry<LineEndingType, Integer> mostFrequentEntry = null;
for (Map.Entry<LineEndingType, Integer> entry : lineEndingTypeCount.entrySet()) {
int entryCount = entry.getValue();
if (entryCount > maximumEntryCount) {
mostFrequentEntry = entry;
maximumEntryCount = entryCount;
}
}
if (null != mostFrequentEntry) {
return mostFrequentEntry.getKey();
}
else {
return LineEndingType.UNKNOWN;
}
}
}

There is a whole lot wrong with this. You need to understand the FileInputStream class better. Note that read is not guaranteed to read all the bytes you requested. offset is the offset into the array, not the file. And so on.

Related

Java - write to a .csv file after sorting an arraylist of objects

I have an arraylist of object type:
public static ArrayList crimes = new ArrayList();
The CityCrime.java has the following:
public class CityCrime {
//Instance variables
private String city;
private String state;
private int population;
private int murder;
private int robbery;
private int assault;
private int burglary;
private int larceny;
private int motorTheft;
public int totalCrimes;
public static void main(String[] args) {
}
public int getTotalCrimes() {
return totalCrimes;
}
public void setTotalCrimes(int murder, int robbery, int assault, int burglary, int larceny, int motorTheft) {
this.totalCrimes = murder + robbery + assault + burglary + larceny + motorTheft;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
if(state.equalsIgnoreCase("ALABAMA")) {
this.state = "AL";
}
else if(state.equalsIgnoreCase("ALASKA")) {
this.state = "AK";
}
else if(state.equalsIgnoreCase("ARIZONA")) {
this.state = "AR";
}
//etc
}
public int getPopulation() {
return population;
}
public void setPopulation(int population) {
this.population = population;
}
public int getMurder() {
return murder;
}
public void setMurder(int murder) {
this.murder = murder;
}
public int getRobbery() {
return robbery;
}
public void setRobbery(int robbery) {
this.robbery = robbery;
}
public int getAssault() {
return assault;
}
public void setAssault(int assault) {
this.assault = assault;
}
public int getBurglary() {
return burglary;
}
public void setBurglary(int burglary) {
this.burglary = burglary;
}
public int getLarceny() {
return larceny;
}
public void setLarceny(int larceny) {
this.larceny = larceny;
}
public int getMotorTheft() {
return motorTheft;
}
public void setMotorTheft(int motorTheft) {
this.motorTheft = motorTheft;
}
public static void showAllMurderDetails() {
for (CityCrime crime : StartApp.crimes) {
System.out.println("Crime: City= " + crime.getCity() + ", Murder= " + crime.getMurder());
}
System.out.println();
}
public static int showAllViolentCrimes() {
int total = 0;
for(CityCrime crime : StartApp.crimes) {
total=total+crime.getMurder();
total=total+crime.getRobbery();
total=total+crime.getAssault();
}
System.out.println("Total of violent crimes: " + total);
return total;
}
public static int getPossessionCrimes() {
int total=0;
for (CityCrime crime : StartApp.crimes) {
total = total + crime.getBurglary();
total = total + crime.getLarceny();
total = total + crime.getMotorTheft();
}
System.out.println("Total of possession crimes: " + total);
return total;
}
}
The CityCrime ArrayList gets popular from another csv file:
public static void readCrimeData() {
File file = new File("crimeUSA.csv");
FileReader fileReader;
BufferedReader bufferedReader;
String crimeInfo;
String[] stats;
try {
fileReader = new FileReader(file);
bufferedReader = new BufferedReader(fileReader);
crimeInfo = bufferedReader.readLine();
crimeInfo = bufferedReader.readLine();
do {
CityCrime crime = new CityCrime(); // Default constructor
stats = crimeInfo.split(",");
{
if (stats[0] != null) {
crime.setCity(stats[0]);
}
if (stats[1] != null) {
crime.setState(stats[1]);
}
if (stats[2] != null) {
if (Integer.parseInt(stats[2]) >= 0) {
crime.setPopulation(Integer.parseInt(stats[2]));
}
}
if (stats[3] != null) {
if (Integer.parseInt(stats[3]) >= 0) {
crime.setMurder(Integer.parseInt(stats[3]));
}
}
if (stats[4] != null) {
if (Integer.parseInt(stats[4]) >= 0) {
crime.setRobbery(Integer.parseInt(stats[4]));
}
}
if (stats[5] != null) {
if (Integer.parseInt(stats[5]) >= 0) {
crime.setAssault(Integer.parseInt(stats[5]));
}
}
if (stats[6] != null) {
if (Integer.parseInt(stats[6]) >= 0) {
crime.setBurglary(Integer.parseInt(stats[6]));
}
}
if (stats[7] != null) {
if (Integer.parseInt(stats[7]) >= 0) {
crime.setLarceny(Integer.parseInt(stats[7]));
}
}
if (stats[8] != null) {
if (Integer.parseInt(stats[8]) >= 0) {
crime.setMotorTheft(Integer.parseInt(stats[8]));
}
}
crime.setTotalCrimes(Integer.parseInt(stats[3]), Integer.parseInt(stats[4]), Integer.parseInt(stats[5]), Integer.parseInt(stats[6]), Integer.parseInt(stats[7]), Integer.parseInt(stats[8]));
}
crimes.add(crime);
System.out.println(crime);
crimeInfo = bufferedReader.readLine();
} while (crimeInfo != null);
fileReader.close();
bufferedReader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
I want to sort the array list and output to the csv file the list of robberies in descending order with the corresponding city. So far I have got the following, but I am stuck and not sure if going in the right direction. I'm relatively new to Java as you can probably tell so would appreciate it in as simple terms as can be:
public static void writeToFile() throws IOException {
File csvFile = new File("Robbery.csv");
FileWriter fileWriter = new FileWriter(csvFile);
ArrayList<Integer> robberyRates = new ArrayList();
for(CityCrime crime : crimes) {
robberyRates.add(crime.getRobbery());
}
Collections.sort(robberyRates);
}
The desired output will be for example:
Robbery,City
23511,New York
15863,Chicago
14353,Los Angeles
11371,Houston
10971,Philadelphia
etc…
Your help is appreciated. I have searched any page I can find on Google, but all I see from other example is writing to the csv from a set String ArrayList where they know the number of lines etc. Thankyou
You can try something like this:
public static void writeToFile() throws IOException {
File csvFile = new File("Robbery.csv");
try(FileWriter fileWriter = new FileWriter(csvFile)) { // try-with-resources to be sure that fileWriter will be closed at end
StringBuilder stringBuilder = new StringBuilder(); // Betther than String for multiple concatenation
crimes.sort(Comparator.comparingInt(CityCrime::getRobbery).reversed()); // I want to compare according to getRobbery, as Int, in reversed order
stringBuilder.append("Robbery")
.append(',')
.append("City")
.append(System.lineSeparator()); // To get new line character according to OS
for (final var crime : crimes)
stringBuilder.append(crime.getRobbery())
.append(',')
.append(crime.getCity())
.append(System.lineSeparator());
fileWriter.write(stringBuilder.toString());
}
}
If you are stuck because you can't figure out how to write a list, convert your list into a String and print the String instead.
I commented the piece of code, if you have any questions, don't hesitate.
Another solution is to use specific CSV parser library, OpenCSV for example.
It makes it easier to read and write CSV file.
Here a tutorial about OpenCSV:
https://mkyong.com/java/how-to-read-and-parse-csv-file-in-java/

Execute command line equivalent to Runtime.getRuntime().exec(cmd); in JNI C

I was developing an app which had requirement to implement root detection logic, so by researching I found some detection logic in JAVA and had implemented following class.
class RootDetection {
public boolean isDeviceRooted() {
return checkForBinary("su") || checkForBinary("busybox") || checkForMaliciousPaths() || checkSUonPath()
|| detectRootManagementApps() || detectPotentiallyDangerousApps() || detectRootCloakingApps()
|| checkForDangerousProps() || checkForRWPaths()
|| detectTestKeys() || checkSuExists();
}
private boolean detectTestKeys() {
String buildTags = android.os.Build.TAGS;
String buildFinger = Build.FINGERPRINT;
String product = Build.PRODUCT;
String hardware = Build.HARDWARE;
String display = Build.DISPLAY;
System.out.println("Java: build: " + buildTags + "\nFingerprint: " + buildFinger + "\n Product: " + product + "\n Hardware: " + hardware + "\nDisplay: " + display);
return (buildTags != null) && (buildTags.contains("test-keys") || buildFinger.contains("genric.*test-keys") || product.contains("generic") || product.contains("sdk") || hardware.contains("goldfish") || display.contains(".*test-keys"));
}
private boolean detectRootManagementApps() {
return detectRootManagementApps(null);
}
private boolean detectRootManagementApps(String[] additionalRootManagementApps) {
ArrayList<String> packages = new ArrayList<>();
packages.addAll(Arrays.asList(knownRootAppsPackages));
if (additionalRootManagementApps != null && additionalRootManagementApps.length > 0) {
packages.addAll(Arrays.asList(additionalRootManagementApps));
}
return isAnyPackageFromListInstalled(packages);
}
private boolean detectPotentiallyDangerousApps() {
return detectPotentiallyDangerousApps(null);
}
private boolean detectPotentiallyDangerousApps(String[] additionalDangerousApps) {
ArrayList<String> packages = new ArrayList<>();
packages.addAll(Arrays.asList(knownDangerousAppsPackages));
if (additionalDangerousApps != null && additionalDangerousApps.length > 0) {
packages.addAll(Arrays.asList(additionalDangerousApps));
}
return isAnyPackageFromListInstalled(packages);
}
private boolean detectRootCloakingApps() {
return detectRootCloakingApps(null);
}
private boolean detectRootCloakingApps(String[] additionalRootCloakingApps) {
ArrayList<String> packages = new ArrayList<>();
packages.addAll(Arrays.asList(knownRootCloakingPackages));
if (additionalRootCloakingApps != null && additionalRootCloakingApps.length > 0) {
packages.addAll(Arrays.asList(additionalRootCloakingApps));
}
return isAnyPackageFromListInstalled(packages);
}
private boolean checkForBinary(String filename) {
for (String path : suPaths) {
String completePath = path + filename;
File f = new File(completePath);
boolean fileExists = f.exists();
if (fileExists) {
return true;
}
}
return false;
}
private boolean checkForMaliciousPaths() {
for (String path : maliciousPaths) {
File f = new File(path);
boolean fileExists = f.exists();
if (fileExists) {
return true;
}
}
return false;
}
private static boolean checkSUonPath() {
for (String pathDir : System.getenv("PATH").split(":")) {
if (new File(pathDir, "su").exists()) {
return true;
}
}
return false;
}
private String[] propsReader() {
InputStream inputstream = null;
try {
inputstream = Runtime.getRuntime().exec("getprop").getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
String propval = "";
try {
propval = new Scanner(inputstream).useDelimiter("\\A").next();
} catch (NoSuchElementException e) {
}
return propval.split("\n");
}
private String[] mountReader() {
InputStream inputstream = null;
try {
inputstream = Runtime.getRuntime().exec("mount").getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
if (inputstream == null) return null;
String propval = "";
try {
propval = new Scanner(inputstream).useDelimiter("\\A").next();
} catch (NoSuchElementException e) {
e.printStackTrace();
}
return propval.split("\n");
}
private boolean isAnyPackageFromListInstalled(List<String> packages) {
PackageManager pm = activity.getPackageManager();
for (String packageName : packages) {
try {
pm.getPackageInfo(packageName, 0);
return true;
} catch (PackageManager.NameNotFoundException e) {
}
}
return false;
}
private boolean checkForDangerousProps() {
final Map<String, String> dangerousProps = new HashMap<>();
dangerousProps.put("ro.debuggable", "1");
dangerousProps.put("ro.secure", "0");
String[] lines = propsReader();
for (String line : lines) {
for (String key : dangerousProps.keySet()) {
if (line.contains(key)) {
String badValue = dangerousProps.get(key);
badValue = "[" + badValue + "]";
if (line.contains(badValue)) {
return true;
}
}
}
}
return false;
}
private boolean checkForRWPaths() {
String[] lines = mountReader();
for (String line : lines) {
String[] args = line.split(" ");
if (args.length < 4) {
continue;
}
String mountPoint = args[1];
String mountOptions = args[3];
for (String pathToCheck : pathsThatShouldNotBeWrtiable) {
if (mountPoint.equalsIgnoreCase(pathToCheck)) {
for (String option : mountOptions.split(",")) {
if (option.equalsIgnoreCase("rw")) {
return true;
}
}
}
}
}
return false;
}
private boolean checkSuExists() {
Process process = null;
try {
process = Runtime.getRuntime().exec(new String[]{"which", "su"});
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
return in.readLine() != null;
} catch (Throwable t) {
return false;
} finally {
if (process != null) process.destroy();
}
}
}
but now to increase security I want to do this root detection logic in native C++ JNI code. I managed to migrate package detection code to JNI C but am not able to find anything regarding these 3 functions
checkForDangerousProps(),checkForRWPaths(),checkSuExists()
these 3 use Runtime.getRuntime().exec which am not able to find. can someone help me in converting this 3 logics to JNI C one from above code? Help would be really appreciated.
Pls guys help.

Add words to languagetool suggesting list

I use LanguageTool for some spellchecking and spell correction functionality in my application.
The LanguageTool documentation describes how to exclude words from spell checking (with call the addIgnoreTokens(...) method of the spell checking rule you're using).
How do you add some words (e.g., from a specific dictionary) to spell checking? That is, can LanguageTool fix words with misspellings and suggest words from my specific dictionary?
Unfortunately, the API doesn't support this I think. Without the API, you can add words to spelling.txt to get them accepted and used as suggestions. With the API, you might need to extend MorfologikSpellerRule and change this place of the code. (Disclosure: I'm the maintainer of LanguageTool)
I have similar requirement, which is load some custom words into dictionary as "suggest words", not just "ignored words". And finally I extend MorfologikSpellerRule to do this:
Create class MorfologikSpellerRuleEx extends from MorfologikSpellerRule, override the method "match()", and write my own "initSpeller()" for creating spellers.
And then for the language tool, create this custom speller rule to replace existing one.
Code:
Language lang = new AmericanEnglish();
JLanguageTool langTool = new JLanguageTool(lang);
langTool.disableRule("MORFOLOGIK_RULE_EN_US");
try {
MorfologikSpellerRuleEx spellingRule = new MorfologikSpellerRuleEx(JLanguageTool.getMessageBundle(), lang);
spellingRule.setSpellingFilePath(spellingFilePath);
//spellingFilePath is the file has my own words + words from /hunspell/spelling_en-US.txt
langTool.addRule(spellingRule);
} catch (IOException e) {
e.printStackTrace();
}
The code of my custom MorfologikSpellerRuleEx:
public class MorfologikSpellerRuleEx extends MorfologikSpellerRule {
private String spellingFilePath = null;
private boolean ignoreTaggedWords = false;
public MorfologikSpellerRuleEx(ResourceBundle messages, Language language) throws IOException {
super(messages, language);
}
#Override
public String getFileName() {
return "/en/hunspell/en_US.dict";
}
#Override
public String getId() {
return "MORFOLOGIK_SPELLING_RULE_EX";
}
#Override
public void setIgnoreTaggedWords() {
ignoreTaggedWords = true;
}
public String getSpellingFilePath() {
return spellingFilePath;
}
public void setSpellingFilePath(String spellingFilePath) {
this.spellingFilePath = spellingFilePath;
}
private void initSpellerEx(String binaryDict) throws IOException {
String plainTextDict = null;
if (JLanguageTool.getDataBroker().resourceExists(getSpellingFileName())) {
plainTextDict = getSpellingFileName();
}
if (plainTextDict != null) {
BufferedReader br = null;
if (this.spellingFilePath != null) {
try {
br = new BufferedReader(new FileReader(this.spellingFilePath));
}
catch (Exception e) {
br = null;
}
}
if (br != null) {
speller1 = new MorfologikMultiSpeller(binaryDict, br, plainTextDict, 1);
speller2 = new MorfologikMultiSpeller(binaryDict, br, plainTextDict, 2);
speller3 = new MorfologikMultiSpeller(binaryDict, br, plainTextDict, 3);
br.close();
}
else {
speller1 = new MorfologikMultiSpeller(binaryDict, plainTextDict, 1);
speller2 = new MorfologikMultiSpeller(binaryDict, plainTextDict, 2);
speller3 = new MorfologikMultiSpeller(binaryDict, plainTextDict, 3);
}
setConvertsCase(speller1.convertsCase());
} else {
throw new RuntimeException("Could not find ignore spell file in path: " + getSpellingFileName());
}
}
private boolean canBeIgnored(AnalyzedTokenReadings[] tokens, int idx, AnalyzedTokenReadings token)
throws IOException {
return token.isSentenceStart() || token.isImmunized() || token.isIgnoredBySpeller() || isUrl(token.getToken())
|| isEMail(token.getToken()) || (ignoreTaggedWords && token.isTagged()) || ignoreToken(tokens, idx);
}
#Override
public RuleMatch[] match(AnalyzedSentence sentence) throws IOException {
List<RuleMatch> ruleMatches = new ArrayList<>();
AnalyzedTokenReadings[] tokens = getSentenceWithImmunization(sentence).getTokensWithoutWhitespace();
// lazy init
if (speller1 == null) {
String binaryDict = null;
if (JLanguageTool.getDataBroker().resourceExists(getFileName())) {
binaryDict = getFileName();
}
if (binaryDict != null) {
initSpellerEx(binaryDict); //here's the change
} else {
// should not happen, as we only configure this rule (or rather its subclasses)
// when we have the resources:
return toRuleMatchArray(ruleMatches);
}
}
int idx = -1;
for (AnalyzedTokenReadings token : tokens) {
idx++;
if (canBeIgnored(tokens, idx, token)) {
continue;
}
// if we use token.getToken() we'll get ignored characters inside and speller
// will choke
String word = token.getAnalyzedToken(0).getToken();
if (tokenizingPattern() == null) {
ruleMatches.addAll(getRuleMatches(word, token.getStartPos(), sentence));
} else {
int index = 0;
Matcher m = tokenizingPattern().matcher(word);
while (m.find()) {
String match = word.subSequence(index, m.start()).toString();
ruleMatches.addAll(getRuleMatches(match, token.getStartPos() + index, sentence));
index = m.end();
}
if (index == 0) { // tokenizing char not found
ruleMatches.addAll(getRuleMatches(word, token.getStartPos(), sentence));
} else {
ruleMatches.addAll(getRuleMatches(word.subSequence(index, word.length()).toString(),
token.getStartPos() + index, sentence));
}
}
}
return toRuleMatchArray(ruleMatches);
}
}

Why am I getting "missing return statement" error in Java even though I have return statement and exception in thread main error in 2nd class?

For example, I am getting the error here- this is just a snippet. I got the error 3 times in 3 different operators.
public boolean delete(String name) {
for (int i = 0; i < directory.length; i++) {
if (directory[i].equalsIgnoreCase(name)) {
directory[i] = null;
return true;
}
else
return false;
}
}
I also have the same error here:
public boolean add(String name) {
if (directory.length == 1024)
return false;
for (int i = 0; i < directory.length; i++) {
if (directory[i].equalsIgnoreCase(name))
return false;
else
directory[directorySize++] = name;
return true;
}
}
And then in my second class (the user interface portion), I keep getting this error: Exception in thread "main" java.lang.NoClassDefFoundError: Directory
Here is the entire code for that class:
import java.io.*;
import java.util.*;
public class DirectoryWithObjectDesign {
public static void main(String[] args) throws IOException {
String directoryDataFile = "Directory.txt";
Directory d = new Directory(directoryDataFile);
Scanner stdin = new Scanner(System.in);
System.out.println("Directory Server is Ready!");
System.out.println("Format: command name");
System.out.println("Enter ^Z to end");
while (stdin.hasNext()) {
String command = stdin.next();
String name = stdin.next();
if (command.equalsIgnoreCase("find")) {
if (d.inDirectory(name))
System.out.println(name + " is in the directory");
else
System.out.println(name + " is NOT in the directory");
}
else if (command.equalsIgnoreCase("add")) {
if (d.add(name))
System.out.println(name + " added");
else
System.out.println(name + " cannot add! " + "no more space or already in directory");
}
else if (command.equalsIgnoreCase("delete")) {
if (d.delete(name))
System.out.println(name + " deleted");
else
System.out.println(name + " NOT in directory");
}
else {
System.out.println("bad command, try again");
}
}
}
}
And here is the code for my directory class:
import java.util.*;
import java.io.*;
public class Directory {
//public static void main(String[] args) {
final int maxDirectorySize = 1024;
String directory[] = new String[maxDirectorySize];
int directorySize = 0;
File directoryFile = null;
Scanner directoryDataIn = null;
public Directory(String directoryFileName) {
directoryFile = new File(directoryFileName);
try {
directoryDataIn = new Scanner(directoryFile);
}
catch (FileNotFoundException e) {
System.out.println("File is not found, exiting!" + directoryFileName);
System.exit(0);
}
while (directoryDataIn.hasNext()) {
directory[directorySize++] = directoryDataIn.nextLine();
}
}
public boolean inDirectory(String name) {
for (int i = 0; i < directory.length; i++) {
if (directory[i].equalsIgnoreCase(name))
return true;
else
return false;
}
}
public boolean add(String name) {
if (directory.length == 1024)
return false;
for (int i = 0; i < directory.length; i++) {
if (directory[i].equalsIgnoreCase(name))
return false;
else
directory[directorySize++] = name;
return true;
}
}
public boolean delete(String name) {
for (int i = 0; i < directory.length; i++) {
if (directory[i].equalsIgnoreCase(name)) {
directory[i] = null;
return true;
}
else
return false;
}
}
public void closeDirectory() {
directoryDataIn.close();
PrintStream directoryDataOut = null;
try {
directoryDataOut = new PrintStream(directoryFile);
}
catch (FileNotFoundException e) {
System.out.printf("File %s not found, exiting!", directoryFile);
System.exit(0);
}
String originalDirectory[] = {"Mike","Jim","Barry","Cristian","Vincent","Chengjun","susan","ng","serena"};
if (originalDirectory == directory)
System.exit(0);
else
for (int i = 0; i < directorySize; i++)
directoryDataOut.println(directory[i]);
directoryDataOut.close();
}
}
The point is that the compiler can't know if your for loop will be entered at all. Therefore you need a final return after the end of the for loop, too. In other words: any path that can possibly be taken within your method needs a final return statement. One easy way to achieve this ... is to have only one return statement; and put that on the last line of the method. This could look like:
Object getSomething() {
Object rv = null; // rv short for "returnValue"
for (int i=0; i < myArray.length; i++) {
if (whatever) {
rv = godKnowsWhat;
} else {
rv = IdontCare;
}
}
return rv;
}
In your second example, the indenting seems to indicate that you have a return in the else statement
directory[directorySize++] = name;
return true;
But when you look closer, you will realize that there are TWO statements after the else
else
directory[directorySize++] = name;
return true;
So this actually reads like
else
directory[directorySize++] = name;
return true;
Meaning: always put {braces} around all your blocks, even for (supposedly) one-liner then/else lines. That helps to avoid such mistakes, when a one-liner turns into a two-liner (or vice versa ;-)
The "NoClassDefFoundException" means: within the classpath that is specified to java ... there is no class Directory.class
To resolve that, you should study what the java classpath is about; and how to set it correctly.

Remove or ignore character from reader

i am reading all characters into stream. I am reading it with inputStream.read. This is java.io.Reader inputStream.
How can i ignore special characters like # when reading into buffer.
code
private final void FillBuff() throws java.io.IOException
{
int i;
if (maxNextCharInd == 4096)
maxNextCharInd = nextCharInd = 0;
try {
if ((i = inputStream.read(nextCharBuf, maxNextCharInd,
4096 - maxNextCharInd)) == -1)
{
inputStream.close();
throw new java.io.IOException();
}
else
maxNextCharInd += i;
return;
}
catch(java.io.IOException e) {
if (bufpos != 0)
{
--bufpos;
backup(0);
}
else
{
bufline[bufpos] = line;
bufcolumn[bufpos] = column;
}
throw e;
}
}
You can use a custom FilterReader.
class YourFilterReader extends FilterReader{
#Override
public int read() throws IOException{
int read;
do{
read = super.read();
} while(read == '#');
return read;
}
#Override
public int read(char[] cbuf, int off, int len) throws IOException{
int read = super.read(cbuf, off, len);
if (read == -1) {
return -1;
}
int pos = off - 1;
for (int readPos = off; readPos < off + read; readPos++) {
if (read == '#') {
continue;
} else {
pos++;
}
if (pos < readPos) {
cbuf[pos] = cbuf[readPos];
}
}
return pos - off + 1;
}
}
Resources :
Javadoc - FilterReader
BCRDF - Skipping Invalid XML Character with ReaderFilter
On the same topic :
filter/remove invalid xml characters from stream
All those readers, writers and streams implement the Decorator pattern. Each decorator adds additional behaviour and functionality to the underlying implementation.
A solution for you requirement could be a FilterReader:
public class FilterReader implements Readable, Closeable {
private Set<Character> blacklist = new HashSet<Character>();
private Reader reader;
public FilterReader(Reader reader) {
this.reader = reader;
}
public void addFilter(char filtered) {
blacklist.add(filtered);
}
#Override
public void close() throws IOException {reader.close();}
#Override
public int read(char[] charBuf) {
char[] temp = new char[charBuf.length];
int charsRead = reader.read(temp);
int index = -1;
if (!(charsRead == -1)) {
for (char c:temp) {
if (!blacklist.contains(c)) {
charBuf[index] = c;
index++;
}
}
}
return index;
}
}
Note - the class java.io.FilterReader is a decorator with zero functionality. You can extend it or just ignore it and create your own decorator (which I prefer in this case).
You could implement an own inputstream derived from InputStream. Then override the read methods so that they filter a special character out of the stream.
private final void FillBuff() throws java.io.IOException
{
int i;
if (maxNextCharInd == 4096)
maxNextCharInd = nextCharInd = 0;
try {
Reader filterReader = new FilterReader(inputStream) {
public int read() {
do {
result = super.read();
} while (specialCharacter(result));
return result;
}
};
if ((i = filterReader.read(nextCharBuf, maxNextCharInd,
4096 - maxNextCharInd)) == -1)
{
inputStream.close();
throw new java.io.IOException();
}
else
maxNextCharInd += i;
return;
}
catch(java.io.IOException e) {
if (bufpos != 0)
{
--bufpos;
backup(0);
}
else
{
bufline[bufpos] = line;
bufcolumn[bufpos] = column;
}
throw e;
}
}

Categories

Resources