Java字符串打破文件操作 [英] Java Strings breaking file operations
问题描述
public static void testFileIO(String [] args)
{
System.out.println(TESTING FILE IO FUNCTIONS ...);
try
{
String filename =test.txt;
String testString =UB\\\䞁ERBLAH\\\Ϳ\\\蝆;
System.out.println(Output:+ testString);
FileWriter fw = new FileWriter(filename);
fw.write(testString);
fw.close();
FileReader fr = new FileReader(filename);
int length;
for(length = 0; fr.read()!= -1; length ++);
if(length!= testString.length())
System.out.println(文件长度测量失败);
fr.close();
fr = new FileReader(filename);
char [] buffer = new char [length];
fr.read(buffer);
String result = new String(buffer);
fr.close();
System.out.println(Input:+ result);
if(result.equals(testString))System.out.println(SUCCESS!);
else System.out.println(FAILURE。);
}
catch(Throwable e)
{
e.printStackTrace();
System.out.println(FAILURE。);
return;
}
}
作为附加说明,文件长度测量失败也被捕获。
这是我用来加密和解密字符串的Crypto类...
抽象公共类Crypto
{
/ **
*使用按位xor cipher加密明文
* @param plainText明文加密
* @param密码按位xor密码
* @return的密钥由给定的明文和密码
* /
生成的密文public static String encrypt(String plainText,String key)
{
char [] data = plainText.toCharArray();
随机rand = new Random();
rand.setSeed(key.hashCode());
char [] pass = new char [data.length]; (int i = 0; i< pass.length; i ++)
{
pass [i] =(char)rand.nextInt();
}
for(int i = 0; i< data.length; i ++)
{
data [i] ^ = pass [i%pass。长度];
}
return new String(data);
}
/ **
*使用与加密相同的密钥解密加密的邮件
* @param cipherText要解密的cipherText消息
* @param password随机生成器的种子获取右键
* @return对应于'cipherText'的明文消息
* /
public static String decrypt(String cipherText,String key )
{
char [] data = cipherText.toCharArray();
随机rand = new Random();
rand.setSeed(key.hashCode());
char [] pass = new char [data.length]; // = key.getBytes(ASCII); (int i = 0; i< pass.length; i ++)
{
pass [i] =(char)rand.nextInt();
}
for(int i = 0; i< data.length; i ++)
{
data [i] ^ = pass [i%pass。长度];
}
return new String(data);
}
}
代码是正确的,但几乎从来没有工作 - 根据经验,避免 FileReader
和 FileWriter
并构建您自己的读者/作者使用 InputStreamReader
和 OutputStreamWriter
,它们允许您指定要使用的编码(因此如何保护16位Unicode字符你写8位数据)。
我使用一个帮助类,因为我需要它所有的时间:
private static final String FILE =file;
private static final String CHARSET =charset;
public static BufferedReader createReader(File file,Encoding charset)throws IOException {
JavaUtils.notNull(FILE,file);
JavaUtils.notNull(CHARSET,charset);
FileInputStream stream = null;
try {
stream = new FileInputStream(file);
return createReader(stream,charset);
} catch(IOException e){
IOUtils.closeQuietly(stream);
throw e;
} catch(RuntimeException e){
IOUtils.closeQuietly(stream);
throw e;
}
}
public static BufferedReader createReader(InputStream stream,Encoding charset)throws IOException {
JavaUtils.notNull(stream,stream);
JavaUtils.notNull(charset,charset);
try {
return new BufferedReader(new InputStreamReader(stream,charset.encoding()));
} catch(UnsupportedEncodingException e){
IOUtils.closeQuietly(stream);
throw new UnknownEncodingException(charset,e);
} catch(RuntimeException e){
IOUtils.closeQuietly(stream);
throw e;
}
}
public static BufferedWriter createWriter(文件文件,Encoding charset)throws IOException {
JavaUtils.notNull(FILE,file);
JavaUtils.notNull(CHARSET,charset);
FileOutputStream stream = null;
try {
stream = new FileOutputStream(file);
return new BufferedWriter(new OutputStreamWriter(stream,charset.encoding()));
} catch(UnsupportedEncodingException e){
IOUtils.closeQuietly(stream);
throw new UnknownEncodingException(charset,e);
} catch(IOException e){
IOUtils.closeQuietly(stream);
throw e;
} catch(RuntimeException e){
IOUtils.closeQuietly(stream);
throw e;
}
}
类型 Encoding
是使用一个或多个
枚举实现的界面
s:
code> public interface Encoding {
String encoding();
Charset charset();
}
I have a glitch in my program that causes a question mark (\u003f) to appear in the sixth (index = 5) slot in strings when I encrypt them. Normally, this is reversed upon decryption. However, it is not reversed if I save the string to a file first. I have determined that when I save a string containing Unicode characters to a file, I will not be able to determine the correct length for the file. I have managed to reproduce the glitch in the following function...
public static void testFileIO(String[] args)
{
System.out.println("TESTING FILE IO FUNCTIONS...");
try
{
String filename = "test.txt";
String testString = "UB\u4781ERBLAH\u037f\u8746";
System.out.println("Output: " + testString);
FileWriter fw = new FileWriter(filename);
fw.write(testString);
fw.close();
FileReader fr = new FileReader(filename);
int length;
for(length = 0; fr.read() != -1; length++);
if(length != testString.length())
System.out.println("Failure on file length measurement.");
fr.close();
fr = new FileReader(filename);
char[] buffer = new char[length];
fr.read(buffer);
String result = new String(buffer);
fr.close();
System.out.println("Input: " + result);
if(result.equals(testString)) System.out.println("SUCCESS!");
else System.out.println("FAILURE.");
}
catch (Throwable e)
{
e.printStackTrace();
System.out.println("FAILURE.");
return;
}
}
As an additional note, a failure in file length measurement is also caught.
Here is the Crypto class that I use to encrypt and decrypt Strings...
abstract public class Crypto
{
/**
* Encrypt the plaintext with a bitwise xor cipher
* @param plainText The plaintext to encrypt
* @param password The key for the bitwise xor cipher
* @return Ciphertext yielded by given plaintext and password
*/
public static String encrypt(String plainText, String key)
{
char[] data = plainText.toCharArray();
Random rand = new Random();
rand.setSeed(key.hashCode());
char[] pass = new char[data.length];
for(int i = 0; i < pass.length; i++)
{
pass[i] = (char)rand.nextInt();
}
for(int i = 0; i < data.length; i++)
{
data[i] ^= pass[i % pass.length];
}
return new String(data);
}
/**
* Decrypt an encrypted message using the same key as for encryption
* @param cipherText The cipherText message to be deciphered
* @param password The seed for the random generator to get the right keys
* @return The plaintext message corresponding to 'cipherText'
*/
public static String decrypt(String cipherText, String key)
{
char[] data = cipherText.toCharArray();
Random rand = new Random();
rand.setSeed(key.hashCode());
char[] pass = new char[data.length];// = key.getBytes("ASCII");
for(int i = 0; i < pass.length; i++)
{
pass[i] = (char)rand.nextInt();
}
for(int i = 0; i < data.length; i++)
{
data[i] ^= pass[i % pass.length];
}
return new String(data);
}
}
The code is correct but almost never works - As a rule of thumb, avoid FileReader
and FileWriter
and build your own readers/writers using InputStreamReader
and OutputStreamWriter
which allow you to specify the encoding to use (and hence how to protect 16bit Unicode characters when you write 8bit data).
I use a helper class for this because I need it all the time:
private static final String FILE = "file";
private static final String CHARSET = "charset";
public static BufferedReader createReader( File file, Encoding charset ) throws IOException {
JavaUtils.notNull( FILE, file );
JavaUtils.notNull( CHARSET, charset );
FileInputStream stream = null;
try {
stream = new FileInputStream( file );
return createReader( stream, charset );
} catch( IOException e ) {
IOUtils.closeQuietly( stream );
throw e;
} catch( RuntimeException e ) {
IOUtils.closeQuietly( stream );
throw e;
}
}
public static BufferedReader createReader( InputStream stream, Encoding charset ) throws IOException {
JavaUtils.notNull( "stream", stream );
JavaUtils.notNull( "charset", charset );
try {
return new BufferedReader( new InputStreamReader( stream, charset.encoding() ) );
} catch( UnsupportedEncodingException e ) {
IOUtils.closeQuietly( stream );
throw new UnknownEncodingException( charset, e );
} catch( RuntimeException e ) {
IOUtils.closeQuietly( stream );
throw e;
}
}
public static BufferedWriter createWriter( File file, Encoding charset ) throws IOException {
JavaUtils.notNull( FILE, file );
JavaUtils.notNull( CHARSET, charset );
FileOutputStream stream = null;
try {
stream = new FileOutputStream( file );
return new BufferedWriter( new OutputStreamWriter( stream, charset.encoding() ) );
} catch( UnsupportedEncodingException e ) {
IOUtils.closeQuietly( stream );
throw new UnknownEncodingException( charset, e );
} catch( IOException e ) {
IOUtils.closeQuietly( stream );
throw e;
} catch( RuntimeException e ) {
IOUtils.closeQuietly( stream );
throw e;
}
}
The type Encoding
is an interface which I implement using one or more enum
s:
public interface Encoding {
String encoding();
Charset charset();
}
这篇关于Java字符串打破文件操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!