尚不清楚是文件中的每一整行要被尊重还是每行中的每个单词要被颠倒,两者之间存在重大差异。在任何情况下,下面提供的方法都可以做到。
您不能写入正在读取的文件,您需要提供不同的文件名。但是,您可以做的是,当创建新文件并且您的代码已关闭读取器和写入器时,您可以删除原始文件,然后使用原始文件的名称重命名新文件。正如您将看到的,这只是几行代码。
您正在阅读用户的输入而不是输入文件。这就是为什么给变量提供清晰、可区分和有意义的名称很重要的原因,例如读者代替输入文件接近扫描仪键盘输入名称输入)。如果变量名称相似或不具描述性,则很容易出错。
这是方法:
/**
* Rewrites the supplied file into a new file where every word in that file
* has its characters reversed. The new file created (in the same directory)
* is named exactly the same except it will contain the file name extension
* of ".temp" unless, the `overwriteFile` option was passed boolean true in
* which case the original file is overwritten.<br><br>
*
* This method will need to be wrapped within a try/catch block.<br>
*
* @param fileName (String) the full path and file name (including file name
* extension) to the file which is to be reversed.<br>
*
* @param options (optional - Boolean - Two of):<pre>
*
* reverseEntireLine - Default is false where each word in each file line
* will be separately reversed. If boolean true is
* optionally supplied then each entire line is
* reversed. If null is supplied then false is implied.
*
* Whitespacing (indents, etc) in the file is also
* taken into consideration and maintained.
*
* overwriteFile - Default is false where the original file being
* read is not overwriten with reversed text but
* instead a new file is created under the same name,
* within the same directory, containing a file name
* extension of ".temp". If boolean true is supplied
* to this optional parameter then the original file
* will be overwriten. It should be noted that there
* is no actual overwrite. The original file is actually
* deleted and then the new file is renamed to the
* original file name. This will allow for extremely
* large files to be overwriten without the worry of
* memory exhaustion.<pre>
*
* @throws FileNotFoundException
* @throws IOException
*/
public static void reverseFile(String fileName, Boolean... options)
throws FileNotFoundException, IOException {
// false = each word in line | true = entire line.
boolean reverseEntireLine = false;
// false = Not Overwrite File | true = Overwrite File.
boolean overwriteFile = false;
if (options.length > 0) {
if (options.length >= 1 && options[0] != null) {
reverseEntireLine = options[0];
}
if (options.length >= 2 && options[1] != null) {
overwriteFile = options[1];
}
}
File fileToRead = new File(fileName); // Create a File object.
/* Create a name for a temporary file to write in
within the same path of the file we are about
to read. This name will be the same but will
have the file name extension of ".temp". */
String fullPath = fileToRead.getAbsolutePath();
String tempFile = fullPath.substring(0, fullPath.lastIndexOf(".")) + ".temp";
/* You can not write to the file you are reading from.
Provide a different (temporary) name. */
/* 'Try With Resources' is used here for both the reader and writer so
to auto-close() them when done and free resources. */
try (BufferedReader reader = new BufferedReader(new java.io.InputStreamReader(
new java.io.FileInputStream(fullPath), "UTF-8"))) {
java.io.OutputStream os = new java.io.FileOutputStream(tempFile);
try (PrintWriter writer = new PrintWriter(new java.io.OutputStreamWriter(os, "UTF-8"))) {
// Iterate if the file has another line...
String line;
while ((line = reader.readLine()) != null) {
// If the line is blank then just print it and continue to next line
if (line.trim().isEmpty()) {
writer.println();
continue; // read next line....
}
StringBuilder sb = new StringBuilder("");
if (reverseEntireLine) {
// Reverse the entire line
sb.append(line).reverse();
}
else {
/* Reverse each word within the currently read line:
Split the line into individual words based on whitespace but,
keep any spacing in case there is indentation etc. We use a
special Regular Expression for this because spacing needs to
be in thier own elements within the created String[] Array
even though we're using it as a split() delimiter. */
String splitExpression = "((?<= )|(?= ))";
String[] lineParts = line.split(splitExpression);
for (String word : lineParts) {
if (word.matches("\s+")) {
sb.append(word);
}
else {
word = new StringBuilder(word).reverse().toString();
sb.append(word);
}
}
}
writer.println(sb.toString()); // Write to file.
writer.flush(); // Write immediately.
}
}
}
if (overwriteFile) {
new File(fullPath).delete();
new File(tempFile).renameTo(new File(fullPath));
}
}
以下是您可以如何使用它:
/* The Line Spearator used for the system the application
is running on. Not all Consoles or Terminals just use "
". */
String ls = System.lineSeparator();
// Provide a distinguishable and meaningful variable name!
Scanner userInput = new Scanner(System.in);
// File name to read prompt...
String fileName = "";
while (fileName.isEmpty()) {
System.out.print("Please enter the file path and name of the file" + ls
+ "you want to reverse (q to quit): -> ");
fileName = userInput.nextLine().trim();
// If 'q' for quit was entered.
if (fileName.equalsIgnoreCase("q")) {
return;
}
/* Validate input!
Does the supplied path and fileName exist? */
if (!new File(fileName).exists()) {
// Nope! Inform User...
System.out.println("The file name (" + fileName + ") can not be found!" + ls
+ "Please, try again..." + ls);
fileName = ""; // Empty fileName so to re-loop and ask again!
}
}
// All is good, the path and or file name exists.
try {
reverseFile(fileName, true, true); // <----
}
catch (FileNotFoundException ex) {
System.err.println(ex);
}
catch (IOException ex) {
System.err.println(ex);
}