简体   繁体   English

在java中输出文本文件的CaesarCipher程序

[英]CaesarCipher program that output a text file in java

I am trying to build a program that takes a text file, apply CaesarCipher method and returns and output file. 我正在尝试构建一个程序,它接受一个文本文件,应用CaesarCipher方法并返回和输出文件。

import java.util.*;
import java.io.*;

class CaesarCipher
{
    public static void main (String [] args) throws FileNotFoundException {
        System.out.print("What is the input file name? ");
        Scanner keyboard = new Scanner(System.in);
        String fileName = keyboard.nextLine();
        Scanner inputFile = new Scanner (new File (fileName));
        String inputFileString = inputFile.toString();
        System.out.print("What is the input file name? ");
        int s = 4;
        System.out.println("Text  : " + inputFileString);
        System.out.println("Shift : " + s);
        System.out.println("Cipher: " + encrypt(inputFileString, s));
    }

    public static String encrypt(String inputFileString, int s) {
        StringBuilder result = new StringBuilder();

        for (int i=0; i< inputFileString.length(); i++) {
            if (Character.isUpperCase(inputFileString.charAt(i))) {
                char ch = (char)(((int)inputFileString.charAt(i) + s - 65) % 26 + 65);
                result.append(ch);
            }
            else {
                char ch = (char)(((int)inputFileString.charAt(i) + s - 97) % 26 + 97);
                result.append(ch);
            }
        }

        return result.toString();
    }
}

I have two questions: 1- The program is compiling but when I run it and enter the text file name I get this error: 我有两个问题:1-程序正在编译,但是当我运行它并输入文本文件名时,我收到此错误:

What is the input file name? 什么是输入文件名? Text : java.util.Scanner[delimiters=\\p{javaWhitespace}+][position=0][match valid=false][need input=false][source closed=false][skipped=false][group separator=\\,][decimal separator=.][positive prefix=][negative prefix=\\Q-\\E][positive suffix=][negative suffix=][NaN string=\\Q \\E][infinity string=\\Q∞\\E] 文本:java.util.Scanner [delimiters = \\ p {javaWhitespace} +] [position = 0] [match valid = false] [need input = false] [source closed = false] [skipped = false] [group separator = \\ ,] [decimal separator =。] [positive prefix =] [negative prefix = \\ Q- \\ E] [positive suffix =] [negative suffix =] [NaN string = \\Q \\ E] [infinity string = \\Q∞ \\ E]

2- How can I construct a new outPut file that contains the coded text? 2-如何构造包含编码文本的新outPut文件?

Your existing code doesn't actually read the input file into a String . 您现有的代码实际上并未将输入文件读入String You can do so with a number of methods, one such is Files.readAllLines(Path) , which returns a List<String> of the file lines. 您可以使用多种方法执行此操作,例如Files.readAllLines(Path) ,它返回文件行的List<String> Stream that, and collect it with line separators. 流式传输,并使用行分隔符收集它。 Like, 喜欢,

String inputFileString = Files.readAllLines(new File(fileName).toPath()).stream()
            .collect(Collectors.joining(System.lineSeparator()));

As for writing to a file, take a look at the PrintStream(File) constructor. 至于写入文件,请查看PrintStream(File)构造函数。

It worked with StringBuilder 它适用于StringBuilder

StringBuilder inputFileString = new StringBuilder();
        while (inputFile.hasNext()) {
            String x = inputFile.nextLine();
            inputFileString.append(x);
        }

To fully answer your question: 完全回答你的问题:

  1. You are not really using the Scanner in a correct way. 您并没有以正确的方式使用扫描仪。 Here is a very good answer which shows several ways of how to convert an InputStream to a String . 这是一个非常好的答案,它显示了如何将InputStream转换为String的几种方法。 The only thing you need to know is how you would get an InputStream for a file (check code below). 您唯一需要知道的是如何为文件获取InputStream(请参阅下面的代码)。 As a side note, you should always remember to close your resources. 作为旁注,您应该始终记得关闭资源。 So close your FileInputStream if not used anymore ( more details here ). 如果不再使用,请关闭FileInputStream( 此处有更多详细信息 )。
    File file = new File("your/file/path/file.ending");
    try (FileInputStream fis = new FileInputStream(file)) {
        // your code here
    } catch (FileNotFoundException e){
        e.printStackTrace();
    }

  1. There are also multiple possibilities to create and write content to a file. 创建文件和向文件写入内容也有多种可能性。 Have a look at: How do I save a String to a text file using Java? 看看: 如何使用Java将String保存到文本文件?

And to sum it all up I created a working example using a slighty different way for the implementation of the caesar encryption and using Files.lines(...) to read the files content and Files.write(...) to write the encrypted content to a new file: 总而言之,我创建了一个工作示例,使用一种略微不同的方式来实现caesar加密,并使用Files.lines(...)来读取文件内容和Files.write(...)来编写加密内容到新文件:

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Scanner;
import java.util.stream.Stream;

public class CaesarCipher {

    public static void main(String[] args) throws IOException {
        Scanner scanner = new Scanner(System.in);

        System.out.print("What is the input file name? ");
        Path filePath = Paths.get(scanner.nextLine());

        System.out.print("What is the output file name? ");
        Path encodedFilePath = Paths.get(scanner.nextLine());

        System.out.print("Caesar cipher offset? ");
        final int offset = Integer.parseInt(scanner.nextLine());

        // Retrieve a a stream of the input file, where each line is mapped using the encrypt function
        Stream<String> mappedFileStream = Files.lines(filePath).map(msg -> CaesarCipher.encrypt(msg, offset));

        // Write encrypted content to a new file using our mapped stream as an iterable
        Files.write(
                encodedFilePath,
                (Iterable<String>) mappedFileStream::iterator,
                StandardCharsets.UTF_8,
                StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);

        // Decrypt the encoded file content and print it
        Files.lines(encodedFilePath)
                .map((fileLine) -> CaesarCipher.decrypt(fileLine, offset))
                .forEach(System.out::println);
    }

    public static String encrypt(String msg, int offset) {
        offset = offset % 26 + 26;
        StringBuilder encoded = new StringBuilder(msg.length());
        for (char i : msg.toCharArray()) {
            if (Character.isLetter(i)) {
                char base = Character.isUpperCase(i) ? 'A' : 'a';
                encoded.append((char) (base + (i - base + offset) % 26));
            } else {
                encoded.append(i);
            }
        }
        return encoded.toString();
    }

    public static String decrypt(String enc, int offset) {
        return encrypt(enc, 26 - offset);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM